Compare commits
1051 Commits
temp_motio
...
temp-ui-wi
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8d09ca96a7 | ||
![]() |
d693aa3590 | ||
![]() |
119cda0a0d | ||
![]() |
9b729adb6e | ||
![]() |
d9a720a709 | ||
fa86efdc97 | |||
18648bef7b | |||
![]() |
5fafd493c2 | ||
a662980f31 | |||
d94137ee7d | |||
8b286bf35a | |||
fdfd87f2f4 | |||
3fa0a1a5bc | |||
d2383ec6c0 | |||
828710d2ac | |||
c62eb919ec | |||
487d2cb4f3 | |||
883b420a51 | |||
39ce0a9916 | |||
4eefba091d | |||
8a2371e408 | |||
253ee0b490 | |||
b36c6b9c47 | |||
d22153425a | |||
a790e172d0 | |||
10dbe966e1 | |||
bccc6c393c | |||
c1506454ec | |||
8d37aaeca1 | |||
8f837e0ac5 | |||
7b467a6fea | |||
3c77822f96 | |||
0c82ba4213 | |||
d70ffd375f | |||
c6d13716c1 | |||
65c3207517 | |||
49f3998a0f | |||
64dc38f089 | |||
ded665a2c9 | |||
![]() |
63265fd0c3 | ||
d9fc9882dc | |||
cc0bbc28e2 | |||
f4ba4c6826 | |||
115c867190 | |||
281f4eb964 | |||
![]() |
e1cea53066 | ||
a9f6b27281 | |||
e229d66e99 | |||
dbdc55ab6a | |||
![]() |
fef31aadc4 | ||
8af8bab0c5 | |||
![]() |
e96e0ddbee | ||
![]() |
58133d4ab2 | ||
96f20c34a2 | |||
c677bd44ce | |||
930fc7d157 | |||
c30c3fde51 | |||
9becee445e | |||
![]() |
20bd253809 | ||
44384c698d | |||
f5a333fe65 | |||
599d8291ad | |||
579329388a | |||
0e80e3d20c | |||
b9ce21fd0f | |||
376e729de0 | |||
e660079e47 | |||
c587302ea1 | |||
03b2bccca8 | |||
8f45e1156f | |||
2c5efd5b3f | |||
be1a684755 | |||
fa4172c28c | |||
ced9381e20 | |||
c2cfec64e3 | |||
43c756ac95 | |||
300f33a8ea | |||
fdc8b12726 | |||
5af7257309 | |||
89edddb26c | |||
868d3605ee | |||
4140312c36 | |||
02f553cc7a | |||
9a995c11d3 | |||
5fe5118845 | |||
5e050918d8 | |||
11bfeb45ce | |||
6146fdc7b0 | |||
0208c95986 | |||
6cba20a8e6 | |||
5b76f72904 | |||
8d179e3c1f | |||
0ea45676d0 | |||
a474409f0b | |||
c54df2ad47 | |||
cae25ff240 | |||
d4a9da28e8 | |||
7742926403 | |||
7853cb3c5a | |||
a7442bef59 | |||
25f381a9b2 | |||
80c50a1d49 | |||
b5c602c9c2 | |||
864c154a41 | |||
![]() |
d39e18853f | ||
c18e6fd87c | |||
8bd425188c | |||
687a321be3 | |||
ea40df582f | |||
16b619b77d | |||
dfc672f8bb | |||
1fc32249f5 | |||
![]() |
4041e654cd | ||
07b525ffe2 | |||
4b6fba355c | |||
ae9ccec7c4 | |||
f1a9a8cbfd | |||
c1938eb127 | |||
b50916d172 | |||
abb976ae88 | |||
cff288cf3a | |||
62c8f46ab6 | |||
![]() |
23f54076db | ||
![]() |
8dbe598192 | ||
73522e1157 | |||
0951ea2c6d | |||
c2dc6aa946 | |||
9b51a9e885 | |||
2411027a79 | |||
7667ad2d4e | |||
e90fea72c1 | |||
e5f7b0f330 | |||
![]() |
76a74e2c58 | ||
![]() |
ae50da6ea6 | ||
4a0f3bece3 | |||
7cfb05dcb0 | |||
b4e1b7b18c | |||
b26eb47961 | |||
9036fa6b2e | |||
1d549530d8 | |||
8d945bf3cb | |||
3a9897f8ce | |||
3aa2dd74b5 | |||
60c8cdf763 | |||
4bf26fda97 | |||
11ad18c82a | |||
dd1e7f16ca | |||
c2c4e02d41 | |||
1b8afac652 | |||
![]() |
230d93ad54 | ||
42d65ef5cc | |||
0f690e2186 | |||
1dd4e933d8 | |||
88d63905a8 | |||
![]() |
73310f25fe | ||
![]() |
4db51cf00e | ||
![]() |
e28f359007 | ||
![]() |
e022e44af0 | ||
00857bec52 | |||
![]() |
e896f4e77d | ||
93d1acfb5c | |||
4cf92c4831 | |||
559e1434d8 | |||
a4f55617d1 | |||
![]() |
3b4a8f1cfa | ||
![]() |
2ec0d53034 | ||
![]() |
a3c5de3e3c | ||
![]() |
6098e48d0c | ||
![]() |
47bc66fc8d | ||
![]() |
31bf82c17d | ||
![]() |
fa1945c9e5 | ||
2904007d31 | |||
e31f8e756f | |||
0e9051fbfe | |||
d894fcb799 | |||
c851d1d045 | |||
c4b2bef163 | |||
49f88326af | |||
1c626f823d | |||
![]() |
527ee3f1f1 | ||
03f00eb91d | |||
12b7850d4f | |||
![]() |
6cad17291c | ||
55fead4767 | |||
31fe49626f | |||
63215aea6f | |||
70f8b5b1ff | |||
7575dbaf2a | |||
c582e186d9 | |||
6b7313be94 | |||
4d4c3b36a7 | |||
2ec00ea0c1 | |||
9d335d29c7 | |||
2ae67de944 | |||
820d191626 | |||
5c7cdfcb42 | |||
7b8230898e | |||
5fabcd099b | |||
75e387d6c5 | |||
4737b12462 | |||
d49703b298 | |||
7380166db2 | |||
26c1ae81be | |||
48c2f7b288 | |||
51c1927ccb | |||
717a303a18 | |||
ce5e62b78a | |||
b8e2b8ae8a | |||
af6bbab5b4 | |||
becf20e29f | |||
30679179dd | |||
a3b86611a8 | |||
cbf936a332 | |||
ce1bc1838b | |||
18af73e461 | |||
ba32d9d4cd | |||
8e9534a850 | |||
8b84c5f9de | |||
18c0a15e1e | |||
90655d06d4 | |||
792d66527b | |||
d4b5dd31a3 | |||
32157d8d01 | |||
339915a962 | |||
96f08bf9a8 | |||
376e4c945e | |||
d226a4ba6d | |||
31cb14f5de | |||
cff71fee21 | |||
![]() |
c6688aeddd | ||
335c3013f4 | |||
79a51f0839 | |||
1e6e3dcbd7 | |||
20c5c5e14b | |||
a6b2650c7d | |||
971affb436 | |||
be047fe455 | |||
f29625922f | |||
4690281b17 | |||
3fba620858 | |||
29ebb56f4d | |||
a0cbebf404 | |||
58956f3b91 | |||
f700c1f3a8 | |||
009bb9e5c9 | |||
8528d76dad | |||
733073550f | |||
96dd213e7e | |||
d3acfa1d87 | |||
038d6ce2cc | |||
c6396d9204 | |||
cd324654b0 | |||
ad7e3c302e | |||
33bac1f401 | |||
6df3e3a959 | |||
2b632dd8c2 | |||
7973363e34 | |||
40a866dad4 | |||
168bb36bc9 | |||
61e4800b45 | |||
79ffa03620 | |||
c61e4f2683 | |||
67fe5726af | |||
15676bcc85 | |||
76beb7b7d4 | |||
ba146899c8 | |||
e355d557f8 | |||
ce092a58a2 | |||
e5d7cbd191 | |||
20ec508ca3 | |||
b74fa38581 | |||
e48c4d73d3 | |||
cdf2dbeb1f | |||
2fe7e60633 | |||
![]() |
27a20c2c60 | ||
fb7281fb6a | |||
c27a1cfd63 | |||
![]() |
88ebffec96 | ||
![]() |
1fab327fdf | ||
8fa1da9213 | |||
f1f4a16eab | |||
53f6a31c4d | |||
17e3f905e1 | |||
a6b1e281eb | |||
e2652bc5ad | |||
5878050a4b | |||
50a46a5973 | |||
38e19536bf | |||
04b3694d93 | |||
221aee7ecd | |||
9ff869e4fb | |||
9dc0fed877 | |||
8cd14d421e | |||
9939c18900 | |||
e301cf3ec2 | |||
2a286829f7 | |||
![]() |
b284667681 | ||
e4b716a03f | |||
5acce60d37 | |||
7c5c7b5ef6 | |||
75f8f1907a | |||
33bd2c1597 | |||
68a9d80739 | |||
d2fac7df32 | |||
dc80ff9b56 | |||
a028575c4a | |||
54e6413d67 | |||
6322867e54 | |||
eff1b54362 | |||
b55ed89b66 | |||
2dce6dccbb | |||
95f698f840 | |||
d6ebf72f9f | |||
dc6153453a | |||
7f32601159 | |||
07fa1b49d9 | |||
8d237503c5 | |||
20d516dc35 | |||
15cb94c65a | |||
ea3dae74d8 | |||
3b362950e9 | |||
b8481f4683 | |||
0c0db92d7a | |||
36630b7e85 | |||
d47e565598 | |||
b3ac7c07ff | |||
0e2bbd0904 | |||
6ee2f79f33 | |||
1788293a01 | |||
cc5d48e8dd | |||
253f416a36 | |||
08fbc303e1 | |||
4be7fb7651 | |||
b6cf4f777d | |||
5c98848895 | |||
6aabc1bde4 | |||
0a249f9853 | |||
abbd82a504 | |||
8155d25d39 | |||
60822ec183 | |||
717046ad2a | |||
748899a50a | |||
0bf2b207e2 | |||
368bd34573 | |||
0b7d0f913d | |||
0795f62ddf | |||
5983280b4f | |||
b604d5ade0 | |||
b305041ce6 | |||
a6f00bb75c | |||
df41f7bf4f | |||
f9a6780dc6 | |||
75d1723518 | |||
461340525e | |||
945f32e66d | |||
cf6002737d | |||
3dd8f287e1 | |||
ec8b7edf53 | |||
e3461a02ac | |||
f2c54df625 | |||
dc3563ff48 | |||
1df42798d4 | |||
89e5c75666 | |||
e7fc8d98f5 | |||
78041fa14a | |||
9ae39a1312 | |||
ff3d535bc2 | |||
b91d64a3d1 | |||
b0df19667f | |||
b23c6c430f | |||
7ae44e8a30 | |||
23831b2161 | |||
ae00011956 | |||
9eb6dcbb46 | |||
a48db0894a | |||
39cf1de33d | |||
9dc9f84740 | |||
5e1a8055f4 | |||
3c911ff8a5 | |||
1d9fbdc9a0 | |||
1d02d34de9 | |||
ef950d6937 | |||
2bfa950438 | |||
b5f282b211 | |||
30772b6f09 | |||
3d36489672 | |||
2466c4f8ce | |||
a040157e5d | |||
ccc3c2dbda | |||
6190d75b5a | |||
a4a3d5650d | |||
66dd9fbf22 | |||
9ee1f96a0f | |||
40d4da829c | |||
432d24f998 | |||
ed3b19f46d | |||
db38a65b02 | |||
2e2164d5d4 | |||
![]() |
f2c6b7cdda | ||
![]() |
d2fc12d73e | ||
87328bde47 | |||
bd28c25f9b | |||
5f25b91b65 | |||
![]() |
50bd598a17 | ||
cb6fc9d141 | |||
![]() |
bd46a92deb | ||
![]() |
b2e18d25b0 | ||
![]() |
08b3e9a49c | ||
422ffd252a | |||
05ee9d2dd0 | |||
bf6ac302cd | |||
e3f86c6580 | |||
e5e9fbfaf0 | |||
86e6d6695e | |||
b368724464 | |||
cd91fd655d | |||
98bf205c39 | |||
b3e7a51ebd | |||
ee263c2566 | |||
1f748d2324 | |||
160c65845d | |||
86572dd7c9 | |||
b9895df36f | |||
6705786540 | |||
431cee2ba0 | |||
66423364ca | |||
be980c4ee4 | |||
e58d788340 | |||
23a4f547e7 | |||
a597a380bb | |||
8f1c1ef3a9 | |||
d712dc5a1d | |||
![]() |
74eb56fe7e | ||
23c76039d9 | |||
1e10e4e2e3 | |||
4bca8a6bc5 | |||
faeac63f68 | |||
003b56801c | |||
9b40616249 | |||
7d10798af2 | |||
2f15a1f66e | |||
92a37993a5 | |||
![]() |
2b73dff7cf | ||
2ccfbf2f81 | |||
cf14437ac9 | |||
45b5bf034b | |||
36a952e3e4 | |||
5e4a8c6a87 | |||
025eda57da | |||
2ad3a1d41e | |||
f5629b7265 | |||
cdd1be44c5 | |||
df4d25991e | |||
bbed6af857 | |||
ecb3e0fe73 | |||
2199a3e38b | |||
086ae3ea04 | |||
752eb64d60 | |||
![]() |
eba5bd3340 | ||
![]() |
b22061e989 | ||
![]() |
5d021e3331 | ||
7c5dd14689 | |||
3e83a0d92d | |||
7b30e2386b | |||
b45749727c | |||
32f7b4a358 | |||
e6711119f2 | |||
712098b1c8 | |||
c1290e441e | |||
20de6f01ed | |||
3a15ec337e | |||
85809e836e | |||
d4c0617496 | |||
955c13d614 | |||
7c06167982 | |||
5f09348fe8 | |||
82e27f5093 | |||
416d164fec | |||
e1606e8c87 | |||
19614f4395 | |||
c23d29c58e | |||
1b8e0d03d4 | |||
0b121d6a5d | |||
1255ac12a6 | |||
37017d149e | |||
9bcf1bb266 | |||
4052384be3 | |||
![]() |
b947998a51 | ||
![]() |
2a325a0eb9 | ||
![]() |
94adf2cc5f | ||
![]() |
80af1f10fc | ||
![]() |
56c6bd646a | ||
40936307dd | |||
67acde92bb | |||
9d090c4717 | |||
595a491e63 | |||
![]() |
85eb2ea3bb | ||
![]() |
f45c2a9cb5 | ||
![]() |
c8f6313487 | ||
2fe9224375 | |||
f2087b4830 | |||
4feef7d4f8 | |||
247d922ce5 | |||
3e3e7ee41c | |||
6568b6d1cd | |||
01a8216a4b | |||
![]() |
51385f6fe8 | ||
b00c49838a | |||
![]() |
a3a56d9aaf | ||
![]() |
03bfc42f74 | ||
e6364c64f2 | |||
13c39e90b3 | |||
2daa4db8a0 | |||
548e650252 | |||
2b97ad348c | |||
32c6d92cb0 | |||
56bf25d219 | |||
4143b8a6c7 | |||
72c7e12a5d | |||
7407ed7637 | |||
52fa5b12e1 | |||
![]() |
f2620c9df1 | ||
dfd383ca00 | |||
9cc1953210 | |||
![]() |
e50904f9c9 | ||
![]() |
0e06f4c491 | ||
8a17918555 | |||
d7b9202567 | |||
d0c5eac4b7 | |||
38940662e5 | |||
107e34407d | |||
1b8b9063f8 | |||
0918461d61 | |||
2cffd6649b | |||
655f498ca7 | |||
cba0858ccd | |||
82740cd282 | |||
9c80e52a89 | |||
6ba4a917a3 | |||
85004461ea | |||
a79d47b14e | |||
![]() |
52ce543f4d | ||
![]() |
0a202fdfce | ||
![]() |
d032de3bae | ||
7ad9ca72dd | |||
b7c42ef93e | |||
2de497eee0 | |||
![]() |
29166b3ae3 | ||
8c0b5c02de | |||
![]() |
d6c93298b5 | ||
9f78aa4c36 | |||
55374426c6 | |||
eee2d8e45c | |||
240646f506 | |||
6a982a080c | |||
![]() |
4050b49f97 | ||
![]() |
34a7156705 | ||
406b9aa7b1 | |||
6f7926c61c | |||
dd44754c5f | |||
e93b969ac9 | |||
0e9842dd04 | |||
582e7a6347 | |||
0119539e4b | |||
e7b3803317 | |||
b16bf6da80 | |||
9f63cbf4a7 | |||
a2f7997e05 | |||
686e8e452c | |||
2d32b92d77 | |||
e142ae77ca | |||
107bbee4c7 | |||
5201748f5f | |||
1dd92f352b | |||
f4f7348c41 | |||
c1a5e6b2fd | |||
c2bcf2dc05 | |||
36c15f4194 | |||
1b297567c0 | |||
feffbe974b | |||
1893e5e4c2 | |||
7e9c347c8c | |||
d54e77b66d | |||
6ffc988ae3 | |||
5b0f674e09 | |||
8d48f8e0b0 | |||
2fd3b9ad84 | |||
532b735ee8 | |||
5c8fc8e505 | |||
![]() |
8c67b8ffe9 | ||
7b1489b93b | |||
968351d916 | |||
17ebbc06e2 | |||
5a19d9d8f3 | |||
3a810bfed6 | |||
eed7efa151 | |||
b610ec50de | |||
a6259d4290 | |||
e42e01875e | |||
2410797ab1 | |||
03d8907ca7 | |||
114e7eaa09 | |||
![]() |
02b3618873 | ||
909fa34c5f | |||
![]() |
bf3fe67862 | ||
f3d5af4172 | |||
0875cb07cc | |||
78cae5bad9 | |||
3443686399 | |||
![]() |
9a3dfa1f21 | ||
e7a48113a9 | |||
25638a9656 | |||
![]() |
eeeb845d33 | ||
7837f0e833 | |||
bbcbd2eed9 | |||
a8b8d60c50 | |||
a7ed374459 | |||
66f1c3b882 | |||
![]() |
9ebe875dcc | ||
![]() |
58c50e786a | ||
![]() |
5513fdc629 | ||
![]() |
f766a61626 | ||
![]() |
aeeb23efa2 | ||
26bd1a766a | |||
a837797740 | |||
980ea4e54f | |||
cdbb60b0a3 | |||
ee1b1b9e59 | |||
bbc4a92318 | |||
![]() |
0d3a3347f0 | ||
![]() |
db5e89ad5c | ||
ec64bf17e3 | |||
161bbfcd19 | |||
4a328a7689 | |||
de6b4dc7f7 | |||
30b7aafe33 | |||
3dc86f586c | |||
37539962fe | |||
0c14a897dd | |||
1d021956f5 | |||
86f09e58d4 | |||
5af1daa2dc | |||
23aa425cd9 | |||
afa25b1136 | |||
![]() |
6ed1a1abe2 | ||
791b5fe9d0 | |||
![]() |
93608e4f3b | ||
![]() |
6a132aa65d | ||
12583287e7 | |||
266459c7da | |||
be07ab58c6 | |||
28d712b238 | |||
72565fbf30 | |||
499308d079 | |||
15c301f533 | |||
12aff8d783 | |||
51e9a814c9 | |||
6022bfbc05 | |||
2b63ec2894 | |||
6de7f3c747 | |||
68d72e2164 | |||
8d15cad449 | |||
631b53bad4 | |||
b997bda9f9 | |||
749f346ce0 | |||
c503d17353 | |||
e42609db49 | |||
97b431e42d | |||
1ace3272aa | |||
9133f5a357 | |||
947cdb3acd | |||
36426c3ee2 | |||
3129685f38 | |||
c864f5d140 | |||
145ab8c49e | |||
659e5234af | |||
b9f89b1647 | |||
![]() |
80f344fd95 | ||
c702dabc3d | |||
2b5e150db0 | |||
626a287c89 | |||
00808eb39a | |||
![]() |
a5b2841aa0 | ||
![]() |
fdb474fc8a | ||
145d3540b3 | |||
2723d10704 | |||
84b8ce32a4 | |||
d96842bf19 | |||
fabc4fc720 | |||
e61ead7d4c | |||
db8ccc18f7 | |||
e80e4c937b | |||
1393695145 | |||
1844160a22 | |||
10c1f208b7 | |||
![]() |
b05cf040cb | ||
5edff01920 | |||
19da2d4124 | |||
12a8d7e6c4 | |||
6781cf0049 | |||
607dca0705 | |||
d3709f4e79 | |||
1a44237d82 | |||
f525483d83 | |||
0e084f93d9 | |||
d3109a1937 | |||
53d12bbe04 | |||
174d5cf627 | |||
78de47ca24 | |||
9b64ebc605 | |||
95a1e99909 | |||
a77edab320 | |||
58d65dd976 | |||
d9046ccbd4 | |||
1779452eb4 | |||
45b2218341 | |||
b71c27a446 | |||
cf1bac3f69 | |||
![]() |
5e9b43cc61 | ||
6510e40500 | |||
21db9fff12 | |||
00bfca2178 | |||
c1d6a26842 | |||
7039808899 | |||
72d21fbd34 | |||
6de17c60bf | |||
df19da3a8b | |||
3bb698646a | |||
c07bba1b05 | |||
5d3ba4fb80 | |||
cec0138bcc | |||
cfd36476a1 | |||
d59721e47a | |||
d17cb3f75f | |||
8bef305b6d | |||
![]() |
56ca7f34dd | ||
![]() |
40d19b519d | ||
079b41dd37 | |||
117bcfe039 | |||
a8bc5f0cdb | |||
![]() |
f12b1790a0 | ||
![]() |
3d12d4b94f | ||
295d0c52a2 | |||
e35a26fbef | |||
6654ec7de7 | |||
827ccc343f | |||
e6f7f36e40 | |||
e245a57640 | |||
68478aea01 | |||
b506f3d328 | |||
d9ef528d05 | |||
9f48aa45ad | |||
c5c2883ce0 | |||
32319dd106 | |||
2ef3c43c5d | |||
3d616ccba8 | |||
aac5485fca | |||
008da0ff5e | |||
3d7329950e | |||
4d74180b9f | |||
09dc470982 | |||
17f12fc71a | |||
9260c0c2ba | |||
48ef0501b7 | |||
e2d3e36ca7 | |||
c68322c7e5 | |||
e170d6be7f | |||
ecb6a6df52 | |||
ff7a46cfad | |||
4d043c99dc | |||
e78b03f9e9 | |||
ab85c5f980 | |||
851d7535d9 | |||
ddeb8c595f | |||
c58b5acefd | |||
79c106705a | |||
8690ea611e | |||
09e89f01a6 | |||
c74255181e | |||
2cdcb1c171 | |||
0e83b0854f | |||
284d294f2c | |||
c0ea3099c5 | |||
ef57051e9c | |||
8e95303414 | |||
c40205738b | |||
ba98e6148b | |||
42314b32f2 | |||
![]() |
6f17fb8630 | ||
![]() |
fc668df245 | ||
![]() |
49aa7b1261 | ||
1676fcded0 | |||
c40759e678 | |||
a09af2dc7b | |||
9ce738e0f6 | |||
a33b1ce500 | |||
![]() |
227aefc18b | ||
0d4cca6593 | |||
f1bad1d16b | |||
40a345a9c7 | |||
04e9a707f4 | |||
b318795c3b | |||
90b4131d16 | |||
57065a6df5 | |||
1c251d7cb6 | |||
72e812de7c | |||
ec8e0336a9 | |||
7ecb199d86 | |||
cb5aecdae9 | |||
91fde2891c | |||
cd7853be22 | |||
4e8092e2e4 | |||
f1917a2188 | |||
d6e180e75a | |||
74f7ef1240 | |||
e2fa6663d3 | |||
80192b5391 | |||
![]() |
f0c5ed39ee | ||
211a95b538 | |||
a1609791ca | |||
4faccf0a78 | |||
d979ac4cc9 | |||
5e241e3028 | |||
7119a0f67d | |||
3044e9fd31 | |||
b5b8599342 | |||
63c9f51133 | |||
c119187be0 | |||
63f62cd757 | |||
857c9e14f7 | |||
43f6ed908f | |||
6057548058 | |||
8be4d76204 | |||
9ddb624a88 | |||
8d752141ce | |||
e3d6269ec4 | |||
cdb0cf3ec7 | |||
aeda4dca77 | |||
a95b0e0e9d | |||
5e2835037a | |||
34d665a4a4 | |||
63dd554ff1 | |||
5a4b51992e | |||
845854959f | |||
2a305580b2 | |||
6b3a43ccb4 | |||
b6820c9522 | |||
e019d8fb8c | |||
e3fe56d9d1 | |||
72a2d22f03 | |||
5a69b93f57 | |||
973afa0172 | |||
f6c661a38f | |||
e807520a1e | |||
74b32a23f7 | |||
4addabaed8 | |||
2de34ba31d | |||
51188ecbf1 | |||
8e1ba0b805 | |||
1d6c025c42 | |||
037181cf1c | |||
27eb2b1017 | |||
e9406256d0 | |||
ae0ed5e9d5 | |||
![]() |
9affa8450a | ||
9d796df4f6 | |||
0d3555fe2e | |||
0f171d4a25 | |||
1cf1f48893 | |||
52e95ad3d3 | |||
d4aeec9204 | |||
9b3722b414 | |||
d8cef42a14 | |||
![]() |
a1e01fda24 | ||
e1fd7b9ca9 | |||
7e529c2a64 | |||
4ed6605d65 | |||
28c34d332f | |||
03efc37a6e | |||
7165d979ae | |||
3468038ed5 | |||
7fbf264c67 | |||
530034511c | |||
18f228d593 | |||
![]() |
a62392dea7 | ||
3ce4a58aa9 | |||
937ecaf77e | |||
da61c36f2a | |||
fc35b758ad | |||
e96d1c7965 | |||
0dcda51836 | |||
37fd262805 | |||
bd5ea70a75 | |||
01f21f8026 | |||
42d5df448c | |||
0119c63405 | |||
bcc4957877 | |||
0b79c5ed29 | |||
e1ce9220d6 | |||
3b57f075a8 | |||
e0ae59f5d8 | |||
aee4527101 | |||
ae3e37b899 | |||
364d934951 | |||
a1c6b73de7 | |||
5b833de521 | |||
c03dcc5421 | |||
810f8928d6 | |||
81b37f5e92 | |||
ecdbe3cc63 | |||
2689247f98 | |||
770dfead86 | |||
aab2da9e65 | |||
fbff0e68a4 | |||
5ca3f3d811 | |||
c55cf743cd | |||
94eb2647d5 | |||
b986f955e9 | |||
173c1133a8 | |||
fa823dc828 | |||
b1a92f2b3a | |||
532e29cd76 | |||
291152e127 | |||
6d63446710 | |||
53e3e46332 | |||
888ed6b7f1 | |||
099aaea447 | |||
6c23497185 | |||
1c707a2392 | |||
124b25cf9d | |||
a44a0cf443 | |||
b633c2857f | |||
3f7ea7489e | |||
bf57c91ead | |||
473d46263b | |||
05b2ab1109 | |||
9090d64544 | |||
d7cd8ff891 | |||
5b8af1d1f1 | |||
edfe2d6691 | |||
fd629d2fb8 | |||
644e2250ce | |||
d8e994b35f | |||
3efc0aca54 | |||
7f3dcbe17f | |||
e464cbae3b | |||
9cefd5612d | |||
eb0310950c | |||
1862991862 | |||
b9fe261255 | |||
91b23992ce | |||
208a917b73 | |||
52997272aa | |||
1e9348efdc | |||
424e5be046 | |||
a2d4c26aa2 | |||
b1ed12bfec | |||
1c81bcffde | |||
75a86d6a8e | |||
a1ac42f5eb | |||
4835fe06f1 | |||
![]() |
9326820a1b | ||
![]() |
e944af67f7 | ||
41d5ff6fe9 | |||
d3e16df4f1 | |||
1cbf748e0c | |||
0f42b8aee0 | |||
097aa852cf | |||
![]() |
54b824106b | ||
0bf0aa6625 | |||
0b51e7d991 | |||
38a60418f7 | |||
60ddaf045a | |||
02a496c61c | |||
7bac8348bf | |||
![]() |
7182677620 | ||
1b8a785d83 | |||
07562a4afb | |||
9e91313a97 | |||
6f36e1f872 | |||
efe4af8fcb | |||
a9d3f663d3 | |||
e2e414218b | |||
0d95b41f9e | |||
7823ca06da | |||
4fae3620d0 | |||
850bb80aef | |||
69e96509a6 | |||
f2bd6d73e6 | |||
6c44265bc9 | |||
34c3beb339 | |||
520fb5c8cd | |||
4ab47a7670 | |||
5893a3445e | |||
37b8153afe | |||
![]() |
7ca40c1061 | ||
![]() |
2205950274 | ||
6a33d13ae7 | |||
596eadf0e1 | |||
b3cc602adc | |||
f6748183a2 | |||
7dae8e54cc | |||
774e034d40 | |||
9c5995c062 | |||
b496819fcc | |||
b666593775 | |||
96d9801423 | |||
b4446b505f | |||
5114637967 | |||
8c2619a11a | |||
![]() |
939948c233 | ||
356afe0085 | |||
6a0a205cb4 | |||
af4d10703b | |||
102e18d05c | |||
2bd6de5bbb | |||
3438130a94 | |||
abc9c26ec8 | |||
a6803bf564 | |||
bb5e46f105 | |||
41564a402e | |||
ee37de75e6 | |||
867cd2048e | |||
b8b57d2da9 | |||
958c20872a | |||
![]() |
087c82e392 | ||
f167f434d9 | |||
8e0ab3d42f | |||
825892ae7a | |||
3560e36ee9 | |||
ec3c2d3be9 | |||
91e767c99c | |||
ab417f31f4 | |||
73a104b8e8 | |||
9f911f62dc | |||
6e844da9da | |||
0446c73c4a | |||
bc69eafa98 | |||
08687ee380 | |||
45d4fadebd | |||
7b0c327b94 | |||
9a83e112be | |||
3092e1031d | |||
af980a20a4 | |||
6c8f2049f6 | |||
cb9bd23d0c | |||
![]() |
e1b8ed8dd4 | ||
962f764d58 | |||
f8385de5ed | |||
![]() |
ffdeba49e6 | ||
![]() |
4f94947157 |
196
CMakeLists.txt
196
CMakeLists.txt
@@ -53,7 +53,9 @@ if(NOT (${CMAKE_VERSION} VERSION_LESS 3.0))
|
||||
endif()
|
||||
|
||||
if(NOT EXECUTABLE_OUTPUT_PATH)
|
||||
set(FIRST_RUN "TRUE")
|
||||
set(FIRST_RUN TRUE)
|
||||
else()
|
||||
set(FIRST_RUN FALSE)
|
||||
endif()
|
||||
|
||||
# this starts out unset
|
||||
@@ -71,7 +73,6 @@ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE NDEBU
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL NDEBUG)
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO NDEBUG)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Set policy
|
||||
|
||||
@@ -129,7 +130,7 @@ macro(option_defaults_init)
|
||||
set(${_var} ON)
|
||||
list(APPEND _init_vars "${_var}")
|
||||
endforeach()
|
||||
unset(_INC)
|
||||
unset(_var)
|
||||
endmacro()
|
||||
|
||||
# remove from namespace
|
||||
@@ -157,25 +158,30 @@ option_defaults_init(
|
||||
_init_SDL
|
||||
_init_FFTW3
|
||||
_init_GAMEENGINE
|
||||
_init_OPENSUBDIV
|
||||
)
|
||||
|
||||
# customize...
|
||||
if(UNIX AND NOT APPLE)
|
||||
if (UNIX AND NOT APPLE)
|
||||
# some of these libraries are problematic on Linux
|
||||
# disable less important dependencies by default
|
||||
set(_init_BUILDINFO OFF)
|
||||
set(_init_CODEC_FFMPEG OFF)
|
||||
set(_init_CYCLES_OSL OFF)
|
||||
set(_init_IMAGE_OPENEXR OFF)
|
||||
set(_init_IMAGE_REDCODE OFF)
|
||||
set(_init_INPUT_NDOF OFF)
|
||||
set(_init_JACK OFF)
|
||||
set(_init_LIBMV_SCHUR_SPECIALIZATION OFF)
|
||||
set(_init_OPENCOLLADA OFF)
|
||||
set(_init_OPENCOLORIO OFF)
|
||||
set(_init_SDL OFF)
|
||||
set(_init_FFTW3 OFF)
|
||||
set(_init_GAMEENGINE OFF)
|
||||
set(_init_OPENSUBDIV OFF)
|
||||
elseif(WIN32)
|
||||
set(_init_JACK OFF)
|
||||
elseif(APPLE)
|
||||
set(_init_INPUT_NDOF OFF)
|
||||
set(_init_JACK OFF)
|
||||
set(_init_OPENSUBDIV OFF)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -220,7 +226,15 @@ mark_as_advanced(WITH_SYSTEM_BULLET)
|
||||
option(WITH_GAMEENGINE "Enable Game Engine" ${_init_GAMEENGINE})
|
||||
option(WITH_PLAYER "Build Player" OFF)
|
||||
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLORIO})
|
||||
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
|
||||
|
||||
# Compositor
|
||||
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
|
||||
option(WITH_COMPOSITOR_WERROR "Treat warnings as errors in compositor code" OFF)
|
||||
mark_as_advanced(WITH_COMPOSITOR_WERROR)
|
||||
|
||||
option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" _init_OPENSUBDIV)
|
||||
option(WITH_SUBSURF_WERROR "Treat warnings as errors in subsurf code" OFF)
|
||||
mark_as_advanced(WITH_COMPOSITOR_WERROR)
|
||||
|
||||
# GHOST Windowing Library Options
|
||||
option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF)
|
||||
@@ -238,7 +252,13 @@ option(WITH_HEADLESS "Build without graphical support (renderfarm, server m
|
||||
mark_as_advanced(WITH_HEADLESS)
|
||||
|
||||
option(WITH_AUDASPACE "Build with blenders audio library (only disable if you know what you're doing!)" ON)
|
||||
option(WITH_SYSTEM_AUDASPACE "Build with external audaspace library installed on the system (only enable if you know what you're doing!)" OFF)
|
||||
mark_as_advanced(WITH_AUDASPACE)
|
||||
mark_as_advanced(WITH_SYSTEM_AUDASPACE)
|
||||
|
||||
if(NOT WITH_AUDASPACE)
|
||||
set(WITH_SYSTEM_AUDASPACE OFF)
|
||||
endif()
|
||||
|
||||
option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ON)
|
||||
|
||||
@@ -317,9 +337,11 @@ if(UNIX AND NOT APPLE)
|
||||
endif()
|
||||
|
||||
# Camera/motion tracking
|
||||
option(WITH_LIBMV "Enable libmv structure from motion library" ON)
|
||||
option(WITH_LIBMV "Enable Libmv structure from motion library" ON)
|
||||
option(WITH_LIBMV_SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ${_init_LIBMV_SCHUR_SPECIALIZATION})
|
||||
option(WITH_LIBMV_WERROR "Treat warnings as errors in Libmv (and Blender's motion tracking) code")
|
||||
mark_as_advanced(WITH_LIBMV_SCHUR_SPECIALIZATIONS)
|
||||
mark_as_advanced(WITH_LIBMV_WERROR)
|
||||
|
||||
# Freestyle
|
||||
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
|
||||
@@ -353,18 +375,20 @@ if(UNIX AND NOT APPLE)
|
||||
endif()
|
||||
|
||||
# Cycles
|
||||
option(WITH_CYCLES "Enable cycles Render Engine" ON)
|
||||
option(WITH_CYCLES_STANDALONE "Build cycles standalone application" OFF)
|
||||
option(WITH_CYCLES_STANDALONE_GUI "Build cycles standalone with GUI" OFF)
|
||||
option(WITH_CYCLES "Enable Cycles Render Engine" ON)
|
||||
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
|
||||
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
|
||||
option(WITH_CYCLES_OSL "Build Cycles with OSL support" ${_init_CYCLES_OSL})
|
||||
option(WITH_CYCLES_CUDA_BINARIES "Build cycles CUDA binaries" OFF)
|
||||
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles CUDA binaries" OFF)
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_20 sm_21 sm_30 sm_35 sm_50 sm_52 CACHE STRING "CUDA architectures to build binaries for")
|
||||
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
|
||||
unset(PLATFORM_DEFAULT)
|
||||
option(WITH_CYCLES_LOGGING "Build cycles with logging support" ON)
|
||||
option(WITH_CYCLES_DEBUG "Build cycles with extra debug capabilities" OFF)
|
||||
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
|
||||
option(WITH_CYCLES_DEBUG "Build Cycles with extra debug capabilities" OFF)
|
||||
option(WITH_CYCLES_WERROR "Treat warnings as errors in Cycles code" OFF)
|
||||
mark_as_advanced(WITH_CYCLES_LOGGING)
|
||||
mark_as_advanced(WITH_CYCLES_DEBUG)
|
||||
mark_as_advanced(WITH_CYCLES_WERROR)
|
||||
|
||||
# LLVM
|
||||
option(WITH_LLVM "Use LLVM" OFF)
|
||||
@@ -394,7 +418,6 @@ option(WITH_BOOST "Enable features depending on boost" ON)
|
||||
|
||||
# Unit testsing
|
||||
option(WITH_GTESTS "Enable GTest unit testing" OFF)
|
||||
option(WITH_TESTS_PERFORMANCE "Enable performance tests" OFF)
|
||||
|
||||
|
||||
# Documentation
|
||||
@@ -411,7 +434,6 @@ option(WITH_GL_EGL "Use the EGL OpenGL system library instead of th
|
||||
option(WITH_GL_PROFILE_COMPAT "Support using the OpenGL 'compatibility' profile. (deprecated)" ON )
|
||||
option(WITH_GL_PROFILE_CORE "Support using the OpenGL 3.2+ 'core' profile." OFF)
|
||||
option(WITH_GL_PROFILE_ES20 "Support using OpenGL ES 2.0. (thru either EGL or the AGL/WGL/XGL 'es20' profile)" OFF)
|
||||
option(WITH_GPU_DEBUG "Create a debug OpenGL context (allows inserting custom messages and getting notifications for bad GL use)" OFF)
|
||||
|
||||
mark_as_advanced(
|
||||
WITH_GLEW_MX
|
||||
@@ -420,7 +442,6 @@ mark_as_advanced(
|
||||
WITH_GL_PROFILE_COMPAT
|
||||
WITH_GL_PROFILE_CORE
|
||||
WITH_GL_PROFILE_ES20
|
||||
WITH_GPU_DEBUG
|
||||
)
|
||||
|
||||
if(WITH_GL_PROFILE_COMPAT)
|
||||
@@ -450,6 +471,7 @@ mark_as_advanced(WITH_CPP11)
|
||||
|
||||
# Dependency graph
|
||||
option(WITH_LEGACY_DEPSGRAPH "Build Blender with legacy dependency graph" ON)
|
||||
mark_as_advanced(WITH_LEGACY_DEPSGRAPH)
|
||||
|
||||
# avoid using again
|
||||
option_defaults_clear()
|
||||
@@ -654,6 +676,13 @@ endif()
|
||||
# auto enable openimageio for cycles
|
||||
if(WITH_CYCLES)
|
||||
set(WITH_OPENIMAGEIO ON)
|
||||
|
||||
# auto enable llvm for cycles_osl
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(WITH_LLVM ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
else()
|
||||
set(WITH_CYCLES_OSL OFF)
|
||||
endif()
|
||||
|
||||
# auto enable openimageio linking dependencies
|
||||
@@ -662,11 +691,6 @@ if(WITH_OPENIMAGEIO)
|
||||
set(WITH_IMAGE_TIFF ON)
|
||||
endif()
|
||||
|
||||
# auto enable llvm for cycles_osl
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(WITH_LLVM ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
# don't store paths to libs for portable distribution
|
||||
if(WITH_INSTALL_PORTABLE)
|
||||
set(CMAKE_SKIP_BUILD_RPATH TRUE)
|
||||
@@ -693,6 +717,34 @@ if(HAVE_STDBOOL_H)
|
||||
add_definitions(-DHAVE_STDBOOL_H)
|
||||
endif()
|
||||
|
||||
if(WITH_AUDASPACE)
|
||||
if(WITH_SYSTEM_AUDASPACE)
|
||||
set(AUDASPACE_DEFINITIONS
|
||||
-DWITH_AUDASPACE
|
||||
-DWITH_SYSTEM_AUDASPACE
|
||||
"-DAUD_DEVICE_H=<AUD_Device.h>"
|
||||
"-DAUD_SPECIAL_H=<AUD_Special.h>"
|
||||
"-DAUD_SOUND_H=<AUD_Sound.h>"
|
||||
"-DAUD_HANDLE_H=<AUD_Handle.h>"
|
||||
"-DAUD_SEQUENCE_H=<AUD_Sequence.h>"
|
||||
"-DAUD_TYPES_H=<AUD_Types.h>"
|
||||
"-DAUD_PYTHON_H=<python/PyAPI.h>"
|
||||
)
|
||||
else()
|
||||
set(AUDASPACE_C_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/intern/audaspace/intern")
|
||||
set(AUDASPACE_PY_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/intern/audaspace/intern")
|
||||
set(AUDASPACE_DEFINITIONS
|
||||
-DWITH_AUDASPACE
|
||||
"-DAUD_DEVICE_H=<AUD_C-API.h>"
|
||||
"-DAUD_SPECIAL_H=<AUD_C-API.h>"
|
||||
"-DAUD_SOUND_H=<AUD_C-API.h>"
|
||||
"-DAUD_HANDLE_H=<AUD_C-API.h>"
|
||||
"-DAUD_SEQUENCE_H=<AUD_C-API.h>"
|
||||
"-DAUD_TYPES_H=<AUD_Space.h>"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Check for valid directories
|
||||
# ... a partial checkout may cause this.
|
||||
@@ -794,6 +846,14 @@ if(WITH_X11)
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Main Platform Checks
|
||||
#
|
||||
# - UNIX
|
||||
# - WIN32
|
||||
# - APPLE
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
macro(find_package_wrapper)
|
||||
if(WITH_STATIC_LIBS)
|
||||
@@ -862,6 +922,13 @@ if(UNIX AND NOT APPLE)
|
||||
endif()
|
||||
|
||||
# Audio IO
|
||||
if(WITH_SYSTEM_AUDASPACE)
|
||||
find_package_wrapper(Audaspace)
|
||||
if(NOT AUDASPACE_FOUND OR NOT AUDASPACE_C_FOUND)
|
||||
message(FATAL_ERROR "Audaspace external library not found!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_OPENAL)
|
||||
find_package_wrapper(OpenAL)
|
||||
if(NOT OPENAL_FOUND)
|
||||
@@ -1062,9 +1129,9 @@ if(UNIX AND NOT APPLE)
|
||||
endif()
|
||||
|
||||
if(WITH_LLVM)
|
||||
find_package_wrapper(LLVM)
|
||||
find_package_wrapper(LLVM)
|
||||
|
||||
if(NOT LLVM_FOUND)
|
||||
if(NOT LLVM_FOUND)
|
||||
set(WITH_LLVM OFF)
|
||||
message(STATUS "LLVM not found")
|
||||
endif()
|
||||
@@ -1075,6 +1142,18 @@ if(UNIX AND NOT APPLE)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,--version-script='${CMAKE_SOURCE_DIR}/source/creator/blender.map'")
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
find_package_wrapper(OpenSubdiv)
|
||||
|
||||
set(OPENSUBDIV_LIBRARIES ${OPENSUBDIV_LIBRARIES})
|
||||
set(OPENSUBDIV_LIBPATH) # TODO, remove and reference the absolute path everywhere
|
||||
|
||||
if(NOT OPENSUBDIV_FOUND)
|
||||
set(WITH_OPENSUBDIV OFF)
|
||||
message(STATUS "OpenSubdiv not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed
|
||||
list(APPEND PLATFORM_LINKLIBS -lutil -lc -lm)
|
||||
|
||||
@@ -1112,12 +1191,12 @@ if(UNIX AND NOT APPLE)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version
|
||||
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||
if ("${LD_VERSION}" MATCHES "GNU gold")
|
||||
if("${LD_VERSION}" MATCHES "GNU gold")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=gold")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold")
|
||||
else ()
|
||||
message(INFO "GNU gold linker isn't available, using the default system linker.")
|
||||
endif ()
|
||||
else()
|
||||
message(STATUS "GNU gold linker isn't available, using the default system linker.")
|
||||
endif()
|
||||
unset(LD_VERSION)
|
||||
|
||||
# CLang is the same as GCC for now.
|
||||
@@ -1495,6 +1574,13 @@ elseif(WIN32)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
set(OPENSUBDIV_INCLUDE_DIR ${LIBDIR}/opensubdiv/include)
|
||||
set(OPENSUBDIV_LIBPATH ${LIBDIR}/opensubdiv/lib)
|
||||
set(OPENSUBDIV_LIBRARIES ${OPENSUBDIV_LIBPATH}/osdCPU.lib ${OPENSUBDIV_LIBPATH}/osdGPU.lib)
|
||||
find_package(OpenSubdiv)
|
||||
endif()
|
||||
|
||||
if(WITH_SDL)
|
||||
set(SDL ${LIBDIR}/sdl)
|
||||
set(SDL_INCLUDE_DIR ${SDL}/include)
|
||||
@@ -1502,6 +1588,16 @@ elseif(WIN32)
|
||||
set(SDL_LIBPATH ${SDL}/lib)
|
||||
endif()
|
||||
|
||||
# Audio IO
|
||||
if(WITH_SYSTEM_AUDASPACE)
|
||||
set(AUDASPACE_INCLUDE_DIRS ${LIBDIR}/audaspace/include/audaspace)
|
||||
set(AUDASPACE_LIBRARIES ${LIBDIR}/audaspace/lib/audaspace.lib)
|
||||
set(AUDASPACE_C_INCLUDE_DIRS ${LIBDIR}/audaspace/include/audaspace)
|
||||
set(AUDASPACE_C_LIBRARIES ${LIBDIR}/audaspace/lib/audaspace-c.lib)
|
||||
set(AUDASPACE_PY_INCLUDE_DIRS ${LIBDIR}/audaspace/include/audaspace)
|
||||
set(AUDASPACE_PY_LIBRARIES ${LIBDIR}/audaspace/lib/audaspace-py.lib)
|
||||
endif()
|
||||
|
||||
# used in many places so include globally, like OpenGL
|
||||
blender_include_dirs_sys("${PTHREADS_INCLUDE_DIRS}")
|
||||
|
||||
@@ -1821,6 +1917,17 @@ elseif(APPLE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
set(OPENSUBDIV ${LIBDIR}/opensubdiv)
|
||||
set(OPENSUBDIV_LIBPATH ${OPENSUBDIV}/lib)
|
||||
find_library(OSL_LIB_UTIL NAMES osdutil PATHS ${OPENSUBDIV_LIBPATH})
|
||||
find_library(OSL_LIB_CPU NAMES osdCPU PATHS ${OPENSUBDIV_LIBPATH})
|
||||
find_library(OSL_LIB_GPU NAMES osdGPU PATHS ${OPENSUBDIV_LIBPATH})
|
||||
set(OPENSUBDIV_INCLUDE_DIR ${OPENSUBDIV}/include)
|
||||
set(OPENSUBDIV_INCLUDE_DIRS ${OPENSUBDIV_INCLUDE_DIR})
|
||||
list(APPEND OPENSUBDIV_LIBRARIES ${OSL_LIB_UTIL} ${OSL_LIB_CPU} ${OSL_LIB_GPU})
|
||||
endif()
|
||||
|
||||
if(WITH_JACK)
|
||||
find_library(JACK_FRAMEWORK
|
||||
NAMES jackmp
|
||||
@@ -2348,10 +2455,6 @@ if(WITH_GL_EGL)
|
||||
list(APPEND GL_DEFINITIONS -DWITH_EGL)
|
||||
endif()
|
||||
|
||||
if(WITH_GPU_DEBUG)
|
||||
list(APPEND GL_DEFINITIONS -DWITH_GPU_DEBUG)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure OpenMP.
|
||||
if(WITH_OPENMP)
|
||||
@@ -2758,25 +2861,29 @@ include(build_files/cmake/packaging.cmake)
|
||||
# Print Final Configuration
|
||||
|
||||
if(FIRST_RUN)
|
||||
set(_config_msg "\n* Blender Configuration *")
|
||||
macro(info_cfg_option
|
||||
_setting)
|
||||
set(_msg " * ${_setting}")
|
||||
|
||||
set(_config_msg "\nBlender Configuration\n=====================")
|
||||
|
||||
function(info_cfg_option
|
||||
_setting
|
||||
)
|
||||
|
||||
set(_msg " - ${_setting}")
|
||||
string(LENGTH "${_msg}" _len)
|
||||
while("32" GREATER "${_len}")
|
||||
set(_msg "${_msg} ")
|
||||
math(EXPR _len "${_len} + 1")
|
||||
endwhile()
|
||||
|
||||
set(_config_msg "${_config_msg}\n${_msg}${${_setting}}")
|
||||
endmacro()
|
||||
set(_config_msg "${_config_msg}\n${_msg}${${_setting}}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
macro(info_cfg_text
|
||||
_text)
|
||||
set(_config_msg "${_config_msg}\n\n ${_text}")
|
||||
function(info_cfg_text
|
||||
_text
|
||||
)
|
||||
|
||||
|
||||
endmacro()
|
||||
set(_config_msg "${_config_msg}\n\n ${_text}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
message(STATUS "C Compiler: \"${CMAKE_C_COMPILER_ID}\"")
|
||||
message(STATUS "C++ Compiler: \"${CMAKE_CXX_COMPILER_ID}\"")
|
||||
@@ -2855,7 +2962,6 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_GL_PROFILE_COMPAT)
|
||||
info_cfg_option(WITH_GL_PROFILE_CORE)
|
||||
info_cfg_option(WITH_GL_PROFILE_ES20)
|
||||
info_cfg_option(WITH_GPU_DEBUG)
|
||||
if(WIN32)
|
||||
info_cfg_option(WITH_GL_ANGLE)
|
||||
endif()
|
||||
|
88
GNUmakefile
88
GNUmakefile
@@ -43,6 +43,11 @@ ifndef BUILD_DIR
|
||||
BUILD_DIR:=$(shell dirname "$(BLENDER_DIR)")/build_$(OS_NCASE)
|
||||
endif
|
||||
|
||||
# Allow to use alternative binary (pypy3, etc)
|
||||
ifndef PYTHON
|
||||
PYTHON:=python3
|
||||
endif
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# additional targets for the build configuration
|
||||
@@ -76,18 +81,20 @@ endif
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Get the number of cores for threaded build
|
||||
NPROCS:=1
|
||||
ifeq ($(OS), Linux)
|
||||
NPROCS:=$(shell nproc)
|
||||
endif
|
||||
ifeq ($(OS), Darwin)
|
||||
NPROCS:=$(shell sysctl -a | grep "hw.ncpu" | cut -d" " -f3)
|
||||
endif
|
||||
ifeq ($(OS), FreeBSD)
|
||||
NPROCS:=$(shell sysctl -a | grep "hw.ncpu" | cut -d" " -f2 )
|
||||
endif
|
||||
ifeq ($(OS), NetBSD)
|
||||
NPROCS:=$(shell sysctl -a | grep "hw.ncpu" | cut -d" " -f2 )
|
||||
ifndef NPROCS
|
||||
NPROCS:=1
|
||||
ifeq ($(OS), Linux)
|
||||
NPROCS:=$(shell nproc)
|
||||
endif
|
||||
ifeq ($(OS), Darwin)
|
||||
NPROCS:=$(shell sysctl -a | grep "hw.ncpu" | cut -d" " -f3)
|
||||
endif
|
||||
ifeq ($(OS), FreeBSD)
|
||||
NPROCS:=$(shell sysctl -a | grep "hw.ncpu" | cut -d" " -f2 )
|
||||
endif
|
||||
ifeq ($(OS), NetBSD)
|
||||
NPROCS:=$(shell sysctl -a | grep "hw.ncpu" | cut -d" " -f2 )
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
@@ -117,12 +124,12 @@ all: FORCE
|
||||
@echo
|
||||
@echo Configuring Blender ...
|
||||
|
||||
# if test ! -f $(BUILD_DIR)/CMakeCache.txt ; then \
|
||||
# $(CMAKE_CONFIG); \
|
||||
# fi
|
||||
# # if test ! -f $(BUILD_DIR)/CMakeCache.txt ; then \
|
||||
# # $(CMAKE_CONFIG); \
|
||||
# # fi
|
||||
|
||||
# do this always incase of failed initial build, could be smarter here...
|
||||
$(CMAKE_CONFIG)
|
||||
# # do this always incase of failed initial build, could be smarter here...
|
||||
@$(CMAKE_CONFIG)
|
||||
|
||||
@echo
|
||||
@echo Building Blender ...
|
||||
@@ -201,6 +208,12 @@ help: FORCE
|
||||
@echo " * tgz - create a compressed archive of the source code."
|
||||
@echo " * update - updates git and all submodules"
|
||||
@echo ""
|
||||
@echo "Environment Variables"
|
||||
@echo " * BUILD_CMAKE_ARGS - arguments passed to CMake."
|
||||
@echo " * BUILD_DIR - override default build path."
|
||||
@echo " * PYTHON - use this for the Python command (used for checking tools)."
|
||||
@echo " * NPROCS - number of processes to use building (auto-detect when omitted)."
|
||||
@echo ""
|
||||
@echo "Documentation Targets (not associated with building blender)"
|
||||
@echo " * doc_py - generate sphinx python api docs"
|
||||
@echo " * doc_doxy - generate doxygen C/C++ docs"
|
||||
@@ -210,6 +223,7 @@ help: FORCE
|
||||
@echo "Information"
|
||||
@echo " * help - this help message"
|
||||
@echo " * help_features - show a list of optional features when building"
|
||||
@echo ""
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Packages
|
||||
@@ -233,21 +247,21 @@ test: FORCE
|
||||
|
||||
# run pep8 check check on scripts we distribute.
|
||||
test_pep8: FORCE
|
||||
python3 tests/python/pep8.py > test_pep8.log 2>&1
|
||||
$(PYTHON) tests/python/pep8.py > test_pep8.log 2>&1
|
||||
@echo "written: test_pep8.log"
|
||||
|
||||
# run some checks on our cmakefiles.
|
||||
test_cmake: FORCE
|
||||
python3 build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1
|
||||
$(PYTHON) build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1
|
||||
@echo "written: test_cmake_consistency.log"
|
||||
|
||||
# run deprecation tests, see if we have anything to remove.
|
||||
test_deprecated: FORCE
|
||||
python3 tests/check_deprecated.py
|
||||
$(PYTHON) tests/check_deprecated.py
|
||||
|
||||
test_style_c: FORCE
|
||||
# run our own checks on C/C++ style
|
||||
PYTHONIOENCODING=utf_8 python3 \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/source/tools/check_source/check_style_c.py" \
|
||||
"$(BLENDER_DIR)/source/blender" \
|
||||
"$(BLENDER_DIR)/source/creator" \
|
||||
@@ -256,7 +270,7 @@ test_style_c: FORCE
|
||||
test_style_c_qtc: FORCE
|
||||
# run our own checks on C/C++ style
|
||||
USE_QTC_TASK=1 \
|
||||
PYTHONIOENCODING=utf_8 python3 \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/source/tools/check_source/check_style_c.py" \
|
||||
"$(BLENDER_DIR)/source/blender" \
|
||||
"$(BLENDER_DIR)/source/creator" \
|
||||
@@ -268,7 +282,7 @@ test_style_c_qtc: FORCE
|
||||
|
||||
test_style_osl: FORCE
|
||||
# run our own checks on C/C++ style
|
||||
PYTHONIOENCODING=utf_8 python3 \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/source/tools/check_source/check_style_c.py" \
|
||||
"$(BLENDER_DIR)/intern/cycles/kernel/shaders" \
|
||||
"$(BLENDER_DIR)/release/scripts/templates_osl"
|
||||
@@ -277,7 +291,7 @@ test_style_osl: FORCE
|
||||
test_style_osl_qtc: FORCE
|
||||
# run our own checks on C/C++ style
|
||||
USE_QTC_TASK=1 \
|
||||
PYTHONIOENCODING=utf_8 python3 \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/source/tools/check_source/check_style_c.py" \
|
||||
"$(BLENDER_DIR)/intern/cycles/kernel/shaders" \
|
||||
"$(BLENDER_DIR)/release/scripts/templates_osl" \
|
||||
@@ -290,10 +304,10 @@ test_style_osl_qtc: FORCE
|
||||
#
|
||||
|
||||
project_qtcreator: FORCE
|
||||
python3 build_files/cmake/cmake_qtcreator_project.py "$(BUILD_DIR)"
|
||||
$(PYTHON) build_files/cmake/cmake_qtcreator_project.py "$(BUILD_DIR)"
|
||||
|
||||
project_netbeans: FORCE
|
||||
python3 build_files/cmake/cmake_netbeans_project.py "$(BUILD_DIR)"
|
||||
$(PYTHON) build_files/cmake/cmake_netbeans_project.py "$(BUILD_DIR)"
|
||||
|
||||
project_eclipse: FORCE
|
||||
cmake -G"Eclipse CDT4 - Unix Makefiles" -H"$(BLENDER_DIR)" -B"$(BUILD_DIR)"
|
||||
@@ -306,39 +320,39 @@ project_eclipse: FORCE
|
||||
check_cppcheck: FORCE
|
||||
$(CMAKE_CONFIG)
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py" 2> \
|
||||
$(PYTHON) "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py" 2> \
|
||||
"$(BLENDER_DIR)/check_cppcheck.txt"
|
||||
@echo "written: check_cppcheck.txt"
|
||||
|
||||
check_clang_array: FORCE
|
||||
$(CMAKE_CONFIG)
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py"
|
||||
$(PYTHON) "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py"
|
||||
|
||||
check_splint: FORCE
|
||||
$(CMAKE_CONFIG)
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py"
|
||||
$(PYTHON) "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py"
|
||||
|
||||
check_sparse: FORCE
|
||||
$(CMAKE_CONFIG)
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py"
|
||||
$(PYTHON) "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py"
|
||||
|
||||
check_smatch: FORCE
|
||||
$(CMAKE_CONFIG)
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py"
|
||||
$(PYTHON) "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py"
|
||||
|
||||
check_spelling_py: FORCE
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
PYTHONIOENCODING=utf_8 python3 \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
|
||||
"$(BLENDER_DIR)/release/scripts"
|
||||
|
||||
check_spelling_c: FORCE
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
PYTHONIOENCODING=utf_8 python3 \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
|
||||
"$(BLENDER_DIR)/source" \
|
||||
"$(BLENDER_DIR)/intern/cycles" \
|
||||
@@ -347,7 +361,7 @@ check_spelling_c: FORCE
|
||||
|
||||
check_spelling_c_qtc: FORCE
|
||||
cd "$(BUILD_DIR)" ; USE_QTC_TASK=1 \
|
||||
PYTHONIOENCODING=utf_8 python3 \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
|
||||
"$(BLENDER_DIR)/source" \
|
||||
"$(BLENDER_DIR)/intern/cycles" \
|
||||
@@ -358,7 +372,7 @@ check_spelling_c_qtc: FORCE
|
||||
|
||||
check_spelling_osl: FORCE
|
||||
cd "$(BUILD_DIR)" ;\
|
||||
PYTHONIOENCODING=utf_8 python3 \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
|
||||
"$(BLENDER_DIR)/intern/cycles/kernel/shaders"
|
||||
|
||||
@@ -404,10 +418,10 @@ doc_dna: FORCE
|
||||
@echo "docs written into: '$(BLENDER_DIR)/doc/blender_file_format/dna.html'"
|
||||
|
||||
doc_man: FORCE
|
||||
python3 doc/manpage/blender.1.py "$(BUILD_DIR)/bin/blender"
|
||||
$(PYTHON) doc/manpage/blender.1.py "$(BUILD_DIR)/bin/blender"
|
||||
|
||||
help_features: FORCE
|
||||
@python3 -c \
|
||||
@$(PYTHON) -c \
|
||||
"import re; \
|
||||
print('\n'.join([ \
|
||||
w for l in open('"$(BLENDER_DIR)"/CMakeLists.txt', 'r').readlines() \
|
||||
|
30
SConstruct
30
SConstruct
@@ -514,6 +514,10 @@ if env['WITH_BF_STATICCXX']:
|
||||
else:
|
||||
print '\tcould not remove stdc++ library from LLIBS, WITH_BF_STATICCXX may not work for your platform'
|
||||
|
||||
# audaspace is needed for the game engine
|
||||
if not env['WITH_BF_AUDASPACE']:
|
||||
env['WITH_BF_GAMEENGINE'] = False
|
||||
|
||||
# check target for blenderplayer. Set WITH_BF_PLAYER if found on cmdline
|
||||
if 'blenderplayer' in B.targets:
|
||||
env['WITH_BF_PLAYER'] = True
|
||||
@@ -540,13 +544,25 @@ else:
|
||||
env['CPPFLAGS'].append('-D__LITTLE_ENDIAN__')
|
||||
|
||||
# TODO, make optional (as with CMake)
|
||||
env['CPPFLAGS'].append('-DWITH_AUDASPACE')
|
||||
env['CPPFLAGS'].append('-DWITH_AVI')
|
||||
env['CPPFLAGS'].append('-DWITH_OPENNL')
|
||||
|
||||
if env['OURPLATFORM'] not in ('win32-vc', 'win64-vc'):
|
||||
env['CPPFLAGS'].append('-DHAVE_STDBOOL_H')
|
||||
|
||||
# Audaspace
|
||||
|
||||
if env['WITH_BF_AUDASPACE']:
|
||||
env['BF_AUDASPACE_C_INC'] = '#intern/audaspace/intern'
|
||||
env['BF_AUDASPACE_PY_INC'] = '#intern/audaspace/intern'
|
||||
env['BF_AUDASPACE_DEF'] = ['WITH_AUDASPACE']
|
||||
env['BF_AUDASPACE_DEF'].append('AUD_DEVICE_H="<AUD_C-API.h>"')
|
||||
env['BF_AUDASPACE_DEF'].append('AUD_SPECIAL_H="<AUD_C-API.h>"')
|
||||
env['BF_AUDASPACE_DEF'].append('AUD_SOUND_H="<AUD_C-API.h>"')
|
||||
env['BF_AUDASPACE_DEF'].append('AUD_HANDLE_H="<AUD_C-API.h>"')
|
||||
env['BF_AUDASPACE_DEF'].append('AUD_SEQUENCE_H="<AUD_C-API.h>"')
|
||||
env['BF_AUDASPACE_DEF'].append('AUD_TYPES_H="<AUD_Space.h>"')
|
||||
|
||||
# OpenGL
|
||||
|
||||
if env['WITH_BF_GL_PROFILE_COMPAT']:
|
||||
@@ -766,6 +782,8 @@ if B.targets != ['cudakernels']:
|
||||
data_to_c_simple("release/datafiles/preview_cycles.blend")
|
||||
|
||||
# --- glsl ---
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_geometry.glsl")
|
||||
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_program_smoke_frag.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl")
|
||||
|
||||
@@ -789,6 +807,7 @@ if B.targets != ['cudakernels']:
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_vert.glsl")
|
||||
data_to_c_simple("intern/opencolorio/gpu_shader_display_transform.glsl")
|
||||
data_to_c_simple("intern/opensubdiv/gpu_shader_opensubd_display.glsl")
|
||||
|
||||
# --- blender ---
|
||||
data_to_c_simple("release/datafiles/bfont.pfb")
|
||||
@@ -1300,6 +1319,15 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
|
||||
windlls = env.Install(dir=env['BF_INSTALLDIR'], source = dllsources)
|
||||
allinstall += windlls
|
||||
|
||||
# TODO(sergey): For unti we've got better way to deal with python binary
|
||||
if env['WITH_BF_PYTHON']:
|
||||
py_target = os.path.join(env['BF_INSTALLDIR'], VERSION, 'python', 'bin')
|
||||
if env['BF_DEBUG']:
|
||||
allinstall += env.Install(dir=py_target, source = ['${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}_d.dll'])
|
||||
else:
|
||||
allinstall += env.Install(dir=py_target, source = ['${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}.dll'])
|
||||
|
||||
|
||||
if env['OURPLATFORM'] == 'win64-mingw':
|
||||
dllsources = []
|
||||
|
||||
|
@@ -27,9 +27,10 @@ getopt \
|
||||
-o s:i:t:h \
|
||||
--long source:,install:,tmp:,info:,threads:,help,no-sudo,with-all,with-opencollada,\
|
||||
ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,\
|
||||
force-all,force-python,force-numpy,force-boost,force-ocio,force-oiio,force-llvm,force-osl,force-opencollada,\
|
||||
force-ffmpeg,\
|
||||
skip-python,skip-numpy,skip-boost,skip-ocio,skip-openexr,skip-oiio,skip-llvm,skip-osl,skip-ffmpeg,skip-opencollada,\
|
||||
force-all,force-python,force-numpy,force-boost,force-ocio,force-oiio,force-llvm,force-osl,force-osd,\
|
||||
force-ffmpeg,force-opencollada,\
|
||||
skip-python,skip-numpy,skip-boost,skip-ocio,skip-openexr,skip-oiio,skip-llvm,skip-osl,skip-osd,\
|
||||
skip-ffmpeg,skip-opencollada,\
|
||||
required-numpy: \
|
||||
-- "$@" \
|
||||
)
|
||||
@@ -138,6 +139,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
|
||||
--force-osl
|
||||
Force the rebuild of OpenShadingLanguage.
|
||||
|
||||
--force-osd
|
||||
Force the rebuild of OpenSubdiv.
|
||||
|
||||
--force-opencollada
|
||||
Force the rebuild of OpenCOLLADA.
|
||||
|
||||
@@ -174,6 +178,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
|
||||
--skip-osl
|
||||
Unconditionally skip OpenShadingLanguage installation/building.
|
||||
|
||||
--skip-osd
|
||||
Unconditionally skip OpenSubdiv installation/building.
|
||||
|
||||
--skip-opencollada
|
||||
Unconditionally skip OpenCOLLADA installation/building.
|
||||
|
||||
@@ -233,6 +240,12 @@ OSL_VERSION_MIN=$OSL_VERSION
|
||||
OSL_FORCE_REBUILD=false
|
||||
OSL_SKIP=false
|
||||
|
||||
# OpenSubdiv needs to be compiled for now
|
||||
OSD_VERSION="3.0.2"
|
||||
OSD_VERSION_MIN=$OSD_VERSION
|
||||
OSD_FORCE_REBUILD=false
|
||||
OSD_SKIP=false
|
||||
|
||||
# Version??
|
||||
OPENCOLLADA_VERSION="1.3"
|
||||
OPENCOLLADA_FORCE_REBUILD=false
|
||||
@@ -375,6 +388,11 @@ while true; do
|
||||
OSL_VERSION_MIN=$OSL_VERSION
|
||||
shift; shift; continue
|
||||
;;
|
||||
--ver-osd)
|
||||
OSD_VERSION="$2"
|
||||
OSD_VERSION_MIN=$OSD_VERSION
|
||||
shift; shift; continue
|
||||
;;
|
||||
--force-all)
|
||||
PYTHON_FORCE_REBUILD=true
|
||||
NUMPY_FORCE_REBUILD=true
|
||||
@@ -384,6 +402,7 @@ while true; do
|
||||
OIIO_FORCE_REBUILD=true
|
||||
LLVM_FORCE_REBUILD=true
|
||||
OSL_FORCE_REBUILD=true
|
||||
OSD_FORCE_REBUILD=true
|
||||
OPENCOLLADA_FORCE_REBUILD=true
|
||||
FFMPEG_FORCE_REBUILD=true
|
||||
shift; continue
|
||||
@@ -417,6 +436,9 @@ while true; do
|
||||
--force-osl)
|
||||
OSL_FORCE_REBUILD=true; shift; continue
|
||||
;;
|
||||
--force-osd)
|
||||
OSD_FORCE_REBUILD=true; shift; continue
|
||||
;;
|
||||
--force-opencollada)
|
||||
OPENCOLLADA_FORCE_REBUILD=true; shift; continue
|
||||
;;
|
||||
@@ -447,6 +469,9 @@ while true; do
|
||||
--skip-osl)
|
||||
OSL_SKIP=true; shift; continue
|
||||
;;
|
||||
--skip-osd)
|
||||
OSD_SKIP=true; shift; continue
|
||||
;;
|
||||
--skip-opencollada)
|
||||
OPENCOLLADA_SKIP=true; shift; continue
|
||||
;;
|
||||
@@ -509,6 +534,14 @@ OSL_SOURCE_REPO=( "https://github.com/Nazg-Gul/OpenShadingLanguage.git" )
|
||||
OSL_SOURCE_REPO_UID="22ee5ea298fd215430dfbd160b5aefd507f06db0"
|
||||
OSL_SOURCE_REPO_BRANCH="blender-fixes"
|
||||
|
||||
OSD_USE_REPO=true
|
||||
# Script foo to make the version string compliant with the archive name:
|
||||
# ${Varname//SearchForThisChar/ReplaceWithThisChar}
|
||||
OSD_SOURCE=( "https://github.com/PixarAnimationStudios/OpenSubdiv/archive/v${OSD_VERSION//./_}.tar.gz" )
|
||||
OSD_SOURCE_REPO=( "https://github.com/PixarAnimationStudios/OpenSubdiv.git" )
|
||||
OSD_SOURCE_REPO_UID="404659fffa659da075d1c9416e4fc939139a84ee"
|
||||
OSD_SOURCE_REPO_BRANCH="dev"
|
||||
|
||||
OPENCOLLADA_SOURCE=( "https://github.com/KhronosGroup/OpenCOLLADA.git" )
|
||||
OPENCOLLADA_REPO_UID="3335ac164e68b2512a40914b14c74db260e6ff7d"
|
||||
FFMPEG_SOURCE=( "http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2" )
|
||||
@@ -1522,6 +1555,99 @@ compile_OSL() {
|
||||
run_ldconfig "osl"
|
||||
}
|
||||
|
||||
#### Build OSD ####
|
||||
_init_osd() {
|
||||
_src=$SRC/OpenSubdiv-$OSD_VERSION
|
||||
_git=true
|
||||
_inst=$INST/osd-$OSD_VERSION
|
||||
_inst_shortcut=$INST/osd
|
||||
}
|
||||
|
||||
clean_OSD() {
|
||||
_init_osd
|
||||
_clean
|
||||
}
|
||||
|
||||
compile_OSD() {
|
||||
# To be changed each time we make edits that would modify the compiled result!
|
||||
osd_magic=0
|
||||
_init_osd
|
||||
|
||||
# Clean install if needed!
|
||||
magic_compile_check osd-$OSD_VERSION $osd_magic
|
||||
if [ $? -eq 1 -o $OSD_FORCE_REBUILD == true ]; then
|
||||
clean_OSD
|
||||
fi
|
||||
|
||||
if [ ! -d $_inst ]; then
|
||||
INFO "Building OpenSubdiv-$OSD_VERSION"
|
||||
|
||||
prepare_opt
|
||||
|
||||
if [ ! -d $_src ]; then
|
||||
mkdir -p $SRC
|
||||
|
||||
if [ $OSD_USE_REPO == true ]; then
|
||||
git clone ${OSD_SOURCE_REPO[0]} $_src
|
||||
else
|
||||
download OSD_SOURCE[@] "$_src.tar.gz"
|
||||
INFO "Unpacking OpenSubdiv-$OSD_VERSION"
|
||||
tar -C $SRC --transform "s,(.*/?)OpenSubdiv-[^/]*(.*),\1OpenSubdiv-$OSD_VERSION\2,x" \
|
||||
-xf $_src.tar.gz
|
||||
fi
|
||||
fi
|
||||
|
||||
cd $_src
|
||||
|
||||
if [ $OSD_USE_REPO == true ]; then
|
||||
git remote set-url origin ${OSD_SOURCE_REPO[0]}
|
||||
# XXX For now, always update from latest repo...
|
||||
git pull --no-edit -X theirs origin $OSD_SOURCE_REPO_BRANCH
|
||||
# Stick to same rev as windows' libs...
|
||||
git checkout $OSD_SOURCE_REPO_UID
|
||||
git reset --hard
|
||||
fi
|
||||
|
||||
# Always refresh the whole build!
|
||||
if [ -d build ]; then
|
||||
rm -rf build
|
||||
fi
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake_d="-D CMAKE_BUILD_TYPE=Release"
|
||||
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
|
||||
# ptex is only needed when nicholas bishop is ready
|
||||
cmake_d="$cmake_d -D NO_PTEX=1"
|
||||
cmake_d="$cmake_d -D NO_CLEW=1"
|
||||
# maya plugin, docs, tutorials, regression tests and examples are not needed
|
||||
cmake_d="$cmake_d -D NO_MAYA=1 -D NO_DOC=1 -D NO_TUTORIALS=1 -D NO_REGRESSION=1 -DNO_EXAMPLES=1"
|
||||
|
||||
cmake $cmake_d ..
|
||||
|
||||
make -j$THREADS && make install
|
||||
make clean
|
||||
|
||||
if [ -d $_inst ]; then
|
||||
_create_inst_shortcut
|
||||
else
|
||||
ERROR "OpenSubdiv-$OSD_VERSION failed to compile, exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
magic_compile_set osd-$OSD_VERSION $osd_magic
|
||||
|
||||
cd $CWD
|
||||
INFO "Done compiling OpenSubdiv-$OSD_VERSION!"
|
||||
else
|
||||
INFO "Own OpenSubdiv-$OSD_VERSION is up to date, nothing to do!"
|
||||
INFO "If you want to force rebuild of this lib, use the --force-osd option."
|
||||
fi
|
||||
|
||||
run_ldconfig "osd"
|
||||
}
|
||||
|
||||
|
||||
#### Build OpenCOLLADA ####
|
||||
_init_opencollada() {
|
||||
_src=$SRC/OpenCOLLADA-$OPENCOLLADA_VERSION
|
||||
@@ -1813,8 +1939,9 @@ install_DEB() {
|
||||
THEORA_DEV="libtheora-dev"
|
||||
|
||||
_packages="gawk cmake cmake-curses-gui scons build-essential libjpeg-dev libpng-dev \
|
||||
libfreetype6-dev libx11-dev libxi-dev wget libsqlite3-dev libbz2-dev \
|
||||
libncurses5-dev libssl-dev liblzma-dev libreadline-dev $OPENJPEG_DEV \
|
||||
libfreetype6-dev libx11-dev \
|
||||
libxcursor-dev libxi-dev wget libsqlite3-dev libxrandr-dev libxinerama-dev \
|
||||
libbz2-dev libncurses5-dev libssl-dev liblzma-dev libreadline-dev $OPENJPEG_DEV \
|
||||
libopenal-dev libglew-dev libglewmx-dev yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV \
|
||||
libsdl1.2-dev libfftw3-dev patch bzip2 libxml2-dev libtinyxml-dev"
|
||||
|
||||
@@ -2089,6 +2216,20 @@ install_DEB() {
|
||||
fi
|
||||
fi
|
||||
|
||||
PRINT ""
|
||||
if $OSD_SKIP; then
|
||||
WARNING "Skipping OpenSubdiv installation, as requested..."
|
||||
else
|
||||
if $have_llvm; then
|
||||
install_packages_DEB flex bison libtbb-dev
|
||||
# No package currently!
|
||||
PRINT ""
|
||||
compile_OSD
|
||||
else
|
||||
WARNING "No LLVM available, cannot build OSD!"
|
||||
fi
|
||||
fi
|
||||
|
||||
if $WITH_OPENCOLLADA; then
|
||||
PRINT ""
|
||||
if $OPENCOLLADA_SKIP; then
|
||||
@@ -2287,9 +2428,9 @@ install_RPM() {
|
||||
OGG_DEV="libogg-devel"
|
||||
THEORA_DEV="libtheora-devel"
|
||||
|
||||
_packages="gcc gcc-c++ make scons libtiff-devel libjpeg-devel\
|
||||
libpng-devel libX11-devel libXi-devel wget ncurses-devel \
|
||||
readline-devel $OPENJPEG_DEV openal-soft-devel \
|
||||
_packages="gcc gcc-c++ git make cmake scons libtiff-devel libjpeg-devel\
|
||||
libpng-devel libX11-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel \
|
||||
wget ncurses-devel readline-devel $OPENJPEG_DEV openal-soft-devel \
|
||||
glew-devel yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV patch \
|
||||
libxml2-devel yaml-cpp-devel tinyxml-devel"
|
||||
|
||||
@@ -2516,7 +2657,7 @@ install_RPM() {
|
||||
else
|
||||
if $have_llvm; then
|
||||
# No package currently!
|
||||
install_packages_RPM flex bison git
|
||||
install_packages_RPM flex bison
|
||||
if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
|
||||
install_packages_RPM tbb-devel
|
||||
fi
|
||||
@@ -2527,12 +2668,29 @@ install_RPM() {
|
||||
fi
|
||||
fi
|
||||
|
||||
PRINT ""
|
||||
if $OSD_SKIP; then
|
||||
WARNING "Skipping OpenSubdiv installation, as requested..."
|
||||
else
|
||||
if $have_llvm; then
|
||||
# No package currently!
|
||||
install_packages_RPM flex bison
|
||||
if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
|
||||
install_packages_RPM tbb-devel
|
||||
fi
|
||||
PRINT ""
|
||||
compile_OSD
|
||||
else
|
||||
WARNING "No LLVM available, cannot build OSD!"
|
||||
fi
|
||||
fi
|
||||
|
||||
if $WITH_OPENCOLLADA; then
|
||||
PRINT ""
|
||||
if $OPENCOLLADA_SKIP; then
|
||||
WARNING "Skipping OpenCOLLADA installation, as requested..."
|
||||
else
|
||||
install_packages_RPM pcre-devel git
|
||||
install_packages_RPM pcre-devel
|
||||
# Find path to libxml shared lib...
|
||||
_XML2_LIB=`rpm -ql libxml2-devel | grep -e ".*/libxml2.so"`
|
||||
# No package...
|
||||
@@ -2640,7 +2798,8 @@ install_ARCH() {
|
||||
OGG_DEV="libogg"
|
||||
THEORA_DEV="libtheora"
|
||||
|
||||
_packages="base-devel scons cmake libxi glew libpng libtiff wget openal \
|
||||
_packages="base-devel git scons cmake \
|
||||
libxi libxcursor libxrandr libxinerama glew libpng libtiff wget openal \
|
||||
$OPENJPEG_DEV $VORBIS_DEV $OGG_DEV $THEORA_DEV yasm sdl fftw \
|
||||
libxml2 yaml-cpp tinyxml"
|
||||
|
||||
@@ -2827,7 +2986,7 @@ install_ARCH() {
|
||||
clean_OSL
|
||||
else
|
||||
#XXX Note: will fail to build with LLVM 3.2!
|
||||
install_packages_ARCH git intel-tbb
|
||||
install_packages_ARCH intel-tbb
|
||||
PRINT ""
|
||||
compile_OSL
|
||||
fi
|
||||
@@ -2836,6 +2995,20 @@ install_ARCH() {
|
||||
fi
|
||||
fi
|
||||
|
||||
PRINT ""
|
||||
if $OSD_SKIP; then
|
||||
WARNING "Skipping OpenSubdiv installation, as requested..."
|
||||
else
|
||||
if $have_llvm; then
|
||||
# No package currently? Just build for now!
|
||||
install_packages_ARCH intel-tbb
|
||||
PRINT ""
|
||||
compile_OSD
|
||||
else
|
||||
WARNING "No LLVM available, cannot build OSD!"
|
||||
fi
|
||||
fi
|
||||
|
||||
if $WITH_OPENCOLLADA; then
|
||||
PRINT ""
|
||||
if $OPENCOLLADA_SKIP; then
|
||||
@@ -2846,7 +3019,7 @@ install_ARCH() {
|
||||
install_packages_ARCH opencollada
|
||||
clean_OpenCOLLADA
|
||||
else
|
||||
install_packages_ARCH pcre git
|
||||
install_packages_ARCH pcre
|
||||
PRINT ""
|
||||
compile_OpenCOLLADA
|
||||
fi
|
||||
@@ -3011,6 +3184,14 @@ print_info() {
|
||||
_buildargs="$_buildargs $_1 $_2"
|
||||
fi
|
||||
|
||||
if [ -d $INST/osd ]; then
|
||||
_1="-D WITH_OPENSUBDIV=ON"
|
||||
_2="-D OPENSUBDIV_ROOT_DIR=$INST/osd"
|
||||
PRINT " $_1"
|
||||
PRINT " $_2"
|
||||
_buildargs="$_buildargs $_1 $_2"
|
||||
fi
|
||||
|
||||
if $WITH_OPENCOLLADA; then
|
||||
_1="-D WITH_OPENCOLLADA=ON"
|
||||
PRINT " $_1"
|
||||
@@ -3077,6 +3258,13 @@ print_info() {
|
||||
PRINT "BF_OSL = '$INST/osl'"
|
||||
fi
|
||||
|
||||
if [ "$OSD_SKIP" = false ]; then
|
||||
PRINT "WITH_BF_OPENSUBDIV = True"
|
||||
if [ -d $INST/osd ]; then
|
||||
PRINT "BF_OPENSUBDIV = '$INST/osd'"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$BOOST_SKIP" = false ]; then
|
||||
PRINT "WITH_BF_BOOST = True"
|
||||
if [ -d $INST/boost ]; then
|
||||
@@ -3123,7 +3311,27 @@ elif [ -f /etc/redhat-release -o /etc/SuSE-release ]; then
|
||||
DISTRO="RPM"
|
||||
install_RPM
|
||||
else
|
||||
ERROR "Failed to detect distribution type"
|
||||
ERROR "Failed to detect distribution type."
|
||||
PRINT ""
|
||||
PRINT "Your distribution is not supported by this script, you'll have to install dependencies and"
|
||||
PRINT "dev packages yourself (list non-exhaustive, but should cover most needs):"
|
||||
PRINT " * Basics of dev environment (cmake or scons, gcc, svn , git, ...)."
|
||||
PRINT " * Python$PYTHON_VERSION_MIN, numpy."
|
||||
PRINT " * libboost$BOOST_VERSION_MIN (locale, filesystem, regex, system, thread, wave)."
|
||||
PRINT " * libjpeg, libpng, libtiff, libopenjpeg, libopenal."
|
||||
PRINT " * ffmpeg (with libvorbis, libogg, libtheora, libx264, libmp3lame, libxvidcore, libvpx, ...)."
|
||||
PRINT " * libx11, libxcursor, libxi, libxrandr, libxinerama (and other libx... as needed)."
|
||||
PRINT " * libsqlite3, libbz2, libssl, libfftw3, libxml2, libtinyxml, yasm, libyaml-cpp."
|
||||
PRINT " * libsdl1.2, libglew, libglewmx."
|
||||
PRINT " * libopencolorio$OCIO_VERSION_MIN, libopenexr$OPENEXR_VERSION_MIN, libopenimageio$OIIO_VERSION_MIN."
|
||||
PRINT " * llvm-$LLVM_VERSION (with clang)."
|
||||
PRINT ""
|
||||
PRINT "Most of up-listed packages are available in recent distributions. The following are likely not,"
|
||||
PRINT "you'll have to build them (they are all optional, though):"
|
||||
PRINT " * OpenShadingLanguage (from https://github.com/Nazg-Gul/OpenShadingLanguage.git, branch blender-fixes, commit 22ee5ea298fd215430dfbd160b5aefd507f06db0)."
|
||||
PRINT " * OpenSubDiv (from https://github.com/PixarAnimationStudios/OpenSubdiv.git, branch dev, commit 404659fffa659da075d1c9416e4fc939139a84ee)."
|
||||
PRINT " * OpenCollada (from https://github.com/KhronosGroup/OpenCOLLADA.git, branch master, commit 3335ac164e68b2512a40914b14c74db260e6ff7d)."
|
||||
PRINT ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@@ -2,4 +2,5 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
|
||||
BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
|
||||
BF_NUMJOBS = 1
|
||||
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50', 'sm_52']
|
||||
#BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50', 'sm_52']
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = []
|
||||
|
@@ -166,6 +166,15 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
|
||||
# Ocean Simulation
|
||||
WITH_BF_OCEANSIM = True
|
||||
|
||||
# OpenSubdiv
|
||||
WITH_BF_OPENSUBDIV = True
|
||||
WITH_BF_STATICOPENSUBDIV = True
|
||||
BF_OPENSUBDIV = '/opt/lib/opensubdiv'
|
||||
BF_OPENSUBDIV_INC = '${BF_OPENSUBDIV}/include'
|
||||
BF_OPENSUBDIV_LIB = 'osdCPU osdGPU'
|
||||
BF_OPENSUBDIV_LIBPATH = '${BF_OPENSUBDIV}/lib'
|
||||
BF_OPENSUBDIV_LIB_STATIC = '${BF_OPENSUBDIV}/lib/libosdCPU.a ${BF_OPENSUBDIV}/lib/libosdGPU.a'
|
||||
|
||||
# Compilation and optimization
|
||||
BF_DEBUG = False
|
||||
REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
|
||||
|
@@ -166,6 +166,15 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
|
||||
# Ocean Simulation
|
||||
WITH_BF_OCEANSIM = True
|
||||
|
||||
# OpenSubdiv
|
||||
WITH_BF_OPENSUBDIV = True
|
||||
WITH_BF_STATICOPENSUBDIV = True
|
||||
BF_OPENSUBDIV = '/opt/lib/opensubdiv'
|
||||
BF_OPENSUBDIV_INC = '${BF_OPENSUBDIV}/include'
|
||||
BF_OPENSUBDIV_LIB = 'osdCPU osdGPU'
|
||||
BF_OPENSUBDIV_LIBPATH = '${BF_OPENSUBDIV}/lib'
|
||||
BF_OPENSUBDIV_LIB_STATIC = '${BF_OPENSUBDIV}/lib/libosdCPU.a ${BF_OPENSUBDIV}/lib/libosdGPU.a'
|
||||
|
||||
# Compilation and optimization
|
||||
BF_DEBUG = False
|
||||
REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
|
||||
|
@@ -4,7 +4,7 @@
|
||||
# <pep8 compliant>
|
||||
|
||||
# List of the branches being built automatically overnight
|
||||
NIGHT_SCHEDULE_BRANCHES = [None, "gooseberry"]
|
||||
NIGHT_SCHEDULE_BRANCHES = [None]
|
||||
|
||||
# List of the branches available for force build
|
||||
FORCE_SCHEDULE_BRANCHES = ["master", "gooseberry", "experimental-build"]
|
||||
@@ -305,12 +305,12 @@ add_builder(c, 'mac_x86_64_10_6_scons', 'darwin-9.x.universal', generic_builder,
|
||||
add_builder(c, 'mac_i386_10_6_scons', 'darwin-9.x.universal', generic_builder, hour=11)
|
||||
add_builder(c, 'linux_glibc211_i386_scons', '', generic_builder, hour=1)
|
||||
add_builder(c, 'linux_glibc211_x86_64_scons', '', generic_builder, hour=2)
|
||||
add_builder(c, 'win32_scons_vc2013', 'windows_vc12', generic_builder, hour=1)
|
||||
add_builder(c, 'win64_scons_vc2013', 'win64_vc12', generic_builder, hour=2)
|
||||
#add_builder(c, 'win32_scons_vc2013', 'windows_vc12', generic_builder, hour=1)
|
||||
#add_builder(c, 'win64_scons_vc2013', 'win64_vc12', generic_builder, hour=2)
|
||||
add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=3)
|
||||
add_builder(c, 'win64_cmake_vc2013', 'win64_vc12', generic_builder, hour=4)
|
||||
#add_builder(c, 'mingw_win32_scons', 'mingw32', generic_builder, hour=4)
|
||||
add_builder(c, 'mingw_win64_scons', 'mingw64', generic_builder, hour=3)
|
||||
#add_builder(c, 'mingw_win64_scons', 'mingw64', generic_builder, hour=3)
|
||||
#add_builder(c, 'freebsd_i386_cmake', '', generic_builder, hour=1)
|
||||
#add_builder(c, 'freebsd_x86_64_cmake', '', generic_builder, hour=2)
|
||||
|
||||
|
@@ -57,7 +57,10 @@ if 'cmake' in builder:
|
||||
retcode = subprocess.call(['cmake', blender_dir] + cmake_options)
|
||||
if retcode != 0:
|
||||
sys.exit(retcode)
|
||||
if 'win' in builder:
|
||||
|
||||
if 'win32' in builder:
|
||||
retcode = subprocess.call(['msbuild', 'INSTALL.vcxproj', '/Property:PlatformToolset=v120_xp', '/p:Configuration=Release'])
|
||||
elif 'win64' in builder:
|
||||
retcode = subprocess.call(['msbuild', 'INSTALL.vcxproj', '/p:Configuration=Release'])
|
||||
else:
|
||||
retcode = subprocess.call(['make', '-s', '-j4', 'install'])
|
||||
|
@@ -123,14 +123,26 @@ else:
|
||||
os.remove(f)
|
||||
retcode = subprocess.call(['cpack', '-G', 'ZIP'])
|
||||
result_file = [f for f in os.listdir('.') if os.path.isfile(f) and f.endswith('.zip')][0]
|
||||
os.rename(result_file, "{}.zip".format(builder))
|
||||
|
||||
# TODO(sergey): Such magic usually happens in SCon's packaging bu we don't have it
|
||||
# in the CMake yet. For until then we do some magic here.
|
||||
tokens = result_file.split('-')
|
||||
blender_version = tokens[1].split('.')
|
||||
blender_full_version = '.'.join(blender_version[0:2])
|
||||
git_hash = tokens[2].split('.')[1]
|
||||
platform = builder.split('_')[0]
|
||||
builderified_name = 'blender-{}-{}-{}'.format(blender_full_version, git_hash, platform)
|
||||
if branch != '':
|
||||
builderified_name = branch + "-" + builderified_name
|
||||
|
||||
os.rename(result_file, "{}.zip".format(builderified_name))
|
||||
# create zip file
|
||||
try:
|
||||
upload_zip = "buildbot_upload.zip"
|
||||
if os.path.exists(upload_zip):
|
||||
os.remove(upload_zip)
|
||||
z = zipfile.ZipFile(upload_zip, "w", compression=zipfile.ZIP_STORED)
|
||||
z.write("{}.zip".format(builder))
|
||||
z.write("{}.zip".format(builderified_name))
|
||||
z.close()
|
||||
sys.exit(retcode)
|
||||
except Exception as ex:
|
||||
|
113
build_files/cmake/Modules/FindAudaspace.cmake
Normal file
113
build_files/cmake/Modules/FindAudaspace.cmake
Normal file
@@ -0,0 +1,113 @@
|
||||
# - Try to find audaspace
|
||||
# Once done, this will define
|
||||
#
|
||||
# AUDASPACE_FOUND - system has audaspace
|
||||
# AUDASPACE_INCLUDE_DIRS - the audaspace include directories
|
||||
# AUDASPACE_LIBRARIES - link these to use audaspace
|
||||
# AUDASPACE_C_FOUND - system has audaspace's C binding
|
||||
# AUDASPACE_C_INCLUDE_DIRS - the audaspace's C binding include directories
|
||||
# AUDASPACE_C_LIBRARIES - link these to use audaspace's C binding
|
||||
# AUDASPACE_PY_FOUND - system has audaspace's python binding
|
||||
# AUDASPACE_PY_INCLUDE_DIRS - the audaspace's python binding include directories
|
||||
# AUDASPACE_PY_LIBRARIES - link these to use audaspace's python binding
|
||||
|
||||
IF(NOT AUDASPACE_ROOT_DIR AND NOT $ENV{AUDASPACE_ROOT_DIR} STREQUAL "")
|
||||
SET(AUDASPACE_ROOT_DIR $ENV{AUDASPACE_ROOT_DIR})
|
||||
ENDIF()
|
||||
|
||||
SET(_audaspace_SEARCH_DIRS
|
||||
${AUDASPACE_ROOT_DIR}
|
||||
/usr/local
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
)
|
||||
|
||||
# Use pkg-config to get hints about paths
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
IF(PKG_CONFIG_FOUND)
|
||||
PKG_CHECK_MODULES(AUDASPACE_PKGCONF audaspace)
|
||||
ENDIF(PKG_CONFIG_FOUND)
|
||||
|
||||
# Include dir
|
||||
FIND_PATH(AUDASPACE_INCLUDE_DIR
|
||||
NAMES ISound.h
|
||||
HINTS ${_audaspace_SEARCH_DIRS}
|
||||
PATHS ${AUDASPACE_PKGCONF_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES include/audaspace
|
||||
)
|
||||
|
||||
# Library
|
||||
FIND_LIBRARY(AUDASPACE_LIBRARY
|
||||
NAMES audaspace
|
||||
HINTS ${_audaspace_SEARCH_DIRS}
|
||||
PATHS ${AUDASPACE_PKGCONF_LIBRARY_DIRS}
|
||||
PATH_SUFFIXES lib lib64
|
||||
)
|
||||
|
||||
# Include dir
|
||||
FIND_PATH(AUDASPACE_C_INCLUDE_DIR
|
||||
NAMES AUD_Sound.h
|
||||
HINTS ${_audaspace_SEARCH_DIRS}
|
||||
PATHS ${AUDASPACE_PKGCONF_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES include/audaspace
|
||||
)
|
||||
|
||||
# Library
|
||||
FIND_LIBRARY(AUDASPACE_C_LIBRARY
|
||||
NAMES audaspace-c
|
||||
HINTS ${_audaspace_SEARCH_DIRS}
|
||||
PATHS ${AUDASPACE_PKGCONF_LIBRARY_DIRS}
|
||||
PATH_SUFFIXES lib lib64
|
||||
)
|
||||
|
||||
# Include dir
|
||||
FIND_PATH(AUDASPACE_PY_INCLUDE_DIR
|
||||
NAMES python/PyAPI.h
|
||||
HINTS ${_audaspace_SEARCH_DIRS}
|
||||
PATHS ${AUDASPACE_PKGCONF_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES include/audaspace
|
||||
)
|
||||
|
||||
# Library
|
||||
FIND_LIBRARY(AUDASPACE_PY_LIBRARY
|
||||
NAMES audaspace-py
|
||||
HINTS ${_audaspace_SEARCH_DIRS}
|
||||
PATHS ${AUDASPACE_PKGCONF_LIBRARY_DIRS}
|
||||
PATH_SUFFIXES lib lib64
|
||||
)
|
||||
|
||||
FIND_PACKAGE(PackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Audaspace DEFAULT_MSG AUDASPACE_LIBRARY AUDASPACE_INCLUDE_DIR)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Audaspace_C DEFAULT_MSG AUDASPACE_C_LIBRARY AUDASPACE_C_INCLUDE_DIR)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Audaspace_Py DEFAULT_MSG AUDASPACE_PY_LIBRARY AUDASPACE_PY_INCLUDE_DIR)
|
||||
|
||||
IF(AUDASPACE_FOUND)
|
||||
SET(AUDASPACE_LIBRARIES ${AUDASPACE_LIBRARY})
|
||||
SET(AUDASPACE_INCLUDE_DIRS ${AUDASPACE_INCLUDE_DIR})
|
||||
ENDIF(AUDASPACE_FOUND)
|
||||
|
||||
IF(AUDASPACE_C_FOUND)
|
||||
SET(AUDASPACE_C_LIBRARIES ${AUDASPACE_C_LIBRARY})
|
||||
SET(AUDASPACE_C_INCLUDE_DIRS ${AUDASPACE_C_INCLUDE_DIR})
|
||||
ENDIF(AUDASPACE_C_FOUND)
|
||||
|
||||
IF(AUDASPACE_PY_FOUND)
|
||||
SET(AUDASPACE_PY_LIBRARIES ${AUDASPACE_PY_LIBRARY})
|
||||
SET(AUDASPACE_PY_INCLUDE_DIRS ${AUDASPACE_PY_INCLUDE_DIR})
|
||||
ENDIF(AUDASPACE_PY_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
AUDASPACE_LIBRARY
|
||||
AUDASPACE_LIBRARIES
|
||||
AUDASPACE_INCLUDE_DIR
|
||||
AUDASPACE_INCLUDE_DIRS
|
||||
AUDASPACE_C_LIBRARY
|
||||
AUDASPACE_C_LIBRARIES
|
||||
AUDASPACE_C_INCLUDE_DIR
|
||||
AUDASPACE_C_INCLUDE_DIRS
|
||||
AUDASPACE_PY_LIBRARY
|
||||
AUDASPACE_PY_LIBRARIES
|
||||
AUDASPACE_PY_INCLUDE_DIR
|
||||
AUDASPACE_PY_INCLUDE_DIRS
|
||||
)
|
@@ -59,7 +59,8 @@ FIND_LIBRARY(OPENIMAGEIO_LIBRARY
|
||||
FIND_FILE(OPENIMAGEIO_IDIFF
|
||||
NAMES
|
||||
idiff
|
||||
${OPENIMAGEIO_ROOT_DIR}
|
||||
HINTS
|
||||
${OPENIMAGEIO_ROOT_DIR}
|
||||
PATH_SUFFIXES
|
||||
bin
|
||||
)
|
||||
|
111
build_files/cmake/Modules/FindOpenSubdiv.cmake
Normal file
111
build_files/cmake/Modules/FindOpenSubdiv.cmake
Normal file
@@ -0,0 +1,111 @@
|
||||
# - Find OpenSubdiv library
|
||||
# Find the native OpenSubdiv includes and library
|
||||
# This module defines
|
||||
# OPENSUBDIV_INCLUDE_DIRS, where to find OpenSubdiv headers, Set when
|
||||
# OPENSUBDIV_INCLUDE_DIR is found.
|
||||
# OPENSUBDIV_LIBRARIES, libraries to link against to use OpenSubdiv.
|
||||
# OPENSUBDIV_ROOT_DIR, the base directory to search for OpenSubdiv.
|
||||
# This can also be an environment variable.
|
||||
# OPENSUBDIV_FOUND, if false, do not try to use OpenSubdiv.
|
||||
#
|
||||
# also defined, but not for general use are
|
||||
# OPENSUBDIV_LIBRARY, where to find the OpenSubdiv library.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2013 Blender Foundation.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
|
||||
# If OPENSUBDIV_ROOT_DIR was defined in the environment, use it.
|
||||
IF(NOT OPENSUBDIV_ROOT_DIR AND NOT $ENV{OPENSUBDIV_ROOT_DIR} STREQUAL "")
|
||||
SET(OPENSUBDIV_ROOT_DIR $ENV{OPENSUBDIV_ROOT_DIR})
|
||||
ENDIF()
|
||||
|
||||
SET(_opensubdiv_FIND_COMPONENTS
|
||||
osdGPU
|
||||
osdCPU
|
||||
)
|
||||
|
||||
SET(_opensubdiv_SEARCH_DIRS
|
||||
${OPENSUBDIV_ROOT_DIR}
|
||||
/usr/local
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt/lib/opensubdiv
|
||||
)
|
||||
|
||||
FIND_PATH(OPENSUBDIV_INCLUDE_DIR
|
||||
NAMES
|
||||
opensubdiv/osd/mesh.h
|
||||
HINTS
|
||||
${_opensubdiv_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
||||
SET(_opensubdiv_LIBRARIES)
|
||||
FOREACH(COMPONENT ${_opensubdiv_FIND_COMPONENTS})
|
||||
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
|
||||
|
||||
FIND_LIBRARY(OPENSUBDIV_${UPPERCOMPONENT}_LIBRARY
|
||||
NAMES
|
||||
${COMPONENT}
|
||||
HINTS
|
||||
${_opensubdiv_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
LIST(APPEND _opensubdiv_LIBRARIES "${OPENSUBDIV_${UPPERCOMPONENT}_LIBRARY}")
|
||||
ENDFOREACH()
|
||||
|
||||
MACRO(OPENSUBDIV_CHECK_CONTROLLER
|
||||
controller_include_file
|
||||
variable_name)
|
||||
IF(EXISTS "${OPENSUBDIV_INCLUDE_DIR}/opensubdiv/osd/${controller_include_file}")
|
||||
SET(${variable_name} TRUE)
|
||||
ELSE()
|
||||
SET(${variable_name} FALSE)
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set OPENSUBDIV_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenSubdiv DEFAULT_MSG
|
||||
_opensubdiv_LIBRARIES OPENSUBDIV_INCLUDE_DIR)
|
||||
|
||||
IF(OPENSUBDIV_FOUND)
|
||||
SET(OPENSUBDIV_LIBRARIES ${_opensubdiv_LIBRARIES})
|
||||
SET(OPENSUBDIV_INCLUDE_DIRS ${OPENSUBDIV_INCLUDE_DIR})
|
||||
|
||||
# Find available compute controllers.
|
||||
|
||||
FIND_PACKAGE(OpenMP)
|
||||
IF(OPENMP_FOUND)
|
||||
SET(OPENSUBDIV_HAS_OPENMP TRUE)
|
||||
ELSE()
|
||||
SET(OPENSUBDIV_HAS_OPENMP FALSE)
|
||||
ENDIF()
|
||||
|
||||
OPENSUBDIV_CHECK_CONTROLLER("tbbEvaluator.h" OPENSUBDIV_HAS_TBB)
|
||||
OPENSUBDIV_CHECK_CONTROLLER("clEvaluator.h" OPENSUBDIV_HAS_OPENCL)
|
||||
OPENSUBDIV_CHECK_CONTROLLER("cudaEvaluator.h" OPENSUBDIV_HAS_CUDA)
|
||||
OPENSUBDIV_CHECK_CONTROLLER("glXFBEvaluator.h" OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
|
||||
OPENSUBDIV_CHECK_CONTROLLER("glComputeEvaluator.h" OPENSUBDIV_HAS_GLSL_COMPUTE)
|
||||
ENDIF(OPENSUBDIV_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
OPENSUBDIV_INCLUDE_DIR
|
||||
)
|
||||
FOREACH(COMPONENT ${_opensubdiv_FIND_COMPONENTS})
|
||||
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
|
||||
MARK_AS_ADVANCED(OPENSUBDIV_${UPPERCOMPONENT}_LIBRARY)
|
||||
ENDFOREACH()
|
@@ -12,7 +12,7 @@
|
||||
#
|
||||
#=============================================================================
|
||||
|
||||
macro(BLENDER_SRC_GTEST NAME SRC EXTRA_LIBS)
|
||||
macro(BLENDER_SRC_GTEST_EX NAME SRC EXTRA_LIBS DO_ADD_TEST)
|
||||
if(WITH_GTESTS)
|
||||
get_property(_current_include_directories
|
||||
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
@@ -40,10 +40,20 @@ macro(BLENDER_SRC_GTEST NAME SRC EXTRA_LIBS)
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${TESTS_OUTPUT_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${TESTS_OUTPUT_DIR}"
|
||||
INCLUDE_DIRECTORIES "${TEST_INC}")
|
||||
add_test(${NAME}_test ${TESTS_OUTPUT_DIR}/${NAME}_test)
|
||||
if(${DO_ADD_TEST})
|
||||
add_test(${NAME}_test ${TESTS_OUTPUT_DIR}/${NAME}_test)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(BLENDER_TEST NAME EXTRA_LIBS)
|
||||
BLENDER_SRC_GTEST("${NAME}" "${NAME}_test.cc" "${EXTRA_LIBS}")
|
||||
macro(BLENDER_SRC_GTEST NAME SRC EXTRA_LIBS)
|
||||
BLENDER_SRC_GTEST_EX("${NAME}" "${SRC}" "${EXTRA_LIBS}" "TRUE")
|
||||
endmacro()
|
||||
|
||||
macro(BLENDER_TEST NAME EXTRA_LIBS)
|
||||
BLENDER_SRC_GTEST_EX("${NAME}" "${NAME}_test.cc" "${EXTRA_LIBS}" "TRUE")
|
||||
endmacro()
|
||||
|
||||
macro(BLENDER_TEST_PERFORMANCE NAME EXTRA_LIBS)
|
||||
BLENDER_SRC_GTEST_EX("${NAME}" "${NAME}_test.cc" "${EXTRA_LIBS}" "FALSE")
|
||||
endmacro()
|
||||
|
@@ -97,6 +97,10 @@ if(EXISTS ${SOURCE_DIR}/.git)
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
OUTPUT_VARIABLE MY_WC_COMMIT_TIMESTAMP
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
# May fail in rare cases
|
||||
if(MY_WC_COMMIT_TIMESTAMP STREQUAL "")
|
||||
set(MY_WC_COMMIT_TIMESTAMP 0)
|
||||
endif()
|
||||
|
||||
# Update GIT index before getting dirty files
|
||||
execute_process(COMMAND git update-index -q --refresh
|
||||
|
@@ -40,6 +40,7 @@ from project_info import (
|
||||
# is_py,
|
||||
cmake_advanced_info,
|
||||
cmake_compiler_defines,
|
||||
cmake_cache_var,
|
||||
project_name_get,
|
||||
)
|
||||
|
||||
@@ -71,6 +72,10 @@ def create_nb_project_main():
|
||||
# be tricky, get the project name from git if we can!
|
||||
PROJECT_NAME = project_name_get()
|
||||
|
||||
|
||||
make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM")
|
||||
make_exe_basename = os.path.basename(make_exe)
|
||||
|
||||
# --------------- NB spesific
|
||||
defines = [("%s=%s" % cdef) if cdef[1] else cdef[0] for cdef in defines]
|
||||
defines += [cdef.replace("#define", "").strip() for cdef in cmake_compiler_defines()]
|
||||
@@ -131,9 +136,9 @@ def create_nb_project_main():
|
||||
f = open(join(PROJECT_DIR_NB, "configurations.xml"), 'w')
|
||||
|
||||
f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
|
||||
f.write('<configurationDescriptor version="94">\n')
|
||||
f.write('<configurationDescriptor version="95">\n')
|
||||
f.write(' <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">\n')
|
||||
f.write(' <df name="0" root="%s">\n' % SOURCE_DIR) # base_root_rel
|
||||
f.write(' <df root="%s" name="0">\n' % SOURCE_DIR) # base_root_rel
|
||||
|
||||
# write files!
|
||||
files_rel_local = [normpath(relpath(join(CMAKE_DIR, path), SOURCE_DIR)) for path in files_rel]
|
||||
@@ -185,16 +190,27 @@ def create_nb_project_main():
|
||||
|
||||
f.write(' <toolsSet>\n')
|
||||
f.write(' <compilerSet>default</compilerSet>\n')
|
||||
f.write(' <dependencyChecking>false</dependencyChecking>\n')
|
||||
f.write(' <rebuildPropChanged>false</rebuildPropChanged>\n')
|
||||
f.write(' </toolsSet>\n')
|
||||
f.write(' <dependencyChecking>false</dependencyChecking>\n')
|
||||
f.write(' <rebuildPropChanged>false</rebuildPropChanged>\n')
|
||||
f.write(' <codeAssistance>\n')
|
||||
f.write(' </codeAssistance>\n')
|
||||
f.write(' <makefileType>\n')
|
||||
|
||||
f.write(' <makeTool>\n')
|
||||
f.write(' <buildCommandWorkingDir>.</buildCommandWorkingDir>\n')
|
||||
f.write(' <buildCommand>${MAKE} -f Makefile</buildCommand>\n')
|
||||
f.write(' <cleanCommand>${MAKE} -f Makefile clean</cleanCommand>\n')
|
||||
|
||||
if make_exe_basename == "ninja":
|
||||
build_cmd = "ninja"
|
||||
clean_cmd = "ninja -t clean"
|
||||
else:
|
||||
build_cmd = "${MAKE} -f Makefile"
|
||||
clean_cmd = "${MAKE} -f Makefile clean"
|
||||
|
||||
f.write(' <buildCommand>%s</buildCommand>\n' % build_cmd)
|
||||
f.write(' <cleanCommand>%s</cleanCommand>\n' % clean_cmd)
|
||||
f.write(' <executablePath>./bin/blender</executablePath>\n')
|
||||
del build_cmd, clean_cmd
|
||||
|
||||
def write_toolinfo():
|
||||
f.write(' <incDir>\n')
|
||||
@@ -221,10 +237,11 @@ def create_nb_project_main():
|
||||
f.write(' \n')
|
||||
|
||||
for path in files_rel_local:
|
||||
is_c = path.endswith(".c")
|
||||
f.write(' <item path="%s"\n' % path)
|
||||
f.write(' ex="false"\n')
|
||||
f.write(' tool="1"\n')
|
||||
f.write(' flavor2="0">\n')
|
||||
f.write(' tool="%d"\n' % (0 if is_c else 1))
|
||||
f.write(' flavor2="%d">\n' % (3 if is_c else 0))
|
||||
f.write(' </item>\n')
|
||||
|
||||
f.write(' <runprofile version="9">\n')
|
||||
|
@@ -1,5 +1,4 @@
|
||||
# turn everything OFF except for python which defaults to ON
|
||||
# and is needed for the UI
|
||||
# Turn everything ON thats expected for an official release builds.
|
||||
#
|
||||
# Example usage:
|
||||
# cmake -C../blender/build_files/cmake/config/blender_full.cmake ../blender
|
||||
@@ -13,6 +12,7 @@ set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS ON CACHE BOOL "" FORCE)
|
||||
set(WITH_GAMEENGINE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
|
||||
@@ -52,11 +52,18 @@ set(WITH_X11_XF86VMODE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_PLAYER ON CACHE BOOL "" FORCE)
|
||||
set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
|
||||
|
||||
|
||||
# platform dependant options
|
||||
if(UNIX AND NOT APPLE)
|
||||
set(WITH_JACK ON CACHE BOOL "" FORCE)
|
||||
set(WITH_DOC_MANPAGE ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
|
||||
elseif(WIN32)
|
||||
set(WITH_JACK OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
|
||||
elseif (APPLE)
|
||||
set(WITH_JACK ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
|
@@ -16,6 +16,7 @@ set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_LLVM OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_GAMEENGINE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
|
||||
|
@@ -48,7 +48,7 @@ macro(list_insert_before
|
||||
unset(_index)
|
||||
endmacro()
|
||||
|
||||
function (list_assert_duplicates
|
||||
function(list_assert_duplicates
|
||||
list_id
|
||||
)
|
||||
|
||||
@@ -104,21 +104,31 @@ macro(file_list_suffix
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(target_link_libraries_optimized TARGET LIBS)
|
||||
function(target_link_libraries_optimized
|
||||
TARGET
|
||||
LIBS
|
||||
)
|
||||
|
||||
foreach(_LIB ${LIBS})
|
||||
target_link_libraries(${TARGET} optimized "${_LIB}")
|
||||
endforeach()
|
||||
unset(_LIB)
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
function(target_link_libraries_debug
|
||||
TARGET
|
||||
LIBS
|
||||
)
|
||||
|
||||
macro(target_link_libraries_debug TARGET LIBS)
|
||||
foreach(_LIB ${LIBS})
|
||||
target_link_libraries(${TARGET} debug "${_LIB}")
|
||||
endforeach()
|
||||
unset(_LIB)
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
function(target_link_libraries_decoupled
|
||||
target
|
||||
libraries_var
|
||||
)
|
||||
|
||||
macro(target_link_libraries_decoupled target libraries_var)
|
||||
if(NOT MSVC)
|
||||
target_link_libraries(${target} ${${libraries_var}})
|
||||
else()
|
||||
@@ -127,14 +137,15 @@ macro(target_link_libraries_decoupled target libraries_var)
|
||||
file_list_suffix(_libraries_debug "${${libraries_var}}" "_d")
|
||||
target_link_libraries_debug(${target} "${_libraries_debug}")
|
||||
target_link_libraries_optimized(${target} "${${libraries_var}}")
|
||||
unset(_libraries_debug)
|
||||
endif()
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
# Nicer makefiles with -I/1/foo/ instead of -I/1/2/3/../../foo/
|
||||
# use it instead of include_directories()
|
||||
macro(blender_include_dirs
|
||||
includes)
|
||||
function(blender_include_dirs
|
||||
includes
|
||||
)
|
||||
|
||||
set(_ALL_INCS "")
|
||||
foreach(_INC ${ARGV})
|
||||
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
|
||||
@@ -145,13 +156,12 @@ macro(blender_include_dirs
|
||||
##endif()
|
||||
endforeach()
|
||||
include_directories(${_ALL_INCS})
|
||||
unset(_INC)
|
||||
unset(_ABS_INC)
|
||||
unset(_ALL_INCS)
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
function(blender_include_dirs_sys
|
||||
includes
|
||||
)
|
||||
|
||||
macro(blender_include_dirs_sys
|
||||
includes)
|
||||
set(_ALL_INCS "")
|
||||
foreach(_INC ${ARGV})
|
||||
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
|
||||
@@ -161,13 +171,11 @@ macro(blender_include_dirs_sys
|
||||
##endif()
|
||||
endforeach()
|
||||
include_directories(SYSTEM ${_ALL_INCS})
|
||||
unset(_INC)
|
||||
unset(_ABS_INC)
|
||||
unset(_ALL_INCS)
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
macro(blender_source_group
|
||||
sources)
|
||||
function(blender_source_group
|
||||
sources
|
||||
)
|
||||
|
||||
# Group by location on disk
|
||||
source_group("Source Files" FILES CMakeLists.txt)
|
||||
@@ -177,23 +185,23 @@ macro(blender_source_group
|
||||
if((${_SRC_EXT} MATCHES ".h") OR
|
||||
(${_SRC_EXT} MATCHES ".hpp") OR
|
||||
(${_SRC_EXT} MATCHES ".hh"))
|
||||
source_group("Header Files" FILES ${_SRC})
|
||||
else()
|
||||
source_group("Source Files" FILES ${_SRC})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
unset(_SRC)
|
||||
unset(_SRC_EXT)
|
||||
endmacro()
|
||||
set(GROUP_ID "Header Files")
|
||||
else()
|
||||
set(GROUP_ID "Source Files")
|
||||
endif()
|
||||
source_group("${GROUP_ID}" FILES ${_SRC})
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
|
||||
# only MSVC uses SOURCE_GROUP
|
||||
macro(blender_add_lib_nolist
|
||||
function(blender_add_lib_nolist
|
||||
name
|
||||
sources
|
||||
includes
|
||||
includes_sys)
|
||||
includes_sys
|
||||
)
|
||||
|
||||
# message(STATUS "Configuring library ${name}")
|
||||
|
||||
@@ -213,22 +221,24 @@ macro(blender_add_lib_nolist
|
||||
# Not for system includes because they can resolve to the same path
|
||||
# list_assert_duplicates("${includes_sys}")
|
||||
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(blender_add_lib
|
||||
function(blender_add_lib
|
||||
name
|
||||
sources
|
||||
includes
|
||||
includes_sys)
|
||||
includes_sys
|
||||
)
|
||||
|
||||
blender_add_lib_nolist(${name} "${sources}" "${includes}" "${includes_sys}")
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY BLENDER_LINK_LIBS ${name})
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(SETUP_LIBDIRS)
|
||||
function(SETUP_LIBDIRS)
|
||||
|
||||
link_directories(${JPEG_LIBPATH} ${PNG_LIBPATH} ${ZLIB_LIBPATH} ${FREETYPE_LIBPATH})
|
||||
|
||||
if(WITH_PYTHON) # AND NOT WITH_PYTHON_MODULE # WIN32 needs
|
||||
@@ -288,24 +298,27 @@ macro(SETUP_LIBDIRS)
|
||||
if(WIN32 AND NOT UNIX)
|
||||
link_directories(${PTHREADS_LIBPATH})
|
||||
endif()
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
macro(setup_liblinks
|
||||
target)
|
||||
function(setup_liblinks
|
||||
target
|
||||
)
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}" PARENT_SCOPE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}" PARENT_SCOPE)
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}" PARENT_SCOPE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}" PARENT_SCOPE)
|
||||
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}" PARENT_SCOPE)
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}" PARENT_SCOPE)
|
||||
|
||||
target_link_libraries(${target}
|
||||
${PNG_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${FREETYPE_LIBRARY})
|
||||
target_link_libraries(
|
||||
${target}
|
||||
${PNG_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${FREETYPE_LIBRARY}
|
||||
)
|
||||
|
||||
# since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions
|
||||
if(WITH_PYTHON) # AND NOT WITH_PYTHON_MODULE # WIN32 needs
|
||||
@@ -330,6 +343,9 @@ macro(setup_liblinks
|
||||
if(WITH_BULLET AND WITH_SYSTEM_BULLET)
|
||||
target_link_libraries(${target} ${BULLET_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_AUDASPACE AND WITH_SYSTEM_AUDASPACE)
|
||||
target_link_libraries(${target} ${AUDASPACE_C_LIBRARIES} ${AUDASPACE_PY_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_OPENAL)
|
||||
target_link_libraries(${target} ${OPENAL_LIBRARY})
|
||||
endif()
|
||||
@@ -357,6 +373,16 @@ macro(setup_liblinks
|
||||
if(WITH_OPENCOLORIO)
|
||||
target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_OPENSUBDIV)
|
||||
if(WIN32 AND NOT UNIX)
|
||||
file_list_suffix(OPENSUBDIV_LIBRARIES_DEBUG "${OPENSUBDIV_LIBRARIES}" "_d")
|
||||
target_link_libraries_debug(${target} "${OPENSUBDIV_LIBRARIES_DEBUG}")
|
||||
target_link_libraries_optimized(${target} "${OPENSUBDIV_LIBRARIES}")
|
||||
unset(OPENSUBDIV_LIBRARIES_DEBUG)
|
||||
else()
|
||||
target_link_libraries(${target} ${OPENSUBDIV_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_CYCLES_OSL)
|
||||
target_link_libraries(${target} ${OSL_LIBRARIES})
|
||||
endif()
|
||||
@@ -402,11 +428,13 @@ macro(setup_liblinks
|
||||
unset(EXPAT_LIB_DEBUG)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(${target}
|
||||
${OPENCOLLADA_LIBRARIES}
|
||||
${PCRE_LIBRARIES}
|
||||
${XML2_LIBRARIES}
|
||||
${EXPAT_LIB})
|
||||
target_link_libraries(
|
||||
${target}
|
||||
${OPENCOLLADA_LIBRARIES}
|
||||
${PCRE_LIBRARIES}
|
||||
${XML2_LIBRARIES}
|
||||
${EXPAT_LIB}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_MEM_JEMALLOC)
|
||||
@@ -436,9 +464,11 @@ macro(setup_liblinks
|
||||
${BLENDER_GL_LIBRARIES})
|
||||
|
||||
target_link_libraries(${target} ${PLATFORM_LINKLIBS} ${CMAKE_DL_LIBS})
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(SETUP_BLENDER_SORTED_LIBS)
|
||||
|
||||
macro(SETUP_BLENDER_SORTED_LIBS)
|
||||
get_property(BLENDER_LINK_LIBS GLOBAL PROPERTY BLENDER_LINK_LIBS)
|
||||
|
||||
list(APPEND BLENDER_LINK_LIBS
|
||||
@@ -578,6 +608,7 @@ macro(SETUP_BLENDER_SORTED_LIBS)
|
||||
extern_libmv
|
||||
extern_glog
|
||||
extern_sdlew
|
||||
extern_eigen3
|
||||
|
||||
bf_intern_glew_mx
|
||||
)
|
||||
@@ -656,6 +687,10 @@ macro(SETUP_BLENDER_SORTED_LIBS)
|
||||
list_insert_after(BLENDER_SORTED_LIBS "ge_logic_ngnetwork" "extern_bullet")
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
list(APPEND BLENDER_SORTED_LIBS bf_intern_opensubdiv)
|
||||
endif()
|
||||
|
||||
foreach(SORTLIB ${BLENDER_SORTED_LIBS})
|
||||
set(REMLIB ${SORTLIB})
|
||||
foreach(SEARCHLIB ${BLENDER_LINK_LIBS})
|
||||
@@ -674,14 +709,12 @@ macro(SETUP_BLENDER_SORTED_LIBS)
|
||||
message(STATUS "Blender Skipping: (${REM_MSG})")
|
||||
endif()
|
||||
|
||||
unset(SEARCHLIB)
|
||||
unset(SORTLIB)
|
||||
unset(REMLIB)
|
||||
unset(REM_MSG)
|
||||
|
||||
set(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} PARENT_SCOPE)
|
||||
|
||||
# for top-level tests
|
||||
set_property(GLOBAL PROPERTY BLENDER_SORTED_LIBS_PROP ${BLENDER_SORTED_LIBS})
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
macro(TEST_SSE_SUPPORT
|
||||
_sse_flags
|
||||
@@ -903,19 +936,22 @@ endmacro()
|
||||
|
||||
# utility macro
|
||||
macro(remove_cc_flag
|
||||
flag)
|
||||
_flag)
|
||||
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
foreach(flag ${ARGV})
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
|
||||
string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
endforeach()
|
||||
unset(flag)
|
||||
|
||||
endmacro()
|
||||
|
||||
@@ -929,28 +965,34 @@ endmacro()
|
||||
macro(remove_strict_flags)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
remove_cc_flag("-Wstrict-prototypes")
|
||||
remove_cc_flag("-Wmissing-prototypes")
|
||||
remove_cc_flag("-Wunused-parameter")
|
||||
remove_cc_flag("-Wunused-macros")
|
||||
remove_cc_flag("-Wwrite-strings")
|
||||
remove_cc_flag("-Wredundant-decls")
|
||||
remove_cc_flag("-Wundef")
|
||||
remove_cc_flag("-Wshadow")
|
||||
remove_cc_flag("-Wdouble-promotion")
|
||||
remove_cc_flag("-Wold-style-definition")
|
||||
remove_cc_flag("-Werror=[^ ]+")
|
||||
remove_cc_flag("-Werror")
|
||||
remove_cc_flag(
|
||||
"-Wstrict-prototypes"
|
||||
"-Wmissing-prototypes"
|
||||
"-Wmissing-format-attribute"
|
||||
"-Wunused-local-typedefs"
|
||||
"-Wunused-macros"
|
||||
"-Wunused-parameter"
|
||||
"-Wwrite-strings"
|
||||
"-Wredundant-decls"
|
||||
"-Wundef"
|
||||
"-Wshadow"
|
||||
"-Wdouble-promotion"
|
||||
"-Wold-style-definition"
|
||||
"-Werror=[^ ]+"
|
||||
"-Werror"
|
||||
)
|
||||
|
||||
# negate flags implied by '-Wall'
|
||||
add_cc_flag("${CC_REMOVE_STRICT_FLAGS}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
remove_cc_flag("-Wunused-parameter")
|
||||
remove_cc_flag("-Wunused-variable")
|
||||
remove_cc_flag("-Werror=[^ ]+")
|
||||
remove_cc_flag("-Werror")
|
||||
remove_cc_flag(
|
||||
"-Wunused-parameter"
|
||||
"-Wunused-variable"
|
||||
"-Werror=[^ ]+"
|
||||
"-Werror"
|
||||
)
|
||||
|
||||
# negate flags implied by '-Wall'
|
||||
add_cc_flag("${CC_REMOVE_STRICT_FLAGS}")
|
||||
@@ -964,11 +1006,15 @@ endmacro()
|
||||
|
||||
macro(remove_extra_strict_flags)
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
remove_cc_flag("-Wunused-parameter")
|
||||
remove_cc_flag(
|
||||
"-Wunused-parameter"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
remove_cc_flag("-Wunused-parameter")
|
||||
remove_cc_flag(
|
||||
"-Wunused-parameter"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
@@ -1004,37 +1050,39 @@ macro(remove_strict_flags_file
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(ADD_CHECK_C_COMPILER_FLAG
|
||||
function(ADD_CHECK_C_COMPILER_FLAG
|
||||
_CFLAGS
|
||||
_CACHE_VAR
|
||||
_FLAG)
|
||||
_FLAG
|
||||
)
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
CHECK_C_COMPILER_FLAG("${_FLAG}" "${_CACHE_VAR}")
|
||||
if(${_CACHE_VAR})
|
||||
# message(STATUS "Using CFLAG: ${_FLAG}")
|
||||
set(${_CFLAGS} "${${_CFLAGS}} ${_FLAG}")
|
||||
set(${_CFLAGS} "${${_CFLAGS}} ${_FLAG}" PARENT_SCOPE)
|
||||
else()
|
||||
message(STATUS "Unsupported CFLAG: ${_FLAG}")
|
||||
endif()
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
macro(ADD_CHECK_CXX_COMPILER_FLAG
|
||||
function(ADD_CHECK_CXX_COMPILER_FLAG
|
||||
_CXXFLAGS
|
||||
_CACHE_VAR
|
||||
_FLAG)
|
||||
_FLAG
|
||||
)
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
CHECK_CXX_COMPILER_FLAG("${_FLAG}" "${_CACHE_VAR}")
|
||||
if(${_CACHE_VAR})
|
||||
# message(STATUS "Using CXXFLAG: ${_FLAG}")
|
||||
set(${_CXXFLAGS} "${${_CXXFLAGS}} ${_FLAG}")
|
||||
set(${_CXXFLAGS} "${${_CXXFLAGS}} ${_FLAG}" PARENT_SCOPE)
|
||||
else()
|
||||
message(STATUS "Unsupported CXXFLAG: ${_FLAG}")
|
||||
endif()
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
function(get_blender_version)
|
||||
# extracts header vars and defines them in the parent scope:
|
||||
@@ -1184,7 +1232,7 @@ endmacro()
|
||||
# pair of macros to allow libraries to be specify files to install, but to
|
||||
# only install them at the end so the directories don't get cleared with
|
||||
# the files in them. used by cycles to install addon.
|
||||
macro(delayed_install
|
||||
function(delayed_install
|
||||
base
|
||||
files
|
||||
destination)
|
||||
@@ -1197,8 +1245,7 @@ macro(delayed_install
|
||||
endif()
|
||||
set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_DESTINATIONS ${destination})
|
||||
endforeach()
|
||||
unset(f)
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
# note this is a function instead of a macro so that ${BUILD_TYPE} in targetdir
|
||||
# does not get expanded in calling but is preserved
|
||||
@@ -1217,16 +1264,17 @@ function(delayed_do_install
|
||||
list(GET destinations ${i} d)
|
||||
install(FILES ${f} DESTINATION ${targetdir}/${d})
|
||||
endforeach()
|
||||
unset(f)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(data_to_c
|
||||
file_from file_to
|
||||
list_to_add)
|
||||
function(data_to_c
|
||||
file_from file_to
|
||||
list_to_add
|
||||
)
|
||||
|
||||
list(APPEND ${list_to_add} ${file_to})
|
||||
set(${list_to_add} ${${list_to_add}} PARENT_SCOPE)
|
||||
|
||||
get_filename_component(_file_to_path ${file_to} PATH)
|
||||
|
||||
@@ -1237,21 +1285,21 @@ macro(data_to_c
|
||||
DEPENDS ${file_from} datatoc)
|
||||
|
||||
set_source_files_properties(${file_to} PROPERTIES GENERATED TRUE)
|
||||
|
||||
unset(_file_to_path)
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
|
||||
# same as above but generates the var name and output automatic.
|
||||
macro(data_to_c_simple
|
||||
file_from
|
||||
list_to_add)
|
||||
function(data_to_c_simple
|
||||
file_from
|
||||
list_to_add
|
||||
)
|
||||
|
||||
# remove ../'s
|
||||
get_filename_component(_file_from ${CMAKE_CURRENT_SOURCE_DIR}/${file_from} REALPATH)
|
||||
get_filename_component(_file_to ${CMAKE_CURRENT_BINARY_DIR}/${file_from}.c REALPATH)
|
||||
|
||||
list(APPEND ${list_to_add} ${_file_to})
|
||||
set(${list_to_add} ${${list_to_add}} PARENT_SCOPE)
|
||||
|
||||
get_filename_component(_file_to_path ${_file_to} PATH)
|
||||
|
||||
@@ -1262,17 +1310,13 @@ macro(data_to_c_simple
|
||||
DEPENDS ${_file_from} datatoc)
|
||||
|
||||
set_source_files_properties(${_file_to} PROPERTIES GENERATED TRUE)
|
||||
|
||||
unset(_file_from)
|
||||
unset(_file_to)
|
||||
unset(_file_to_path)
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
# macro for converting pixmap directory to a png and then a c file
|
||||
macro(data_to_c_simple_icons
|
||||
path_from
|
||||
list_to_add
|
||||
)
|
||||
function(data_to_c_simple_icons
|
||||
path_from
|
||||
list_to_add
|
||||
)
|
||||
|
||||
# Conversion steps
|
||||
# path_from -> _file_from -> _file_to
|
||||
@@ -1284,6 +1328,7 @@ macro(data_to_c_simple_icons
|
||||
get_filename_component(_file_to ${CMAKE_CURRENT_BINARY_DIR}/${path_from}.png.c REALPATH)
|
||||
|
||||
list(APPEND ${list_to_add} ${_file_to})
|
||||
set(${list_to_add} ${${list_to_add}} PARENT_SCOPE)
|
||||
|
||||
get_filename_component(_file_to_path ${_file_to} PATH)
|
||||
|
||||
@@ -1305,27 +1350,22 @@ macro(data_to_c_simple_icons
|
||||
)
|
||||
|
||||
set_source_files_properties(${_file_from} ${_file_to} PROPERTIES GENERATED TRUE)
|
||||
|
||||
unset(_path_from_abs)
|
||||
unset(_file_from)
|
||||
unset(_file_to)
|
||||
unset(_file_to_path)
|
||||
unset(_icon_files)
|
||||
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
# XXX Not used for now...
|
||||
macro(svg_to_png
|
||||
file_from
|
||||
file_to
|
||||
dpi
|
||||
list_to_add)
|
||||
function(svg_to_png
|
||||
file_from
|
||||
file_to
|
||||
dpi
|
||||
list_to_add
|
||||
)
|
||||
|
||||
# remove ../'s
|
||||
get_filename_component(_file_from ${CMAKE_CURRENT_SOURCE_DIR}/${file_from} REALPATH)
|
||||
get_filename_component(_file_to ${CMAKE_CURRENT_SOURCE_DIR}/${file_to} REALPATH)
|
||||
|
||||
list(APPEND ${list_to_add} ${_file_to})
|
||||
set(${list_to_add} ${${list_to_add}} PARENT_SCOPE)
|
||||
|
||||
find_program(INKSCAPE_EXE inkscape)
|
||||
mark_as_advanced(INKSCAPE_EXE)
|
||||
@@ -1348,15 +1388,12 @@ macro(svg_to_png
|
||||
else()
|
||||
message(WARNING "Inkscape not found, could not re-generate ${_file_to} from ${_file_from}!")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
unset(_file_from)
|
||||
unset(_file_to)
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(msgfmt_simple
|
||||
file_from
|
||||
list_to_add)
|
||||
function(msgfmt_simple
|
||||
file_from
|
||||
list_to_add
|
||||
)
|
||||
|
||||
# remove ../'s
|
||||
get_filename_component(_file_from_we ${file_from} NAME_WE)
|
||||
@@ -1365,6 +1402,7 @@ macro(msgfmt_simple
|
||||
get_filename_component(_file_to ${CMAKE_CURRENT_BINARY_DIR}/${_file_from_we}.mo REALPATH)
|
||||
|
||||
list(APPEND ${list_to_add} ${_file_to})
|
||||
set(${list_to_add} ${${list_to_add}} PARENT_SCOPE)
|
||||
|
||||
get_filename_component(_file_to_path ${_file_to} PATH)
|
||||
|
||||
@@ -1375,15 +1413,11 @@ macro(msgfmt_simple
|
||||
DEPENDS msgfmt ${_file_from})
|
||||
|
||||
set_source_files_properties(${_file_to} PROPERTIES GENERATED TRUE)
|
||||
endfunction()
|
||||
|
||||
unset(_file_from_we)
|
||||
unset(_file_from)
|
||||
unset(_file_to)
|
||||
unset(_file_to_path)
|
||||
endmacro()
|
||||
|
||||
macro(find_python_package
|
||||
package)
|
||||
function(find_python_package
|
||||
package
|
||||
)
|
||||
|
||||
string(TOUPPER ${package} _upper_package)
|
||||
|
||||
@@ -1421,25 +1455,17 @@ macro(find_python_package
|
||||
"'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/dist-packages/${package}', "
|
||||
"'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/dist-packages/${package}', "
|
||||
"WITH_PYTHON_INSTALL_${_upper_package} option will be ignored when installing python")
|
||||
set(WITH_PYTHON_INSTALL_${_upper_package} OFF)
|
||||
set(WITH_PYTHON_INSTALL_${_upper_package} OFF PARENT_SCOPE)
|
||||
else()
|
||||
message(STATUS "${package} found at '${PYTHON_${_upper_package}_PATH}'")
|
||||
endif()
|
||||
|
||||
unset(_PY_VER_SPLIT)
|
||||
unset(_PY_VER_MAJOR)
|
||||
endif()
|
||||
|
||||
unset(_upper_package)
|
||||
endmacro()
|
||||
endfunction()
|
||||
|
||||
# like Python's 'print(dir())'
|
||||
macro(print_all_vars)
|
||||
function(print_all_vars)
|
||||
get_cmake_property(_vars VARIABLES)
|
||||
foreach(_var ${_vars})
|
||||
message("${_var}=${${_var}}")
|
||||
endforeach()
|
||||
unset(_vars)
|
||||
unset(_var)
|
||||
endmacro()
|
||||
|
||||
endfunction()
|
||||
|
@@ -24,7 +24,7 @@ if(EXISTS ${CMAKE_SOURCE_DIR}/.git/)
|
||||
include(FindGit)
|
||||
if(GIT_FOUND)
|
||||
message(STATUS "-- Found Git: ${GIT_EXECUTABLE}")
|
||||
execute_process(COMMAND git rev-parse --short @{u}
|
||||
execute_process(COMMAND git rev-parse --short HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE MY_WC_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
|
@@ -130,7 +130,7 @@ def is_project_file(filename):
|
||||
|
||||
|
||||
def cmake_advanced_info():
|
||||
""" Extracr includes and defines from cmake.
|
||||
""" Extract includes and defines from cmake.
|
||||
"""
|
||||
|
||||
make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM")
|
||||
|
@@ -59,14 +59,21 @@ def is_c_any(filename):
|
||||
CMAKE_DIR = "."
|
||||
|
||||
|
||||
def cmake_cache_var(var):
|
||||
cache_file = open(join(CMAKE_DIR, "CMakeCache.txt"))
|
||||
lines = [l_strip for l in cache_file for l_strip in (l.strip(),) if l_strip if not l_strip.startswith("//") if not l_strip.startswith("#")]
|
||||
cache_file.close()
|
||||
def cmake_cache_var_iter():
|
||||
import re
|
||||
re_cache = re.compile(r'([A-Za-z0-9_\-]+)?:?([A-Za-z0-9_\-]+)?=(.*)$')
|
||||
with open(join(CMAKE_DIR, "CMakeCache.txt"), 'r', encoding='utf-8') as cache_file:
|
||||
for l in cache_file:
|
||||
match = re_cache.match(l.strip())
|
||||
if match is not None:
|
||||
var, type_, val = match.groups()
|
||||
yield (var, type_ or "", val)
|
||||
|
||||
for l in lines:
|
||||
if l.split(":")[0] == var:
|
||||
return l.split("=", 1)[-1]
|
||||
|
||||
def cmake_cache_var(var):
|
||||
for var_iter, type_iter, value_iter in cmake_cache_var_iter():
|
||||
if var == var_iter:
|
||||
return value_iter
|
||||
return None
|
||||
|
||||
|
||||
|
@@ -52,6 +52,8 @@ BF_CXX = '/usr'
|
||||
WITH_BF_STATICCXX = False
|
||||
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
|
||||
|
||||
WITH_BF_AUDASPACE = True
|
||||
|
||||
# we use simply jack framework
|
||||
WITH_BF_JACK = True
|
||||
BF_JACK = '/Library/Frameworks/Jackmp.framework'
|
||||
@@ -213,6 +215,12 @@ WITH_BF_FREESTYLE = True
|
||||
#OpenMP ( will be checked for compiler support and turned off eventually )
|
||||
WITH_BF_OPENMP = True
|
||||
|
||||
WITH_BF_OPENSUBDIV = False
|
||||
BF_OPENSUBDIV = LIBDIR + '/opensubdiv'
|
||||
BF_OPENSUBDIV_INC = '${BF_OPENSUBDIV}/include'
|
||||
BF_OPENSUBDIV_LIB = 'osdCPU osdGPU'
|
||||
BF_OPENSUBDIV_LIBPATH = '${BF_OPENSUBDIV}/lib'
|
||||
|
||||
#Ray trace optimization
|
||||
WITH_BF_RAYOPTIMIZATION = True
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = []
|
||||
|
@@ -26,6 +26,8 @@ BF_CXX = '/usr'
|
||||
WITH_BF_STATICCXX = False
|
||||
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
|
||||
|
||||
WITH_BF_AUDASPACE = True
|
||||
|
||||
WITH_BF_JACK = False
|
||||
BF_JACK = '/usr'
|
||||
BF_JACK_INC = '${BF_JACK}/include/jack'
|
||||
@@ -206,7 +208,7 @@ WITH_BF_CYCLES = WITH_BF_OIIO and WITH_BF_BOOST
|
||||
|
||||
WITH_BF_CYCLES_CUDA_BINARIES = False
|
||||
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50', 'sm_52']
|
||||
|
||||
WITH_BF_OPENMP = True
|
||||
|
||||
@@ -226,6 +228,14 @@ BF_3DMOUSE_LIB_STATIC = '${BF_3DMOUSE_LIBPATH}/libspnav.a'
|
||||
#Freestyle
|
||||
WITH_BF_FREESTYLE = True
|
||||
|
||||
WITH_BF_OPENSUBDIV = False
|
||||
WITH_BF_STATICOPENSUBDIV = False
|
||||
BF_OPENSUBDIV = '/usr'
|
||||
BF_OPENSUBDIV_INC = '${BF_OPENSUBDIV}/include'
|
||||
BF_OPENSUBDIV_LIB = 'osdCPU osdGPU'
|
||||
BF_OPENSUBDIV_LIB_STATIC = '${BF_OPENSUBDIV_LIBPATH}/libosdGPU.a ${BF_OPENSUBDIV_LIBPATH}/libosdCPU.a'
|
||||
BF_OPENSUBDIV_LIBPATH = '${BF_OPENSUBDIV}/lib'
|
||||
|
||||
##
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
|
@@ -23,6 +23,8 @@ BF_FFMPEG_LIBPATH = LIBDIR + '/ffmpeg/lib'
|
||||
BF_FFMPEG_INC = LIBDIR + '/ffmpeg/include'
|
||||
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-55.dll ${BF_FFMPEG_LIBPATH}/avcodec-55.dll ${BF_FFMPEG_LIBPATH}/avdevice-55.dll ${BF_FFMPEG_LIBPATH}/avutil-52.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
|
||||
|
||||
WITH_BF_AUDASPACE = True
|
||||
|
||||
WITH_BF_JACK = False
|
||||
BF_JACK = LIBDIR + '/jack'
|
||||
BF_JACK_INC = '${BF_JACK}/include'
|
||||
@@ -145,7 +147,7 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
|
||||
WITH_BF_CYCLES = True
|
||||
WITH_BF_CYCLES_CUDA_BINARIES = False
|
||||
BF_CYCLES_CUDA_NVCC = "" # Path to the NVIDIA CUDA compiler
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50', 'sm_52']
|
||||
|
||||
WITH_BF_OIIO = True
|
||||
BF_OIIO = LIBDIR + '/openimageio'
|
||||
@@ -166,6 +168,12 @@ BF_BOOST_LIB = 'boost_date_time-mgw46-mt-s-1_49 boost_filesystem-mgw46-mt-s-1_49
|
||||
BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mgw46-mt-s-1_49'
|
||||
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
|
||||
|
||||
WITH_BF_OPENSUBDIV = False
|
||||
BF_OPENSUBDIV = LIBDIR + '/opensubdiv'
|
||||
BF_OPENSUBDIV_INC = '${BF_OPENSUBDIV}/include'
|
||||
BF_OPENSUBDIV_LIB = 'osdCPU osdGPU'
|
||||
BF_OPENSUBDIV_LIBPATH = '${BF_OPENSUBDIV}/lib'
|
||||
|
||||
#Ray trace optimization
|
||||
WITH_BF_RAYOPTIMIZATION = True
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
|
||||
|
@@ -42,6 +42,8 @@ BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
BF_ICONV_LIB = 'iconv'
|
||||
BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
|
||||
|
||||
WITH_BF_AUDASPACE = True
|
||||
|
||||
WITH_BF_JACK = False
|
||||
BF_JACK = LIBDIR + '/jack'
|
||||
BF_JACK_INC = '${BF_JACK}/include ${BF_FFMPEG}/include/msvc'
|
||||
@@ -208,6 +210,12 @@ BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE']
|
||||
#Freestyle
|
||||
WITH_BF_FREESTYLE = True
|
||||
|
||||
WITH_BF_OPENSUBDIV = True
|
||||
BF_OPENSUBDIV = LIBDIR + '/opensubdiv'
|
||||
BF_OPENSUBDIV_INC = '${BF_OPENSUBDIV}/include'
|
||||
BF_OPENSUBDIV_LIB = 'osdCPU osdGPU'
|
||||
BF_OPENSUBDIV_LIBPATH = '${BF_OPENSUBDIV}/lib'
|
||||
|
||||
WITH_BF_STATICOPENGL = False
|
||||
BF_OPENGL_INC = '${BF_OPENGL}/include'
|
||||
BF_OPENGL_LIBINC = '${BF_OPENGL}/lib'
|
||||
|
@@ -22,6 +22,8 @@ BF_FFMPEG_LIBPATH = LIBDIR + '/ffmpeg/lib'
|
||||
BF_FFMPEG_INC = LIBDIR + '/ffmpeg/include'
|
||||
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll ${BF_FFMPEG_LIBPATH}/swresample-0.dll ${BF_FFMPEG_LIBPATH}/xvidcore.dll'
|
||||
|
||||
WITH_BF_AUDASPACE = True
|
||||
|
||||
WITH_BF_JACK = False
|
||||
BF_JACK = LIBDIR + '/jack'
|
||||
BF_JACK_INC = '${BF_JACK}/include'
|
||||
@@ -144,7 +146,7 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
|
||||
WITH_BF_CYCLES = True
|
||||
WITH_BF_CYCLES_CUDA_BINARIES = False
|
||||
BF_CYCLES_CUDA_NVCC = "" # Path to the NVIDIA CUDA compiler
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50', 'sm_52']
|
||||
|
||||
WITH_BF_OIIO = True
|
||||
BF_OIIO = LIBDIR + '/openimageio'
|
||||
@@ -165,6 +167,12 @@ BF_BOOST_LIB = 'boost_date_time-mgw47-mt-s-1_49 boost_date_time-mgw47-mt-sd-1_49
|
||||
BF_BOOST_LIB_INTERNATIONAL = ' boost_locale-mgw47-mt-s-1_49 boost_locale-mgw47-mt-sd-1_49'
|
||||
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
|
||||
|
||||
WITH_BF_OPENSUBDIV = False
|
||||
BF_OPENSUBDIV = LIBDIR + '/opensubdiv'
|
||||
BF_OPENSUBDIV_INC = '${BF_OPENSUBDIV}/include'
|
||||
BF_OPENSUBDIV_LIB = 'osdCPU osdGPU'
|
||||
BF_OPENSUBDIV_LIBPATH = '${BF_OPENSUBDIV}/lib'
|
||||
|
||||
#Ray trace optimization
|
||||
WITH_BF_RAYOPTIMIZATION = True
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-mmmx', '-msse', '-msse2']
|
||||
|
@@ -55,6 +55,8 @@ BF_SDL_INC = '${BF_SDL}/include'
|
||||
BF_SDL_LIB = 'SDL2.lib'
|
||||
BF_SDL_LIBPATH = '${BF_SDL}/lib'
|
||||
|
||||
WITH_BF_AUDASPACE = True
|
||||
|
||||
WITH_BF_JACK = False
|
||||
|
||||
BF_PTHREADS = LIBDIR + '/pthreads'
|
||||
@@ -212,6 +214,12 @@ BF_RAYOPTIMIZATION_SSE_FLAGS = ['']
|
||||
#Freestyle
|
||||
WITH_BF_FREESTYLE = True
|
||||
|
||||
WITH_BF_OPENSUBDIV = True
|
||||
BF_OPENSUBDIV = LIBDIR + '/opensubdiv'
|
||||
BF_OPENSUBDIV_INC = '${BF_OPENSUBDIV}/include'
|
||||
BF_OPENSUBDIV_LIB = 'osdCPU osdGPU'
|
||||
BF_OPENSUBDIV_LIBPATH = '${BF_OPENSUBDIV}/lib'
|
||||
|
||||
WITH_BF_STATICOPENGL = False
|
||||
BF_OPENGL_INC = '${BF_OPENGL}/include'
|
||||
BF_OPENGL_LIBINC = '${BF_OPENGL}/lib'
|
||||
|
@@ -242,6 +242,11 @@ def setup_staticlibs(lenv):
|
||||
if lenv['WITH_BF_STATIC3DMOUSE']:
|
||||
statlibs += Split(lenv['BF_3DMOUSE_LIB_STATIC'])
|
||||
|
||||
if lenv['WITH_BF_OPENSUBDIV']:
|
||||
libincs += Split(lenv['BF_OPENSUBDIV_LIBPATH'])
|
||||
if lenv['WITH_BF_STATICOPENSUBDIV']:
|
||||
statlibs += Split(lenv['BF_OPENSUBDIV_LIB_STATIC'])
|
||||
|
||||
# setting this last so any overriding of manually libs could be handled
|
||||
if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross', 'win64-mingw'):
|
||||
# We must remove any previous items defining this path, for same reason stated above!
|
||||
@@ -344,6 +349,13 @@ def setup_syslibs(lenv):
|
||||
if not lenv['WITH_BF_STATICPNG']:
|
||||
syslibs += Split(lenv['BF_PNG_LIB'])
|
||||
|
||||
if lenv['WITH_BF_OPENSUBDIV']:
|
||||
if not lenv['WITH_BF_STATICOPENSUBDIV']:
|
||||
if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw', 'win64-mingw'):
|
||||
syslibs += [osdlib+'_d' for osdlib in Split(lenv['BF_OPENSUBDIV_LIB'])]
|
||||
else:
|
||||
syslibs += Split(lenv['BF_OPENSUBDIV_LIB'])
|
||||
|
||||
# Hack to pass OSD libraries to linker before extern_{clew,cuew}
|
||||
for syslib in create_blender_liblist(lenv, 'system'):
|
||||
syslibs.append(os.path.basename(syslib))
|
||||
@@ -764,7 +776,7 @@ def AppIt(target=None, source=None, env=None):
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/kernel/*.h %s/kernel/*.cl %s/kernel/*.cu %s/kernel/' % (croot, croot, croot, cinstalldir)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/kernel/svm %s/kernel/closure %s/kernel/geom %s/util/util_color.h %s/util/util_half.h %s/util/util_math.h %s/util/util_math_fast.h %s/util/util_transform.h %s/util/util_types.h %s/kernel/' % (croot, croot, croot, croot, croot, croot, croot, croot, croot, cinstalldir)
|
||||
cmd = 'cp -R %s/kernel/svm %s/kernel/closure %s/kernel/geom %s/kernel/split %s/kernel/kernels %s/util/util_color.h %s/util/util_half.h %s/util/util_math.h %s/util/util_math_fast.h %s/util/util_transform.h %s/util/util_types.h %s/util/util_atomic.h %s/kernel/' % (croot, croot, croot, croot, croot, croot, croot, croot, croot, croot, croot, croot, cinstalldir)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/../intern/cycles/kernel/*.cubin %s/lib/' % (builddir, cinstalldir)
|
||||
commands.getoutput(cmd)
|
||||
|
@@ -107,6 +107,7 @@ def print_arguments(args, bc):
|
||||
def validate_arguments(args, bc):
|
||||
opts_list = [
|
||||
'WITH_BF_FREESTYLE', 'WITH_BF_PYTHON', 'WITH_BF_PYTHON_SAFETY', 'WITH_BF_PYTHON_SECURITY', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'BF_PYTHON_LIBPATH_ARCH', 'WITH_BF_STATICPYTHON', 'WITH_OSX_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', 'BF_PYTHON_DLL', 'BF_PYTHON_ABI_FLAGS',
|
||||
'WITH_BF_AUDASPACE', 'BF_AUDASPACE_C_INC', 'BF_AUDASPACE_PY_INC', 'BF_AUDASPACE_DEF',
|
||||
'WITH_BF_OPENAL', 'BF_OPENAL', 'BF_OPENAL_INC', 'BF_OPENAL_LIB', 'BF_OPENAL_LIBPATH', 'WITH_BF_STATICOPENAL', 'BF_OPENAL_LIB_STATIC',
|
||||
'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH', 'WITH_BF_SDL_DYNLOAD',
|
||||
'WITH_BF_JACK', 'BF_JACK', 'BF_JACK_INC', 'BF_JACK_LIB', 'BF_JACK_LIBPATH', 'WITH_BF_JACK_DYNLOAD',
|
||||
@@ -182,7 +183,8 @@ def validate_arguments(args, bc):
|
||||
'WITH_BF_BOOST', 'WITH_BF_STATICBOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIB_INTERNATIONAL', 'BF_BOOST_LIB_STATIC', 'BF_BOOST_LIBPATH',
|
||||
'WITH_BF_LIBMV', 'WITH_BF_LIBMV_SCHUR_SPECIALIZATIONS',
|
||||
'WITH_BF_CYCLES_OSL', 'WITH_BF_STATICOSL', 'BF_OSL', 'BF_OSL_INC', 'BF_OSL_LIB', 'BF_OSL_LIBPATH', 'BF_OSL_LIB_STATIC', 'BF_OSL_COMPILER',
|
||||
'WITH_BF_LLVM', 'WITH_BF_STATICLLVM', 'BF_LLVM', 'BF_LLVM_LIB', 'BF_LLVM_LIBPATH', 'BF_LLVM_LIB_STATIC', 'BF_PROGRAM_LINKFLAGS'
|
||||
'WITH_BF_LLVM', 'WITH_BF_STATICLLVM', 'BF_LLVM', 'BF_LLVM_LIB', 'BF_LLVM_LIBPATH', 'BF_LLVM_LIB_STATIC', 'BF_PROGRAM_LINKFLAGS',
|
||||
'WITH_BF_OPENSUBDIV', 'WITH_BF_STATICOPENSUBDIV', 'BF_OPENSUBDIV', 'BF_OPENSUBDIV_INC', 'BF_OPENSUBDIV_LIB', 'BF_OPENSUBDIV_LIBPATH', 'BF_OPENSUBDIV_LIB_STATIC'
|
||||
]
|
||||
|
||||
# Have options here that scons expects to be lists
|
||||
@@ -297,6 +299,11 @@ def read_opts(env, cfg, args):
|
||||
('BF_OPENAL_LIBPATH', 'Path to OpenAL library', ''),
|
||||
(BoolVariable('WITH_BF_STATICOPENAL', 'Staticly link to openal', False)),
|
||||
|
||||
(BoolVariable('WITH_BF_AUDASPACE', 'Build with audaspace if true', True)),
|
||||
('BF_AUDASPACE_C_INC', 'audaspace-c include path', ''),
|
||||
('BF_AUDASPACE_PY_INC', 'audaspace-py include path', ''),
|
||||
('BF_AUDASPACE_DEF', 'audaspace defines', ''),
|
||||
|
||||
(BoolVariable('WITH_BF_SDL', 'Use SDL if true', False)),
|
||||
('BF_SDL', 'SDL base path', ''),
|
||||
('BF_SDL_INC', 'SDL include path', ''),
|
||||
@@ -656,6 +663,14 @@ def read_opts(env, cfg, args):
|
||||
|
||||
('BF_PROGRAM_LINKFLAGS', 'Link flags applied only to final binaries (blender and blenderplayer, not makesrna/makesdna)', ''),
|
||||
|
||||
(BoolVariable('WITH_BF_OPENSUBDIV', 'Build with OpenSubdiv library', False)),
|
||||
(BoolVariable('WITH_BF_STATICOPENSUBDIV', 'Staticly link to OpenColorIO', False)),
|
||||
('BF_OPENSUBDIV', 'OpenSubdiv root path', ''),
|
||||
('BF_OPENSUBDIV_INC', 'OpenSubdiv include path', ''),
|
||||
('BF_OPENSUBDIV_LIB', 'OpenSubdiv library', ''),
|
||||
('BF_OPENSUBDIV_LIBPATH', 'OpenSubdiv library path', ''),
|
||||
('BF_OPENSUBDIV_LIB_STATIC', 'OpenSubdiv static library', ''),
|
||||
|
||||
(BoolVariable('WITH_BF_CPP11', '"Build with C++11 standard enabled, for development use only!', False)),
|
||||
|
||||
(BoolVariable('WITH_BF_LEGACY_DEPSGRAPH', 'Build Blender with legacy dependency graph', True)),
|
||||
|
@@ -1,104 +0,0 @@
|
||||
|
||||
Blender CMake build system
|
||||
============================
|
||||
|
||||
Contents
|
||||
---------------
|
||||
|
||||
1. Introduction
|
||||
2. Obtaining CMake
|
||||
3. Building Blender
|
||||
4. Generic Setup
|
||||
5. Configuring the build after SVN updates
|
||||
|
||||
1. Introduction
|
||||
---------------
|
||||
|
||||
This document describes general usage of the new CMake scripts. The
|
||||
inner workings will be described in blender-cmake-dev.txt (TODO).
|
||||
|
||||
2. Obtaining CMake
|
||||
------------------
|
||||
|
||||
CMake for can either be downloaded using your favorite package manager
|
||||
or is also available from the CMake website at http://www.cmake.org
|
||||
The website also contains some documentation on CMake usage but I found
|
||||
the man page alone pretty helpful.
|
||||
|
||||
3. Building Blender
|
||||
-------------------
|
||||
|
||||
Building Blender requires obtaining a compiler, library dependencies,
|
||||
and correct setup depending on the system. For details on how to set
|
||||
up a build on various operating systems, see the wiki documentation:
|
||||
|
||||
http://wiki.blender.org/index.php/Dev:Doc/Building_Blender
|
||||
|
||||
4. Generic Setup
|
||||
----------------
|
||||
|
||||
CMake allows one to generate the build project files and binary objects
|
||||
outside the source tree which can be pretty handy in working and experimenting
|
||||
with different Blender configurations (Audio/NoAudio, GameEngine/NoGameEngine etc.)
|
||||
while maintaining a clean source tree. It also makes it possible to generate files
|
||||
for different build systems on the same source tree. This also has benefits for
|
||||
general SVN management for the developer as patches and submit logs are much cleaner.
|
||||
|
||||
Create a directory outside the blender source tree where you would like to build
|
||||
Blender (from now on called $BLENDERBUILD). On the commandline you can then run
|
||||
the cmake command to generate your initial build files. First just run 'cmake' which
|
||||
will inform you what the available generators are. Thn you can run
|
||||
'cmake -G generator $BLENDERSOURCE' to generate the build files. Here is an example
|
||||
of all this for Xcode:
|
||||
|
||||
% mkdir $BLENDERBUILD
|
||||
% cd $BLENDERBUILD
|
||||
% cmake
|
||||
|
||||
...
|
||||
...
|
||||
--version [file] = Show program name/version banner and exit.
|
||||
|
||||
Generators
|
||||
|
||||
The following generators are available on this platform:
|
||||
KDevelop3 = Generates KDevelop 3 project files.
|
||||
Unix Makefiles = Generates standard UNIX makefiles.
|
||||
Xcode = Generate XCode project files.
|
||||
|
||||
|
||||
|
||||
% cmake -G Xcode $BLENDERSOURCE
|
||||
...
|
||||
...
|
||||
-- Configuring blender
|
||||
-- Configuring blenderplayer
|
||||
-- Configuring done
|
||||
-- Generating done
|
||||
-- Build files have been written to: $BLENDERBUILD
|
||||
|
||||
This will generate the build files with default values. Specific features can
|
||||
be enabled or disabled by running the ccmake "GUI" from $BLENDERBUILD as follows:
|
||||
|
||||
% ccmake $BLENDERSOURCE
|
||||
|
||||
A number of options appear which can be changed depending on your needs and
|
||||
available dependencies (e.g. setting WITH_OPENEXR to OFF will disable support
|
||||
for OpenEXR). It will also allow you to override default and detected paths
|
||||
(e.g. Python directories) and compile and link flags. When you are satisfied
|
||||
used ccmake to re-configure the build files and exit.
|
||||
|
||||
It is also possible to use the commandline of 'cmake' to override certain
|
||||
of these settings.
|
||||
|
||||
5. Configuring the build after SVN updates
|
||||
------------------------------------------
|
||||
|
||||
The $BLENDERBUILD directory maintains a file called CMakeCache.txt which
|
||||
remembers the initial run's settings for subsequent generation runs. After
|
||||
SVN updates that contain changes to the build system, rebuilding Blender will
|
||||
automatically invoke CMake to regenerate the CMakeCache.txt and other files
|
||||
as needed.
|
||||
|
||||
/Jacques Beaurain (jbinto)
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* These pages document the source code of blender.
|
||||
*
|
||||
* \subsection implinks Important Links
|
||||
* - <a href="http://developer.blender.org">developer.blender.org</a> with bug tracker
|
||||
* - <a href="http://developer.blender.org">developer.blender.org</a> with bug tracker.
|
||||
* - <a href="http://wiki.blender.org/index.php/Dev:Contents">Development documents</a> on our wiki.
|
||||
*
|
||||
* \subsection blother Other
|
||||
|
@@ -11,7 +11,6 @@
|
||||
/** \defgroup bmesh BMesh
|
||||
* \ingroup blender
|
||||
*/
|
||||
/** \defgroup texture Texturing */
|
||||
/** \defgroup compositor Compositing */
|
||||
|
||||
/** \defgroup python Python
|
||||
@@ -322,7 +321,7 @@
|
||||
* \ingroup gui
|
||||
*/
|
||||
|
||||
/** \defgroup externformats external formats */
|
||||
/** \defgroup externformats External Formats */
|
||||
|
||||
/** \defgroup collada COLLADA
|
||||
* \ingroup externformats
|
||||
|
@@ -2,8 +2,8 @@
|
||||
Texture Replacement
|
||||
+++++++++++++++++++
|
||||
Example of how to replace a texture in game with an external image.
|
||||
createTexture() and removeTexture() are to be called from a module Python
|
||||
Controller.
|
||||
``createTexture()`` and ``removeTexture()`` are to be called from a
|
||||
module Python Controller.
|
||||
"""
|
||||
from bge import logic
|
||||
from bge import texture
|
||||
|
@@ -1,7 +1,8 @@
|
||||
"""
|
||||
Basic Video Playback
|
||||
++++++++++++++++++++
|
||||
Example of how to replace a texture in game with a video. It needs to run everyframe
|
||||
Example of how to replace a texture in game with a video. It needs to run
|
||||
everyframe.
|
||||
"""
|
||||
import bge
|
||||
from bge import texture
|
||||
|
@@ -31,7 +31,7 @@ class SimpleMouseOperator(bpy.types.Operator):
|
||||
y = bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
# rather then printing, use the report function,
|
||||
# rather than printing, use the report function,
|
||||
# this way the message appears in the header,
|
||||
self.report({'INFO'}, "Mouse coords are %d %d" % (self.x, self.y))
|
||||
return {'FINISHED'}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Note that when keying data paths which contain nested properties this must be
|
||||
done from the :class:`ID` subclass, in this case the :class:`Armature` rather
|
||||
then the bone.
|
||||
than the bone.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
47
doc/python_api/rst/bge.app.rst
Normal file
47
doc/python_api/rst/bge.app.rst
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
Application Data (bge.app)
|
||||
==========================
|
||||
|
||||
Module to access application values that remain unchanged during runtime.
|
||||
|
||||
.. module:: bge.app
|
||||
|
||||
.. data:: version
|
||||
|
||||
The Blender/BGE version as a tuple of 3 ints, eg. (2, 75, 1).
|
||||
|
||||
.. note:: Version tuples can be compared simply with (in)equality symbols;
|
||||
for example, ``(2, 74, 5) <= (2, 75, 0)`` returns True (lexical order).
|
||||
|
||||
:type: tuple of three ints
|
||||
|
||||
.. data:: version_string
|
||||
|
||||
The Blender/BGE version formatted as a string, eg. "2.75 (sub 1)".
|
||||
|
||||
:type: str
|
||||
|
||||
.. data:: version_char
|
||||
|
||||
The Blender/BGE version character (for minor releases).
|
||||
|
||||
:type: str
|
||||
|
||||
.. data:: has_texture_ffmpeg
|
||||
|
||||
True if the BGE has been built with FFmpeg support, enabling use of :class:`~bge.texture.ImageFFmpeg` and :class:`~bge.texture.VideoFFmpeg`.
|
||||
|
||||
:type: bool
|
||||
|
||||
.. data:: has_joystick
|
||||
|
||||
True if the BGE has been built with joystick support.
|
||||
|
||||
:type: bool
|
||||
|
||||
.. data:: has_physics
|
||||
|
||||
True if the BGE has been built with physics support.
|
||||
|
||||
:type: bool
|
||||
|
@@ -4,75 +4,77 @@ Physics Constraints (bge.constraints)
|
||||
|
||||
.. module:: bge.constraints
|
||||
|
||||
.. literalinclude:: ../examples/bge.constraints.py
|
||||
:language: rest
|
||||
:lines: 2-4
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. include:: ../examples/bge.constraints.py
|
||||
:start-line: 1
|
||||
:end-line: 4
|
||||
|
||||
.. literalinclude:: ../examples/bge.constraints.py
|
||||
:lines: 6-
|
||||
|
||||
.. function:: createConstraint(physicsid_1, physicsid_2, constraint_type, pivot_X, pivot_y, pivot_z, axis_x, axis_y, axis_z, flag)
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: createConstraint( \
|
||||
physicsid_1, physicsid_2, constraint_type, \
|
||||
pivot_x=0.0, pivot_y=0.0, pivot_z=0.0, \
|
||||
axis_x=0.0, axis_y=0.0, axis_z=0.0, flag=0)
|
||||
|
||||
Creates a constraint.
|
||||
|
||||
Constraints types:
|
||||
- :class:`POINTTOPOINT_CONSTRAINT`
|
||||
- :class:`LINEHINGE_CONSTRAINT`
|
||||
- :class:`ANGULAR_CONSTRAINT`
|
||||
- :class:`CONETWIST_CONSTRAINT`
|
||||
- :class:`VEHICLE_CONSTRAINT`
|
||||
- :class:`GENERIC_6DOF_CONSTRAINT`
|
||||
|
||||
:arg physicsid_1: the physics id of the first object in constraint.
|
||||
:arg physicsid_1: The physics id of the first object in constraint.
|
||||
:type physicsid_1: int
|
||||
|
||||
:arg physicsid_2: the physics id of the second object in constraint.
|
||||
:arg physicsid_2: The physics id of the second object in constraint.
|
||||
:type physicsid_2: int
|
||||
|
||||
:arg constrainttype: the type of the constraint.
|
||||
:type constrainttype: int
|
||||
:arg constraint_type: The type of the constraint, see `Create Constraint Constants`_.
|
||||
|
||||
:arg pivot_X: pivot X position (optional).
|
||||
:type pivot_X: float
|
||||
:type constraint_type: int
|
||||
|
||||
:arg pivot_Y: pivot Y position (optional).
|
||||
:type pivot_Y: float
|
||||
:arg pivot_x: Pivot X position. (optional)
|
||||
:type pivot_x: float
|
||||
|
||||
:arg pivot_Z: pivot Z position (optional).
|
||||
:type pivot_Z: float
|
||||
:arg pivot_y: Pivot Y position. (optional)
|
||||
:type pivot_y: float
|
||||
|
||||
:arg axis_X: X axis angle in degrees (optional).
|
||||
:type axis_X: float
|
||||
:arg pivot_z: Pivot Z position. (optional)
|
||||
:type pivot_z: float
|
||||
|
||||
:arg axis_Y: Y axis angle in degrees (optional).
|
||||
:type axis_Y: float
|
||||
:arg axis_x: X axis angle in degrees. (optional)
|
||||
:type axis_x: float
|
||||
|
||||
:arg axis_Z: Z axis angle in degrees (optional).
|
||||
:type axis_Z: float
|
||||
:arg axis_y: Y axis angle in degrees. (optional)
|
||||
:type axis_y: float
|
||||
|
||||
:arg flag: 128 to disable collision between linked bodies (optional).
|
||||
:arg axis_z: Z axis angle in degrees. (optional)
|
||||
:type axis_z: float
|
||||
|
||||
:arg flag: 128 to disable collision between linked bodies. (optional)
|
||||
:type flag: int
|
||||
|
||||
:return: a constraint wrapper.
|
||||
:rtype: :class:`bge.types.KX_ConstraintWrapper`
|
||||
|
||||
.. attribute:: error
|
||||
|
||||
Symbolic constant string that indicates error.
|
||||
:return: A constraint wrapper.
|
||||
:rtype: :class:`~bge.types.KX_ConstraintWrapper`
|
||||
|
||||
.. function:: exportBulletFile(filename)
|
||||
|
||||
export a .bullet file
|
||||
Exports a file representing the dynamics world (usually using ``.bullet`` extension).
|
||||
|
||||
:arg filename: File name
|
||||
:type filename: string
|
||||
See `Bullet binary serialization <http://bulletphysics.org/mediawiki-1.5.8/index.php/Bullet_binary_serialization>`__.
|
||||
|
||||
:arg filename: File path.
|
||||
:type filename: str
|
||||
|
||||
.. function:: getAppliedImpulse(constraintId)
|
||||
|
||||
:arg constraintId: The id of the constraint.
|
||||
:type constraintId: int
|
||||
|
||||
:return: the most recent applied impulse.
|
||||
:return: The most recent applied impulse.
|
||||
:rtype: float
|
||||
|
||||
.. function:: getVehicleConstraint(constraintId)
|
||||
@@ -80,16 +82,16 @@ Physics Constraints (bge.constraints)
|
||||
:arg constraintId: The id of the vehicle constraint.
|
||||
:type constraintId: int
|
||||
|
||||
:return: a vehicle constraint object.
|
||||
:rtype: :class:`bge.types.KX_VehicleWrapper`
|
||||
:return: A vehicle constraint object.
|
||||
:rtype: :class:`~bge.types.KX_VehicleWrapper`
|
||||
|
||||
.. function:: getCharacter(gameobj)
|
||||
|
||||
:arg gameobj: The game object with the character physics.
|
||||
:type gameobj: :class:`bge.types.KX_GameObject`
|
||||
:type gameobj: :class:`~bge.types.KX_GameObject`
|
||||
|
||||
:return: character wrapper
|
||||
:rtype: :class:`bge.types.KX_CharacterWrapper`
|
||||
:return: Character wrapper.
|
||||
:rtype: :class:`~bge.types.KX_CharacterWrapper`
|
||||
|
||||
.. function:: removeConstraint(constraintId)
|
||||
|
||||
@@ -143,23 +145,8 @@ Physics Constraints (bge.constraints)
|
||||
|
||||
Sets the debug mode.
|
||||
|
||||
Debug modes:
|
||||
- :class:`DBG_NODEBUG`
|
||||
- :class:`DBG_DRAWWIREFRAME`
|
||||
- :class:`DBG_DRAWAABB`
|
||||
- :class:`DBG_DRAWFREATURESTEXT`
|
||||
- :class:`DBG_DRAWCONTACTPOINTS`
|
||||
- :class:`DBG_NOHELPTEXT`
|
||||
- :class:`DBG_DRAWTEXT`
|
||||
- :class:`DBG_PROFILETIMINGS`
|
||||
- :class:`DBG_ENABLESATCOMPARISION`
|
||||
- :class:`DBG_DISABLEBULLETLCP`
|
||||
- :class:`DBG_ENABLECCD`
|
||||
- :class:`DBG_DRAWCONSTRAINTS`
|
||||
- :class:`DBG_DRAWCONSTRAINTLIMITS`
|
||||
- :class:`DBG_FASTWIREFRAME`
|
||||
:arg mode: The new debug mode, see `Debug Mode Constants`_.
|
||||
|
||||
:arg mode: The new debug mode.
|
||||
:type mode: int
|
||||
|
||||
.. function:: setGravity(x, y, z)
|
||||
@@ -178,7 +165,8 @@ Physics Constraints (bge.constraints)
|
||||
.. function:: setLinearAirDamping(damping)
|
||||
|
||||
.. note::
|
||||
Not implemented.
|
||||
|
||||
Not implemented
|
||||
|
||||
Sets the linear air damping for rigidbodies.
|
||||
|
||||
@@ -238,144 +226,111 @@ Physics Constraints (bge.constraints)
|
||||
|
||||
.. function:: setUseEpa(epa)
|
||||
|
||||
Not implemented.
|
||||
.. note::
|
||||
|
||||
Not implemented
|
||||
|
||||
|
||||
Constants
|
||||
+++++++++
|
||||
|
||||
.. attribute:: error
|
||||
|
||||
Symbolic constant string that indicates error.
|
||||
|
||||
:type: str
|
||||
|
||||
|
||||
Debug Mode Constants
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Debug mode to be used with :func:`setDebugMode`.
|
||||
|
||||
|
||||
.. data:: DBG_NODEBUG
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
No debug.
|
||||
|
||||
.. data:: DBG_DRAWWIREFRAME
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Draw wireframe in debug.
|
||||
|
||||
.. data:: DBG_DRAWAABB
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Draw Axis Aligned Bounding Box in debug.
|
||||
|
||||
.. data:: DBG_DRAWFREATURESTEXT
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Draw freatures text in debug.
|
||||
Draw features text in debug.
|
||||
|
||||
.. data:: DBG_DRAWCONTACTPOINTS
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Draw contact points in debug.
|
||||
|
||||
.. data:: DBG_NOHELPTEXT
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Debug without help text.
|
||||
|
||||
.. data:: DBG_DRAWTEXT
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Draw text in debug.
|
||||
|
||||
.. data:: DBG_PROFILETIMINGS
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Draw profile timings in debug.
|
||||
|
||||
.. data:: DBG_ENABLESATCOMPARISION
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Enable sat comparision in debug.
|
||||
|
||||
.. data:: DBG_DISABLEBULLETLCP
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Disable Bullet LCP.
|
||||
|
||||
.. data:: DBG_ENABLECCD
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Enable Continous Colision Detection in debug.
|
||||
Enable Continous Collision Detection in debug.
|
||||
|
||||
.. data:: DBG_DRAWCONSTRAINTS
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Draw constraints in debug.
|
||||
|
||||
.. data:: DBG_DRAWCONSTRAINTLIMITS
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Draw constraint limits in debug.
|
||||
|
||||
.. data:: DBG_FASTWIREFRAME
|
||||
|
||||
.. note::
|
||||
Debug mode to be used with function :class:`setDebugMode`
|
||||
|
||||
Draw a fast wireframe in debug.
|
||||
|
||||
.. data:: POINTTOPOINT_CONSTRAINT
|
||||
|
||||
.. note::
|
||||
Constraint type to be used with function :class:`createConstraint`
|
||||
Create Constraint Constants
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Constraint type to be used with :func:`createConstraint`.
|
||||
|
||||
|
||||
.. data:: POINTTOPOINT_CONSTRAINT
|
||||
|
||||
.. to do
|
||||
|
||||
.. data:: LINEHINGE_CONSTRAINT
|
||||
|
||||
.. note::
|
||||
Constraint type to be used with function :class:`createConstraint`
|
||||
|
||||
.. to do
|
||||
|
||||
.. data:: ANGULAR_CONSTRAINT
|
||||
|
||||
.. note::
|
||||
Constraint type to be used with function :class:`createConstraint`
|
||||
|
||||
.. to do
|
||||
|
||||
.. data:: CONETWIST_CONSTRAINT
|
||||
|
||||
.. note::
|
||||
Constraint type to be used with function :class:`createConstraint`
|
||||
|
||||
.. to do
|
||||
|
||||
.. data:: VEHICLE_CONSTRAINT
|
||||
|
||||
.. note::
|
||||
Constraint type to be used with function :class:`createConstraint`
|
||||
|
||||
.. to do
|
||||
|
||||
.. data:: GENERIC_6DOF_CONSTRAINT
|
||||
|
||||
.. note::
|
||||
Constraint type to be used with function :class:`createConstraint`
|
||||
|
||||
.. to do
|
||||
|
||||
|
@@ -894,6 +894,8 @@ Various
|
||||
2D Filter
|
||||
---------
|
||||
|
||||
.. _Two-D-FilterActuator-mode:
|
||||
|
||||
.. data:: RAS_2DFILTER_BLUR
|
||||
|
||||
:value: 2
|
||||
@@ -1288,5 +1290,3 @@ See :class:`bge.types.KX_StateActuator.operation`
|
||||
Add bits to state mask
|
||||
|
||||
:value: 3
|
||||
|
||||
.. _Two-D-FilterActuator-mode:
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -7,11 +7,66 @@ base class --- :class:`PyObjectPlus`
|
||||
|
||||
.. class:: KX_BlenderMaterial(PyObjectPlus)
|
||||
|
||||
KX_BlenderMaterial
|
||||
This is the interface to materials in the game engine.
|
||||
|
||||
Materials define the render state to be applied to mesh objects.
|
||||
|
||||
The example below shows a simple GLSL shader setup allowing to dynamically mix two texture channels
|
||||
in a material. All materials of the object executing this script should have two textures using
|
||||
separate UV maps in the two first texture channels.
|
||||
|
||||
The code works for both Multitexture and GLSL rendering modes.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from bge import logic
|
||||
|
||||
vertex_shader = """
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// simple projection of the vertex position to view space
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
// coordinate of the 1st texture channel
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
// coordinate of the 2nd texture channel
|
||||
gl_TexCoord[1] = gl_MultiTexCoord1;
|
||||
}
|
||||
"""
|
||||
|
||||
fragment_shader ="""
|
||||
|
||||
uniform sampler2D texture_0;
|
||||
uniform sampler2D texture_1;
|
||||
uniform float factor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 color_0 = texture2D(texture_0, gl_TexCoord[0].st);
|
||||
vec4 color_1 = texture2D(texture_1, gl_TexCoord[1].st);
|
||||
gl_FragColor = mix(color_0, color_1, factor);
|
||||
}
|
||||
"""
|
||||
|
||||
object = logic.getCurrentController().owner
|
||||
|
||||
for mesh in object.meshes:
|
||||
for material in mesh.materials:
|
||||
shader = material.getShader()
|
||||
if shader is not None:
|
||||
if not shader.isValid():
|
||||
shader.setSource(vertex_shader, fragment_shader, True)
|
||||
|
||||
# get the first texture channel of the material
|
||||
shader.setSampler('texture_0', 0)
|
||||
# get the second texture channel of the material
|
||||
shader.setSampler('texture_1', 1)
|
||||
# pass another uniform to the shader
|
||||
shader.setUniform1f('factor', 0.3)
|
||||
|
||||
.. attribute:: shader
|
||||
|
||||
The materials shader.
|
||||
The material's shader.
|
||||
|
||||
:type: :class:`BL_Shader`
|
||||
|
||||
@@ -34,39 +89,83 @@ base class --- :class:`PyObjectPlus`
|
||||
:return: the material's shader
|
||||
:rtype: :class:`BL_Shader`
|
||||
|
||||
.. attribute:: alpha
|
||||
|
||||
The material's alpha transparency.
|
||||
|
||||
:type: float between 0.0 and 1.0 inclusive
|
||||
|
||||
.. attribute:: hardness
|
||||
|
||||
How hard (sharp) the material's specular reflection is.
|
||||
|
||||
:type: integer between 1 and 511 inclusive
|
||||
|
||||
.. attribute:: emit
|
||||
|
||||
Amount of light to emit.
|
||||
|
||||
:type: float between 0.0 and 2.0 inclusive
|
||||
|
||||
.. attribute:: specularIntensity
|
||||
|
||||
How intense (bright) the material's specular reflection is.
|
||||
|
||||
:type: float between 0.0 and 1.0 inclusive
|
||||
|
||||
.. attribute:: diffuseIntensity
|
||||
|
||||
The material's amount of diffuse reflection.
|
||||
|
||||
:type: float between 0.0 and 1.0 inclusive
|
||||
|
||||
.. attribute:: specularColor
|
||||
|
||||
The material's specular color.
|
||||
|
||||
:type: :class:`mathutils.Color`
|
||||
|
||||
.. attribute:: diffuseColor
|
||||
|
||||
The material's diffuse color.
|
||||
|
||||
:type: :class:`mathutils.Color`
|
||||
|
||||
.. method:: setBlending(src, dest)
|
||||
|
||||
Set the pixel color arithmetic functions.
|
||||
|
||||
:arg src: Specifies how the red, green, blue, and alpha source blending factors are computed.
|
||||
:type src: Value in...
|
||||
:arg src: Specifies how the red, green, blue, and alpha source blending factors are computed, one of...
|
||||
|
||||
* :data:`~bgl.GL_ZERO`
|
||||
* :data:`~bgl.GL_ONE`
|
||||
* :data:`~bgl.GL_SRC_COLOR`
|
||||
* :data:`~bgl.GL_ONE_MINUS_SRC_COLOR`
|
||||
* :data:`~bgl.GL_DST_COLOR`
|
||||
* :data:`~bgl.GL_ONE_MINUS_DST_COLOR`
|
||||
* :data:`~bgl.GL_SRC_ALPHA`
|
||||
* :data:`~bgl.GL_ONE_MINUS_SRC_ALPHA`
|
||||
* :data:`~bgl.GL_DST_ALPHA`
|
||||
* :data:`~bgl.GL_ONE_MINUS_DST_ALPHA`
|
||||
* :data:`~bgl.GL_SRC_ALPHA_SATURATE`
|
||||
|
||||
:type src: int
|
||||
|
||||
* GL_ZERO,
|
||||
* GL_ONE,
|
||||
* GL_SRC_COLOR,
|
||||
* GL_ONE_MINUS_SRC_COLOR,
|
||||
* GL_DST_COLOR,
|
||||
* GL_ONE_MINUS_DST_COLOR,
|
||||
* GL_SRC_ALPHA,
|
||||
* GL_ONE_MINUS_SRC_ALPHA,
|
||||
* GL_DST_ALPHA,
|
||||
* GL_ONE_MINUS_DST_ALPHA,
|
||||
* GL_SRC_ALPHA_SATURATE
|
||||
|
||||
:arg dest: Specifies how the red, green, blue, and alpha destination blending factors are computed.
|
||||
:type dest: Value in...
|
||||
|
||||
* GL_ZERO
|
||||
* GL_ONE
|
||||
* GL_SRC_COLOR
|
||||
* GL_ONE_MINUS_SRC_COLOR
|
||||
* GL_DST_COLOR
|
||||
* GL_ONE_MINUS_DST_COLOR
|
||||
* GL_SRC_ALPHA
|
||||
* GL_ONE_MINUS_SRC_ALPHA
|
||||
* GL_DST_ALPHA
|
||||
* GL_ONE_MINUS_DST_ALPHA
|
||||
* GL_SRC_ALPHA_SATURATE
|
||||
:arg dest: Specifies how the red, green, blue, and alpha destination blending factors are computed, one of...
|
||||
|
||||
* :data:`~bgl.GL_ZERO`
|
||||
* :data:`~bgl.GL_ONE`
|
||||
* :data:`~bgl.GL_SRC_COLOR`
|
||||
* :data:`~bgl.GL_ONE_MINUS_SRC_COLOR`
|
||||
* :data:`~bgl.GL_DST_COLOR`
|
||||
* :data:`~bgl.GL_ONE_MINUS_DST_COLOR`
|
||||
* :data:`~bgl.GL_SRC_ALPHA`
|
||||
* :data:`~bgl.GL_ONE_MINUS_SRC_ALPHA`
|
||||
* :data:`~bgl.GL_DST_ALPHA`
|
||||
* :data:`~bgl.GL_ONE_MINUS_DST_ALPHA`
|
||||
* :data:`~bgl.GL_SRC_ALPHA_SATURATE`
|
||||
|
||||
:type dest: int
|
||||
|
||||
.. method:: getMaterialIndex()
|
||||
|
||||
|
@@ -51,6 +51,18 @@ base class --- :class:`KX_GameObject`
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: shift_x
|
||||
|
||||
The camera's horizontal shift.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: shift_y
|
||||
|
||||
The camera's vertical shift.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: perspective
|
||||
|
||||
True if this camera has a perspective transform, False for an orthographic projection.
|
||||
|
@@ -137,7 +137,30 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
.. note::
|
||||
|
||||
A value of 0.0 disables this option (rather then setting it stationary).
|
||||
A value of 0.0 disables this option (rather than setting it stationary).
|
||||
|
||||
.. attribute:: angularVelocityMin
|
||||
|
||||
Enforces the object keeps rotating at a minimum velocity. A value of 0.0 disables this.
|
||||
|
||||
:type: non-negative float
|
||||
|
||||
.. note::
|
||||
|
||||
Applies to dynamic and rigid body objects only.
|
||||
While objects are stationary the minimum velocity will not be applied.
|
||||
|
||||
|
||||
.. attribute:: angularVelocityMax
|
||||
|
||||
Clamp the maximum angular velocity to prevent objects rotating beyond a set speed.
|
||||
A value of 0.0 disables clamping; it does not stop rotation.
|
||||
|
||||
:type: non-negative float
|
||||
|
||||
.. note::
|
||||
|
||||
Applies to dynamic and rigid body objects only.
|
||||
|
||||
.. attribute:: localInertia
|
||||
|
||||
@@ -949,6 +972,16 @@ base class --- :class:`SCA_IObject`
|
||||
:return: The current frame of the action
|
||||
:rtype: float
|
||||
|
||||
.. method:: getActionName(layer=0)
|
||||
|
||||
Gets the name of the current action playing in the supplied layer.
|
||||
|
||||
:arg layer: The layer that you want to get the action name from.
|
||||
:type layer: integer
|
||||
|
||||
:return: The name of the current action
|
||||
:rtype: string
|
||||
|
||||
.. method:: setActionFrame(frame, layer=0)
|
||||
|
||||
Set the current frame of the action playing in the supplied layer.
|
||||
|
@@ -51,7 +51,7 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
.. attribute:: materials
|
||||
|
||||
:type: list of :class:`KX_BlenderMaterial` or :class:`KX_PolygonMaterial` types
|
||||
:type: list of :class:`KX_BlenderMaterial` type
|
||||
|
||||
.. attribute:: numPolygons
|
||||
|
||||
|
@@ -23,7 +23,7 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
The material of the polygon.
|
||||
|
||||
:type: :class:`KX_PolygonMaterial` or :class:`KX_BlenderMaterial`
|
||||
:type: :class:`KX_BlenderMaterial`
|
||||
|
||||
.. attribute:: texture_name
|
||||
|
||||
@@ -84,7 +84,7 @@ base class --- :class:`SCA_IObject`
|
||||
.. method:: getMaterial()
|
||||
|
||||
:return: The polygon material
|
||||
:rtype: :class:`KX_PolygonMaterial` or :class:`KX_BlenderMaterial`
|
||||
:rtype: :class:`KX_BlenderMaterial`
|
||||
|
||||
.. method:: getTextureName()
|
||||
|
||||
|
@@ -1,250 +0,0 @@
|
||||
KX_PolygonMaterial(PyObjectPlus)
|
||||
================================
|
||||
|
||||
.. module:: bge.types
|
||||
|
||||
base class --- :class:`PyObjectPlus`
|
||||
|
||||
.. class:: KX_PolygonMaterial(PyObjectPlus)
|
||||
|
||||
This is the interface to materials in the game engine.
|
||||
|
||||
Materials define the render state to be applied to mesh objects.
|
||||
|
||||
.. warning::
|
||||
|
||||
Some of the methods/variables are CObjects. If you mix these up, you will crash blender.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from bge import logic
|
||||
|
||||
vertex_shader = """
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// original vertex position, no changes
|
||||
gl_Position = ftransform();
|
||||
// coordinate of the 1st texture channel
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
// coordinate of the 2nd texture channel
|
||||
gl_TexCoord[1] = gl_MultiTexCoord1;
|
||||
}
|
||||
"""
|
||||
|
||||
fragment_shader ="""
|
||||
|
||||
uniform sampler2D color_0;
|
||||
uniform sampler2D color_1;
|
||||
uniform float factor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 color_0 = texture2D(color_0, gl_TexCoord[0].st);
|
||||
vec4 color_1 = texture2D(color_1, gl_TexCoord[1].st);
|
||||
gl_FragColor = mix(color_0, color_1, factor);
|
||||
}
|
||||
"""
|
||||
|
||||
object = logic.getCurrentController().owner
|
||||
object = cont.owner
|
||||
for mesh in object.meshes:
|
||||
for material in mesh.materials:
|
||||
shader = material.getShader()
|
||||
if shader != None:
|
||||
if not shader.isValid():
|
||||
shader.setSource(vertex_shader, fragment_shader, True)
|
||||
|
||||
# get the first texture channel of the material
|
||||
shader.setSampler('color_0', 0)
|
||||
# get the second texture channel of the material
|
||||
shader.setSampler('color_1', 1)
|
||||
# pass another uniform to the shader
|
||||
shader.setUniform1f('factor', 0.3)
|
||||
|
||||
|
||||
.. attribute:: texture
|
||||
|
||||
Texture name.
|
||||
|
||||
:type: string (read-only)
|
||||
|
||||
.. attribute:: gl_texture
|
||||
|
||||
OpenGL texture handle (eg for glBindTexture(GL_TEXTURE_2D, gl_texture).
|
||||
|
||||
:type: integer (read-only)
|
||||
|
||||
.. attribute:: material
|
||||
|
||||
Material name.
|
||||
|
||||
:type: string (read-only)
|
||||
|
||||
.. attribute:: tface
|
||||
|
||||
Texture face properties.
|
||||
|
||||
:type: CObject (read-only)
|
||||
|
||||
.. attribute:: tile
|
||||
|
||||
Texture is tiling.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: tilexrep
|
||||
|
||||
Number of tile repetitions in x direction.
|
||||
|
||||
:type: integer
|
||||
|
||||
.. attribute:: tileyrep
|
||||
|
||||
Number of tile repetitions in y direction.
|
||||
|
||||
:type: integer
|
||||
|
||||
.. attribute:: drawingmode
|
||||
|
||||
Drawing mode for the material.
|
||||
- 2 (drawingmode & 4) Textured
|
||||
- 4 (drawingmode & 16) Light
|
||||
- 14 (drawingmode & 16384) 3d Polygon Text.
|
||||
|
||||
:type: bitfield
|
||||
|
||||
.. attribute:: transparent
|
||||
|
||||
This material is transparent. All meshes with this
|
||||
material will be rendered after non transparent meshes from back
|
||||
to front.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: zsort
|
||||
|
||||
Transparent polygons in meshes with this material will be sorted back to
|
||||
front before rendering.
|
||||
Non-Transparent polygons will be sorted front to back before rendering.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: diffuse
|
||||
|
||||
The diffuse color of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0].
|
||||
|
||||
:type: list [r, g, b]
|
||||
|
||||
.. attribute:: specular
|
||||
|
||||
The specular color of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0].
|
||||
|
||||
:type: list [r, g, b]
|
||||
|
||||
.. attribute:: shininess
|
||||
|
||||
The shininess (specular exponent) of the material. 0.0 <= shininess <= 128.0.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: specularity
|
||||
|
||||
The amount of specular of the material. 0.0 <= specularity <= 1.0.
|
||||
|
||||
:type: float
|
||||
|
||||
.. method:: updateTexture(tface, rasty)
|
||||
|
||||
Updates a realtime animation.
|
||||
|
||||
:arg tface: Texture face (eg mat.tface)
|
||||
:type tface: CObject
|
||||
:arg rasty: Rasterizer
|
||||
:type rasty: CObject
|
||||
|
||||
.. method:: setTexture(tface)
|
||||
|
||||
Sets texture render state.
|
||||
|
||||
:arg tface: Texture face
|
||||
:type tface: CObject
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
mat.setTexture(mat.tface)
|
||||
|
||||
.. method:: activate(rasty, cachingInfo)
|
||||
|
||||
Sets material parameters for this object for rendering.
|
||||
|
||||
Material Parameters set:
|
||||
|
||||
#. Texture
|
||||
#. Backface culling
|
||||
#. Line drawing
|
||||
#. Specular Colour
|
||||
#. Shininess
|
||||
#. Diffuse Colour
|
||||
#. Polygon Offset.
|
||||
|
||||
:arg rasty: Rasterizer instance.
|
||||
:type rasty: CObject
|
||||
:arg cachingInfo: Material cache instance.
|
||||
:type cachingInfo: CObject
|
||||
|
||||
.. method:: setCustomMaterial(material)
|
||||
|
||||
Sets the material state setup object.
|
||||
|
||||
Using this method, you can extend or completely replace the gameengine material
|
||||
to do your own advanced multipass effects.
|
||||
|
||||
Use this method to register your material class. Instead of the normal material,
|
||||
your class's activate method will be called just before rendering the mesh.
|
||||
This should setup the texture, material, and any other state you would like.
|
||||
It should return True to render the mesh, or False if you are finished. You should
|
||||
clean up any state Blender does not set before returning False.
|
||||
|
||||
Activate Method Definition:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def activate(self, rasty, cachingInfo, material):
|
||||
|
||||
:arg material: The material object.
|
||||
:type material: instance
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class PyMaterial:
|
||||
def __init__(self):
|
||||
self.pass_no = -1
|
||||
|
||||
def activate(self, rasty, cachingInfo, material):
|
||||
# Activate the material here.
|
||||
#
|
||||
# The activate method will be called until it returns False.
|
||||
# Every time the activate method returns True the mesh will
|
||||
# be rendered.
|
||||
#
|
||||
# rasty is a CObject for passing to material.updateTexture()
|
||||
# and material.activate()
|
||||
# cachingInfo is a CObject for passing to material.activate()
|
||||
# material is the KX_PolygonMaterial instance this material
|
||||
# was added to
|
||||
|
||||
# default material properties:
|
||||
self.pass_no += 1
|
||||
if self.pass_no == 0:
|
||||
material.activate(rasty, cachingInfo)
|
||||
# Return True to do this pass
|
||||
return True
|
||||
|
||||
# clean up and return False to finish.
|
||||
self.pass_no = -1
|
||||
return False
|
||||
|
||||
# Create a new Python Material and pass it to the renderer.
|
||||
mat.setCustomMaterial(PyMaterial())
|
||||
|
@@ -1,4 +1,4 @@
|
||||
KX_WordlInfo(PyObjectPlus)
|
||||
KX_WorldInfo(PyObjectPlus)
|
||||
=============================
|
||||
|
||||
.. module:: bge.types
|
||||
@@ -7,7 +7,7 @@ base class --- :class:`PyObjectPlus`
|
||||
|
||||
.. class:: KX_WorldInfo(PyObjectPlus)
|
||||
|
||||
A wolrd object.
|
||||
A world object.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@@ -7,7 +7,7 @@ base class --- :class:`SCA_IActuator`
|
||||
|
||||
.. class:: SCA_2DFilterActuator(SCA_IActuator)
|
||||
|
||||
Create, enable and disable 2D filters
|
||||
Create, enable and disable 2D filters.
|
||||
|
||||
The following properties don't have an immediate effect.
|
||||
You must active the actuator to get the result.
|
||||
@@ -29,7 +29,7 @@ base class --- :class:`SCA_IActuator`
|
||||
|
||||
.. attribute:: mode
|
||||
|
||||
Type of 2D filter, use one of :ref:`these constants <Two-D-FilterActuator-mode>`
|
||||
Type of 2D filter, use one of :ref:`these constants <Two-D-FilterActuator-mode>`.
|
||||
|
||||
:type: integer
|
||||
|
||||
|
@@ -121,7 +121,7 @@ Here are some more complex examples:
|
||||
bpy.context.scene.render.layers["RenderLayer"].samples
|
||||
|
||||
# access to the current weight paint brush size
|
||||
bpy.context.tool_settings.weight_paint.brush.size
|
||||
bpy.context.tool_settings.weight_paint.brush.size
|
||||
|
||||
# check if the window is fullscreen
|
||||
bpy.context.window.screen.show_fullscreen
|
||||
@@ -141,15 +141,16 @@ When starting out scripting you will often run into the problem where you're not
|
||||
|
||||
There are a few ways to do this.
|
||||
|
||||
- Use the Python console's auto-complete to inspect properties. *This can be hit-and-miss but has the advantage
|
||||
- Use the Python console's auto-complete to inspect properties.
|
||||
*This can be hit-and-miss but has the advantage
|
||||
that you can easily see the values of properties and assign them to interactively see the results.*
|
||||
|
||||
- Copy the Data-Path from the user interface. *Explained further in :ref:`Copy Data Path <info_data_path_copy>`*
|
||||
|
||||
- Using the documentation to follow references. *Explained further in :ref:`Indirect Data Access <info_data_path_indirect>`*
|
||||
- Copy the Data-Path from the user interface.
|
||||
*Explained further in :ref:`Copy Data Path <info_data_path_copy>`*
|
||||
- Using the documentation to follow references.
|
||||
*Explained further in :ref:`Indirect Data Access <info_data_path_indirect>`*
|
||||
|
||||
|
||||
.. _info_data_path_copy
|
||||
.. _info_data_path_copy:
|
||||
|
||||
Copy Data Path
|
||||
--------------
|
||||
@@ -172,7 +173,8 @@ you won't be doing collection look-ups on every access and typically you'll want
|
||||
then access each :class:`bpy.types.ID` instance by name.
|
||||
|
||||
|
||||
Type in the ID path into a Python console :mod:`bpy.context.active_object`. Include the trailing dot and don't hit "enter", yet.
|
||||
Type in the ID path into a Python console :mod:`bpy.context.active_object`.
|
||||
Include the trailing dot and don't hit "enter", yet.
|
||||
|
||||
Now right-click on the button and select **Copy Data Path**, then paste the result into the console.
|
||||
|
||||
@@ -191,7 +193,7 @@ Hit "enter" and you'll get the current value of 1. Now try changing the value to
|
||||
You can see the value update in the Subdivision-Surface modifier's UI as well as the cube.
|
||||
|
||||
|
||||
.. _info_data_path_indirect
|
||||
.. _info_data_path_indirect:
|
||||
|
||||
Indirect Data Access
|
||||
--------------------
|
||||
@@ -201,32 +203,24 @@ For this example we'll go over something more involved, showing the steps to acc
|
||||
Lets say we want to access the texture of a brush via Python, to adjust its ``contrast`` for example.
|
||||
|
||||
- Start in the default scene and enable 'Sculpt' mode from the 3D-View header.
|
||||
|
||||
- From the toolbar expand the **Texture** panel and add a new texture.
|
||||
|
||||
*Notice the texture button its self doesn't have very useful links (you can check the tool-tips).*
|
||||
|
||||
- The contrast setting isn't exposed in the sculpt toolbar, so view the texture in the properties panel...
|
||||
|
||||
- In the properties button select the Texture context.
|
||||
|
||||
- Select the Brush icon to show the brush texture.
|
||||
|
||||
- Expand the **Colors** panel to locate the **Contrast** button.
|
||||
|
||||
- Right click on the contrast button and select **Online Python Reference** This takes you to ``bpy.types.Texture.contrast``
|
||||
|
||||
- Now we can see that ``contrast`` is a property of texture, so next we'll check on how to access the texture from the brush.
|
||||
|
||||
- Expand the *Colors* panel to locate the *Contrast* button.
|
||||
- Right click on the contrast button and select **Online Python Reference**
|
||||
This takes you to ``bpy.types.Texture.contrast``
|
||||
- Now we can see that ``contrast`` is a property of texture,
|
||||
so next we'll check on how to access the texture from the brush.
|
||||
- Check on the **References** at the bottom of the page, sometimes there are many references, and it may take
|
||||
some guess work to find the right one, but in this case its obviously ``Brush.texture``.
|
||||
|
||||
*Now we know that the texture can be accessed from* ``bpy.data.brushes["BrushName"].texture``
|
||||
*but normally you won't want to access the brush by name, so we'll see now to access the active brush instead.*
|
||||
|
||||
- So the next step is to check on where brushes are accessed from via the **References**.
|
||||
In this case there is simply ``bpy.context.brush`` which is all we need.
|
||||
|
||||
|
||||
Now you can use the Python console to form the nested properties needed to access brush textures contrast,
|
||||
logically we now know.
|
||||
@@ -282,7 +276,8 @@ are interested to check on the source code.
|
||||
|
||||
.. note::
|
||||
|
||||
Not all operators can be called usefully from Python, for more on this see :ref:`using operators <using_operators>`.
|
||||
Not all operators can be called usefully from Python,
|
||||
for more on this see :ref:`using operators <using_operators>`.
|
||||
|
||||
|
||||
Info View
|
||||
@@ -294,7 +289,8 @@ This is located above the file-menu which can be dragged down to display its con
|
||||
Select the **Script** screen that comes default with Blender to see its output.
|
||||
You can perform some actions and see them show up - delete a vertex for example.
|
||||
|
||||
Each entry can be selected (Right-Mouse-Button), then copied :kbd:`Control-C`, usually to paste in the text editor or python console.
|
||||
Each entry can be selected (Right-Mouse-Button),
|
||||
then copied :kbd:`Control-C`, usually to paste in the text editor or python console.
|
||||
|
||||
.. note::
|
||||
|
||||
|
@@ -1,16 +1,20 @@
|
||||
|
||||
*************
|
||||
Best Practice
|
||||
*************
|
||||
|
||||
When writing your own scripts python is great for new developers to pick up and become productive, but you can also pick up odd habits or at least write scripts that are not easy for others to understand.
|
||||
When writing your own scripts python is great for new developers to pick up and become productive,
|
||||
but you can also pick up odd habits or at least write scripts that are not easy for others to understand.
|
||||
|
||||
For your own work this is of course fine, but if you want to collaborate with others or have your work included with blender there are practices we encourage.
|
||||
For your own work this is of course fine,
|
||||
but if you want to collaborate with others or have your work included with blender there are practices we encourage.
|
||||
|
||||
|
||||
Style Conventions
|
||||
=================
|
||||
|
||||
For Blender/Python development we have chosen to follow python suggested style guide to avoid mixing styles amongst our own scripts and make it easier to use python scripts from other projects.
|
||||
For Blender/Python development we have chosen to follow python suggested style guide to avoid mixing styles
|
||||
amongst our own scripts and make it easier to use python scripts from other projects.
|
||||
|
||||
Using our style guide for your own scripts makes it easier if you eventually want to contribute them to blender.
|
||||
|
||||
@@ -18,22 +22,17 @@ This style guide is known as pep8 and can be found `here <http://www.python.org/
|
||||
|
||||
A brief listing of pep8 criteria.
|
||||
|
||||
* camel caps for class names: MyClass
|
||||
|
||||
* all lower case underscore separated module names: my_module
|
||||
|
||||
* indentation of 4 spaces (no tabs)
|
||||
|
||||
* spaces around operators. ``1 + 1``, not ``1+1``
|
||||
|
||||
* only use explicit imports, (no importing '*')
|
||||
|
||||
* don't use single line: ``if val: body``, separate onto 2 lines instead.
|
||||
- camel caps for class names: MyClass
|
||||
- all lower case underscore separated module names: my_module
|
||||
- indentation of 4 spaces (no tabs)
|
||||
- spaces around operators. ``1 + 1``, not ``1+1``
|
||||
- only use explicit imports, (no importing ``*``)
|
||||
- don't use single line: ``if val: body``, separate onto 2 lines instead.
|
||||
|
||||
|
||||
As well as pep8 we have other conventions used for blender python scripts.
|
||||
|
||||
* Use single quotes for enums, and double quotes for strings.
|
||||
- Use single quotes for enums, and double quotes for strings.
|
||||
|
||||
Both are of course strings but in our internal API enums are unique items from a limited set. eg.
|
||||
|
||||
@@ -42,9 +41,11 @@ As well as pep8 we have other conventions used for blender python scripts.
|
||||
bpy.context.scene.render.image_settings.file_format = 'PNG'
|
||||
bpy.context.scene.render.filepath = "//render_out"
|
||||
|
||||
* pep8 also defines that lines should not exceed 79 characters, we felt this is too restrictive so this is optional per script.
|
||||
- pep8 also defines that lines should not exceed 79 characters,
|
||||
we felt this is too restrictive so this is optional per script.
|
||||
|
||||
Periodically we run checks for pep8 compliance on blender scripts, for scripts to be included in this check add this line as a comment at the top of the script.
|
||||
Periodically we run checks for pep8 compliance on blender scripts,
|
||||
for scripts to be included in this check add this line as a comment at the top of the script.
|
||||
|
||||
``# <pep8 compliant>``
|
||||
|
||||
@@ -58,72 +59,75 @@ User Interface Layout
|
||||
|
||||
Some notes to keep in mind when writing UI layouts:
|
||||
|
||||
* UI code is quite simple. Layout declarations are there to easily create a decent layout.
|
||||
- UI code is quite simple. Layout declarations are there to easily create a decent layout.
|
||||
|
||||
General rule here: If you need more code for the layout declaration,
|
||||
then for the actual properties, you do it wrong.
|
||||
|
||||
General rule here: If you need more code for the layout declaration, then for the actual properties, you do it wrong.
|
||||
|
||||
Example layouts:
|
||||
|
||||
* layout()
|
||||
- layout()
|
||||
|
||||
The basic layout is a simple Top -> Bottom layout.
|
||||
|
||||
The basic layout is a simple Top -> Bottom layout.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
layout.prop()
|
||||
layout.prop()
|
||||
layout.prop()
|
||||
layout.prop()
|
||||
|
||||
* layout.row()
|
||||
- layout.row()
|
||||
|
||||
Use row(), when you want more than 1 property in one line.
|
||||
|
||||
Use row(), when you want more than 1 property in one line.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
row = layout.row()
|
||||
row.prop()
|
||||
row.prop()
|
||||
|
||||
* layout.column()
|
||||
row = layout.row()
|
||||
row.prop()
|
||||
row.prop()
|
||||
|
||||
- layout.column()
|
||||
|
||||
Use column(), when you want your properties in a column.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
col = layout.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
* layout.split()
|
||||
col = layout.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
This can be used to create more complex layouts. For example you can split the layout and create two column() layouts next to each other.
|
||||
- layout.split()
|
||||
|
||||
This can be used to create more complex layouts.
|
||||
For example you can split the layout and create two column() layouts next to each other.
|
||||
Don't use split, when you simply want two properties in a row. Use row() for that.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
Declaration names:
|
||||
|
||||
Try to only use these variable names for layout declarations:
|
||||
|
||||
* row for a row() layout
|
||||
* col for a column() layout
|
||||
* split for a split() layout
|
||||
* flow for a column_flow() layout
|
||||
* sub for a sub layout (a column inside a column for example)
|
||||
- row for a row() layout
|
||||
- col for a column() layout
|
||||
- split for a split() layout
|
||||
- flow for a column_flow() layout
|
||||
- sub for a sub layout (a column inside a column for example)
|
||||
|
||||
|
||||
Script Efficiency
|
||||
=================
|
||||
|
||||
|
||||
List Manipulation (General Python Tips)
|
||||
---------------------------------------
|
||||
|
||||
@@ -133,7 +137,8 @@ Searching for list items
|
||||
|
||||
In Python there are some handy list functions that save you having to search through the list.
|
||||
|
||||
Even though you're not looping on the list data **python is**, so you need to be aware of functions that will slow down your script by searching the whole list.
|
||||
Even though you're not looping on the list data **python is**,
|
||||
so you need to be aware of functions that will slow down your script by searching the whole list.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -145,11 +150,16 @@ Even though you're not looping on the list data **python is**, so you need to be
|
||||
|
||||
Modifying Lists
|
||||
^^^^^^^^^^^^^^^
|
||||
In python we can add and remove from a list, this is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
|
||||
In python we can add and remove from a list, this is slower when the list length is modified,
|
||||
especially at the start of the list, since all the data after the index of
|
||||
modification needs to be moved up or down 1 place.
|
||||
|
||||
The most simple way to add onto the end of the list is to use ``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to remove an item is ``my_list.pop()`` or ``del my_list[-1]``.
|
||||
The most simple way to add onto the end of the list is to use
|
||||
``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to
|
||||
remove an item is ``my_list.pop()`` or ``del my_list[-1]``.
|
||||
|
||||
To use an index you can use ``my_list.insert(index, list_item)`` or ``list.pop(index)`` for list removal, but these are slower.
|
||||
To use an index you can use ``my_list.insert(index, list_item)`` or ``list.pop(index)``
|
||||
for list removal, but these are slower.
|
||||
|
||||
Sometimes its faster (but more memory hungry) to just rebuild the list.
|
||||
|
||||
@@ -193,7 +203,8 @@ Use...
|
||||
my_list.extend([a, b, c...])
|
||||
|
||||
|
||||
Note that insert can be used when needed, but it is slower than append especially when inserting at the start of a long list.
|
||||
Note that insert can be used when needed,
|
||||
but it is slower than append especially when inserting at the start of a long list.
|
||||
|
||||
This example shows a very sub-optimal way of making a reversed list.
|
||||
|
||||
@@ -205,7 +216,8 @@ This example shows a very sub-optimal way of making a reversed list.
|
||||
reverse_list.insert(0, list_item)
|
||||
|
||||
|
||||
Python provides more convenient ways to reverse a list using the slice method, but you may want to time this before relying on it too much:
|
||||
Python provides more convenient ways to reverse a list using the slice method,
|
||||
but you may want to time this before relying on it too much:
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
@@ -220,7 +232,8 @@ Use ``my_list.pop(index)`` rather than ``my_list.remove(list_item)``
|
||||
|
||||
This requires you to have the index of the list item but is faster since ``remove()`` will search the list.
|
||||
|
||||
Here is an example of how to remove items in 1 loop, removing the last items first, which is faster (as explained above).
|
||||
Here is an example of how to remove items in 1 loop,
|
||||
removing the last items first, which is faster (as explained above).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -232,7 +245,9 @@ Here is an example of how to remove items in 1 loop, removing the last items fir
|
||||
my_list.pop(list_index)
|
||||
|
||||
|
||||
This example shows a fast way of removing items, for use in cases where you can alter the list order without breaking the scripts functionality. This works by swapping 2 list items, so the item you remove is always last.
|
||||
This example shows a fast way of removing items,
|
||||
for use in cases where you can alter the list order without breaking the scripts functionality.
|
||||
This works by swapping 2 list items, so the item you remove is always last.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -251,7 +266,9 @@ When removing many items in a large list this can provide a good speedup.
|
||||
Avoid Copying Lists
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When passing a list/dictionary to a function, it is faster to have the function modify the list rather than returning a new list so python doesn't have to duplicate the list in memory.
|
||||
When passing a list/dictionary to a function,
|
||||
it is faster to have the function modify the list rather than returning
|
||||
a new list so python doesn't have to duplicate the list in memory.
|
||||
|
||||
Functions that modify a list in-place are more efficient than functions that create new lists.
|
||||
|
||||
@@ -296,20 +313,26 @@ Python’s string joining function. To join a list of strings
|
||||
>>> file.write(" ".join([str1, str2, str3, "\n"]))
|
||||
|
||||
|
||||
join is fastest on many strings, `string formatting <http://docs.python.org/py3k/library/string.html#string-formatting>`_ is quite fast too (better for converting data types). String arithmetic is slowest.
|
||||
join is fastest on many strings,
|
||||
`string formatting <http://docs.python.org/py3k/library/string.html#string-formatting>`__
|
||||
is quite fast too (better for converting data types). String arithmetic is slowest.
|
||||
|
||||
|
||||
Parsing Strings (Import/Exporting)
|
||||
----------------------------------
|
||||
|
||||
Since many file formats are ASCII, the way you parse/export strings can make a large difference in how fast your script runs.
|
||||
Since many file formats are ASCII,
|
||||
the way you parse/export strings can make a large difference in how fast your script runs.
|
||||
|
||||
There are a few ways to parse strings when importing them into Blender.
|
||||
|
||||
|
||||
Parsing Numbers
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``, float() will work for an int too but it's faster to read ints with int().
|
||||
Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``,
|
||||
float() will work for an int too but it's faster to read ints with int().
|
||||
|
||||
|
||||
Checking String Start/End
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -322,7 +345,8 @@ Use...
|
||||
|
||||
>>> if line.startswith("vert "):
|
||||
|
||||
Using ``startswith()`` is slightly faster (approx 5%) and also avoids a possible error with the slice length not matching the string length.
|
||||
Using ``startswith()`` is slightly faster (approx 5%) and also avoids a possible
|
||||
error with the slice length not matching the string length.
|
||||
|
||||
my_string.endswith("foo_bar") can be used for line endings too.
|
||||
|
||||
@@ -336,15 +360,19 @@ Use try/except Sparingly
|
||||
|
||||
The **try** statement is useful to save time writing error checking code.
|
||||
|
||||
However **try** is significantly slower than an **if** since an exception has to be set each time, so avoid using **try** in areas of your code that execute in a loop and runs many times.
|
||||
However **try** is significantly slower than an **if** since an exception has to be set each time,
|
||||
so avoid using **try** in areas of your code that execute in a loop and runs many times.
|
||||
|
||||
There are cases where using **try** is faster than checking whether the condition will raise an error, so it is worth experimenting.
|
||||
There are cases where using **try** is faster than checking whether the condition will raise an error,
|
||||
so it is worth experimenting.
|
||||
|
||||
|
||||
Value Comparison
|
||||
----------------
|
||||
|
||||
Python has two ways to compare values ``a == b`` and ``a is b``, the difference is that ``==`` may run the objects comparison function ``__cmp__()`` whereas ``is`` compares identity, that both variables reference the same item in memory.
|
||||
Python has two ways to compare values ``a == b`` and ``a is b``,
|
||||
the difference is that ``==`` may run the objects comparison function ``__cmp__()`` whereas ``is`` compares identity,
|
||||
that both variables reference the same item in memory.
|
||||
|
||||
In cases where you know you are checking for the same value which is referenced from multiple places, ``is`` is faster.
|
||||
|
||||
@@ -362,3 +390,4 @@ While developing a script it's good to time it to be aware of any changes in per
|
||||
# do something...
|
||||
|
||||
print("My Script Finished: %.4f sec" % time.time() - time_start)
|
||||
|
||||
|
@@ -2,7 +2,8 @@
|
||||
Gotchas
|
||||
*******
|
||||
|
||||
This document attempts to help you work with the Blender API in areas that can be troublesome and avoid practices that are known to give instability.
|
||||
This document attempts to help you work with the Blender API in areas
|
||||
that can be troublesome and avoid practices that are known to give instability.
|
||||
|
||||
|
||||
.. _using_operators:
|
||||
@@ -10,16 +11,15 @@ This document attempts to help you work with the Blender API in areas that can b
|
||||
Using Operators
|
||||
===============
|
||||
|
||||
Blender's operators are tools for users to access, that python can access them too is very useful nevertheless operators have limitations that can make them cumbersome to script.
|
||||
Blender's operators are tools for users to access, that Python can access them too is very useful
|
||||
nevertheless operators have limitations that can make them cumbersome to script.
|
||||
|
||||
Main limits are...
|
||||
|
||||
* Can't pass data such as objects, meshes or materials to operate on (operators use the context instead)
|
||||
|
||||
* The return value from calling an operator gives the success (if it finished or was canceled),
|
||||
- Can't pass data such as objects, meshes or materials to operate on (operators use the context instead)
|
||||
- The return value from calling an operator gives the success (if it finished or was canceled),
|
||||
in some cases it would be more logical from an API perspective to return the result of the operation.
|
||||
|
||||
* Operators poll function can fail where an API function would raise an exception giving details on exactly why.
|
||||
- Operators poll function can fail where an API function would raise an exception giving details on exactly why.
|
||||
|
||||
|
||||
Why does an operator's poll fail?
|
||||
@@ -32,20 +32,28 @@ When calling an operator gives an error like this:
|
||||
|
||||
Which raises the question as to what the correct context might be?
|
||||
|
||||
Typically operators check for the active area type, a selection or active object they can operate on, but some operators are more picky about when they run.
|
||||
Typically operators check for the active area type, a selection or active object they can operate on,
|
||||
but some operators are more picky about when they run.
|
||||
|
||||
In most cases you can figure out what context an operator needs simply be seeing how it's used in Blender and thinking about what it does.
|
||||
In most cases you can figure out what context an operator needs
|
||||
simply be seeing how it's used in Blender and thinking about what it does.
|
||||
|
||||
|
||||
Unfortunately if you're still stuck - the only way to **really** know whats going on is to read the source code for the poll function and see what its checking.
|
||||
Unfortunately if you're still stuck - the only way to **really** know
|
||||
whats going on is to read the source code for the poll function and see what its checking.
|
||||
|
||||
For python operators it's not so hard to find the source since it's included with Blender and the source file/line is included in the operator reference docs.
|
||||
For Python operators it's not so hard to find the source
|
||||
since it's included with Blender and the source file/line is included in the operator reference docs.
|
||||
|
||||
Downloading and searching the C code isn't so simple, especially if you're not familiar with the C language but by searching the operator name or description you should be able to find the poll function with no knowledge of C.
|
||||
Downloading and searching the C code isn't so simple,
|
||||
especially if you're not familiar with the C language but by searching the
|
||||
operator name or description you should be able to find the poll function with no knowledge of C.
|
||||
|
||||
.. note::
|
||||
|
||||
Blender does have the functionality for poll functions to describe why they fail, but its currently not used much, if you're interested to help improve our API feel free to add calls to ``CTX_wm_operator_poll_msg_set`` where its not obvious why poll fails.
|
||||
Blender does have the functionality for poll functions to describe why they fail,
|
||||
but its currently not used much, if you're interested to help improve our API
|
||||
feel free to add calls to ``CTX_wm_operator_poll_msg_set`` where its not obvious why poll fails.
|
||||
|
||||
>>> bpy.ops.gpencil.draw()
|
||||
RuntimeError: Operator bpy.ops.gpencil.draw.poll() Failed to find Grease Pencil data to draw into
|
||||
@@ -54,36 +62,45 @@ Downloading and searching the C code isn't so simple, especially if you're not f
|
||||
The operator still doesn't work!
|
||||
--------------------------------
|
||||
|
||||
Certain operators in Blender are only intended for use in a specific context, some operators for example are only called from the properties window where they check the current material, modifier or constraint.
|
||||
Certain operators in Blender are only intended for use in a specific context,
|
||||
some operators for example are only called from the properties window where they check the current material,
|
||||
modifier or constraint.
|
||||
|
||||
Examples of this are:
|
||||
|
||||
* :mod:`bpy.ops.texture.slot_move`
|
||||
* :mod:`bpy.ops.constraint.limitdistance_reset`
|
||||
* :mod:`bpy.ops.object.modifier_copy`
|
||||
* :mod:`bpy.ops.buttons.file_browse`
|
||||
- :mod:`bpy.ops.texture.slot_move`
|
||||
- :mod:`bpy.ops.constraint.limitdistance_reset`
|
||||
- :mod:`bpy.ops.object.modifier_copy`
|
||||
- :mod:`bpy.ops.buttons.file_browse`
|
||||
|
||||
Another possibility is that you are the first person to attempt to use this operator in a script and some modifications need to be made to the operator to run in a different context, if the operator should logically be able to run but fails when accessed from a script it should be reported to the bug tracker.
|
||||
Another possibility is that you are the first person to attempt to use this operator
|
||||
in a script and some modifications need to be made to the operator to run in a different context,
|
||||
if the operator should logically be able to run but fails when accessed from a script
|
||||
it should be reported to the bug tracker.
|
||||
|
||||
|
||||
Stale Data
|
||||
==========
|
||||
|
||||
|
||||
No updates after setting values
|
||||
-------------------------------
|
||||
|
||||
Sometimes you want to modify values from python and immediately access the updated values, eg:
|
||||
Sometimes you want to modify values from Python and immediately access the updated values, eg:
|
||||
|
||||
Once changing the objects :class:`bpy.types.Object.location` you may want to access its transformation right after from :class:`bpy.types.Object.matrix_world`, but this doesn't work as you might expect.
|
||||
Once changing the objects :class:`bpy.types.Object.location`
|
||||
you may want to access its transformation right after from :class:`bpy.types.Object.matrix_world`,
|
||||
but this doesn't work as you might expect.
|
||||
|
||||
Consider the calculations that might go into working out the object's final transformation, this includes:
|
||||
|
||||
* animation function curves.
|
||||
* drivers and their pythons expressions.
|
||||
* constraints
|
||||
* parent objects and all of their f-curves, constraints etc.
|
||||
- animation function curves.
|
||||
- drivers and their Python expressions.
|
||||
- constraints
|
||||
- parent objects and all of their f-curves, constraints etc.
|
||||
|
||||
To avoid expensive recalculations every time a property is modified, Blender defers making the actual calculations until they are needed.
|
||||
To avoid expensive recalculations every time a property is modified,
|
||||
Blender defers making the actual calculations until they are needed.
|
||||
|
||||
However, while the script runs you may want to access the updated values.
|
||||
In this case you need to call :class:`bpy.types.Scene.update` after modifying values, for example:
|
||||
@@ -94,7 +111,9 @@ In this case you need to call :class:`bpy.types.Scene.update` after modifying va
|
||||
bpy.context.scene.update()
|
||||
|
||||
|
||||
Now all dependent data (child objects, modifiers, drivers... etc) has been recalculated and is available to the script.
|
||||
Now all dependent data (child objects, modifiers, drivers... etc)
|
||||
has been recalculated and is available to the script.
|
||||
|
||||
|
||||
Can I redraw during the script?
|
||||
-------------------------------
|
||||
@@ -103,23 +122,33 @@ The official answer to this is no, or... *"You don't want to do that"*.
|
||||
|
||||
To give some background on the topic...
|
||||
|
||||
While a script executes Blender waits for it to finish and is effectively locked until its done, while in this state Blender won't redraw or respond to user input.
|
||||
Normally this is not such a problem because scripts distributed with Blender tend not to run for an extended period of time, nevertheless scripts *can* take ages to execute and its nice to see whats going on in the view port.
|
||||
While a script executes Blender waits for it to finish and is effectively locked until its done,
|
||||
while in this state Blender won't redraw or respond to user input.
|
||||
Normally this is not such a problem because scripts distributed with Blender
|
||||
tend not to run for an extended period of time,
|
||||
nevertheless scripts *can* take ages to execute and its nice to see whats going on in the view port.
|
||||
|
||||
Tools that lock Blender in a loop and redraw are highly discouraged since they conflict with Blenders ability to run multiple operators at once and update different parts of the interface as the tool runs.
|
||||
Tools that lock Blender in a loop and redraw are highly discouraged
|
||||
since they conflict with Blenders ability to run multiple operators
|
||||
at once and update different parts of the interface as the tool runs.
|
||||
|
||||
So the solution here is to write a **modal** operator, that is - an operator which defines a modal() function, See the modal operator template in the text editor.
|
||||
So the solution here is to write a **modal** operator, that is - an operator which defines a modal() function,
|
||||
See the modal operator template in the text editor.
|
||||
|
||||
Modal operators execute on user input or setup their own timers to run frequently, they can handle the events or pass through to be handled by the keymap or other modal operators.
|
||||
Modal operators execute on user input or setup their own timers to run frequently,
|
||||
they can handle the events or pass through to be handled by the keymap or other modal operators.
|
||||
|
||||
Transform, Painting, Fly-Mode and File-Select are example of a modal operators.
|
||||
|
||||
Writing modal operators takes more effort than a simple ``for`` loop that happens to redraw but is more flexible and integrates better with Blenders design.
|
||||
Writing modal operators takes more effort than a simple ``for`` loop
|
||||
that happens to redraw but is more flexible and integrates better with Blenders design.
|
||||
|
||||
|
||||
**Ok, Ok! I still want to draw from python**
|
||||
**Ok, Ok! I still want to draw from Python**
|
||||
|
||||
If you insist - yes its possible, but scripts that use this hack wont be considered for inclusion in Blender and any issues with using it wont be considered bugs, this is also not guaranteed to work in future releases.
|
||||
If you insist - yes its possible, but scripts that use this hack wont be considered
|
||||
for inclusion in Blender and any issues with using it wont be considered bugs,
|
||||
this is also not guaranteed to work in future releases.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -129,16 +158,18 @@ If you insist - yes its possible, but scripts that use this hack wont be conside
|
||||
Modes and Mesh Access
|
||||
=====================
|
||||
|
||||
When working with mesh data you may run into the problem where a script fails to run as expected in edit-mode. This is caused by edit-mode having its own data which is only written back to the mesh when exiting edit-mode.
|
||||
When working with mesh data you may run into the problem where a script fails to run as expected in edit-mode.
|
||||
This is caused by edit-mode having its own data which is only written back to the mesh when exiting edit-mode.
|
||||
|
||||
A common example is that exporters may access a mesh through ``obj.data`` (a :class:`bpy.types.Mesh`) but the user is in edit-mode, where the mesh data is available but out of sync with the edit mesh.
|
||||
A common example is that exporters may access a mesh through ``obj.data`` (a :class:`bpy.types.Mesh`)
|
||||
but the user is in edit-mode, where the mesh data is available but out of sync with the edit mesh.
|
||||
|
||||
In this situation you can...
|
||||
|
||||
* Exit edit-mode before running the tool.
|
||||
* Explicitly update the mesh by calling :class:`bmesh.types.BMesh.to_mesh`.
|
||||
* Modify the script to support working on the edit-mode data directly, see: :mod:`bmesh.from_edit_mesh`.
|
||||
* Report the context as incorrect and only allow the script to run outside edit-mode.
|
||||
- Exit edit-mode before running the tool.
|
||||
- Explicitly update the mesh by calling :class:`bmesh.types.BMesh.to_mesh`.
|
||||
- Modify the script to support working on the edit-mode data directly, see: :mod:`bmesh.from_edit_mesh`.
|
||||
- Report the context as incorrect and only allow the script to run outside edit-mode.
|
||||
|
||||
|
||||
.. _info_gotcha_mesh_faces:
|
||||
@@ -146,35 +177,55 @@ In this situation you can...
|
||||
NGons and Tessellation Faces
|
||||
============================
|
||||
|
||||
Since 2.63 NGons are supported, this adds some complexity since in some cases you need to access triangles/quads still (some exporters for example).
|
||||
Since 2.63 NGons are supported, this adds some complexity
|
||||
since in some cases you need to access triangles/quads still (some exporters for example).
|
||||
|
||||
There are now 3 ways to access faces:
|
||||
|
||||
* :class:`bpy.types.MeshPolygon` - this is the data structure which now stores faces in object mode (access as ``mesh.polygons`` rather then ``mesh.faces``).
|
||||
* :class:`bpy.types.MeshTessFace` - the result of triangulating (tessellated) polygons, the main method of face access in 2.62 or older (access as ``mesh.tessfaces``).
|
||||
* :class:`bmesh.types.BMFace` - the polygons as used in editmode.
|
||||
- :class:`bpy.types.MeshPolygon` -
|
||||
this is the data structure which now stores faces in object mode
|
||||
(access as ``mesh.polygons`` rather than ``mesh.faces``).
|
||||
- :class:`bpy.types.MeshTessFace` -
|
||||
the result of triangulating (tessellated) polygons,
|
||||
the main method of face access in 2.62 or older (access as ``mesh.tessfaces``).
|
||||
- :class:`bmesh.types.BMFace` -
|
||||
the polygons as used in editmode.
|
||||
|
||||
For the purpose of the following documentation, these will be referred to as polygons, tessfaces and bmesh-faces respectively.
|
||||
For the purpose of the following documentation,
|
||||
these will be referred to as polygons, tessfaces and bmesh-faces respectively.
|
||||
|
||||
5+ sided faces will be referred to as ``ngons``.
|
||||
|
||||
|
||||
Support Overview
|
||||
----------------
|
||||
|
||||
+--------------+------------------------------+--------------------------------+--------------------------------+
|
||||
|Usage |:class:`bpy.types.MeshPolygon`|:class:`bpy.types.MeshTessFace` |:class:`bmesh.types.BMFace` |
|
||||
+==============+==============================+================================+================================+
|
||||
|Import/Create |Bad (inflexible) |Fine (supported as upgrade path)|Best |
|
||||
+--------------+------------------------------+--------------------------------+--------------------------------+
|
||||
|Manipulate |Bad (inflexible) |Bad (loses ngons) |Best |
|
||||
+--------------+------------------------------+--------------------------------+--------------------------------+
|
||||
|Export/Output |Good (ngons) |Good (When ngons can't be used) |Good (ngons, memory overhead) |
|
||||
+--------------+------------------------------+--------------------------------+--------------------------------+
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 1
|
||||
|
||||
* - Usage
|
||||
- :class:`bpy.types.MeshPolygon`
|
||||
- :class:`bpy.types.MeshTessFace`
|
||||
- :class:`bmesh.types.BMFace`
|
||||
* - Import/Create
|
||||
- Poor *(inflexible)*
|
||||
- Good *(supported as upgrade path)*
|
||||
- Best
|
||||
* - Manipulate
|
||||
- Poor *(inflexible)*
|
||||
- Poor *(loses ngons)*
|
||||
- Best
|
||||
* - Export/Output
|
||||
- Good *(ngon support)*
|
||||
- Good *(When ngons can't be used)*
|
||||
- Good *(ngons, extra memory overhead)*
|
||||
|
||||
.. note::
|
||||
|
||||
Using the :mod:`bmesh` api is completely separate api from :mod:`bpy`, typically you would would use one or the other based on the level of editing needed, not simply for a different way to access faces.
|
||||
Using the :mod:`bmesh` api is completely separate api from :mod:`bpy`,
|
||||
typically you would would use one or the other based on the level of editing needed,
|
||||
not simply for a different way to access faces.
|
||||
|
||||
|
||||
Creating
|
||||
@@ -182,9 +233,18 @@ Creating
|
||||
|
||||
All 3 datatypes can be used for face creation.
|
||||
|
||||
* polygons are the most efficient way to create faces but the data structure is _very_ rigid and inflexible, you must have all your vertes and faces ready and create them all at once. This is further complicated by the fact that each polygon does not store its own verts (as with tessfaces), rather they reference an index and size in :class:`bpy.types.Mesh.loops` which are a fixed array too.
|
||||
* tessfaces ideally should not be used for creating faces since they are really only tessellation cache of polygons, however for scripts upgrading from 2.62 this is by far the most straightforward option. This works by creating tessfaces and when finished - they can be converted into polygons by calling :class:`bpy.types.Mesh.update`. The obvious limitation is ngons can't be created this way.
|
||||
* bmesh-faces are most likely the easiest way for new scripts to create faces, since faces can be added one by one and the api has features intended for mesh manipulation. While :class:`bmesh.types.BMesh` uses more memory it can be managed by only operating on one mesh at a time.
|
||||
- polygons are the most efficient way to create faces but the data structure is _very_ rigid and inflexible,
|
||||
you must have all your vertes and faces ready and create them all at once.
|
||||
This is further complicated by the fact that each polygon does not store its own verts (as with tessfaces),
|
||||
rather they reference an index and size in :class:`bpy.types.Mesh.loops` which are a fixed array too.
|
||||
- tessfaces ideally should not be used for creating faces since they are really only tessellation cache of polygons,
|
||||
however for scripts upgrading from 2.62 this is by far the most straightforward option.
|
||||
This works by creating tessfaces and when finished -
|
||||
they can be converted into polygons by calling :class:`bpy.types.Mesh.update`.
|
||||
The obvious limitation is ngons can't be created this way.
|
||||
- bmesh-faces are most likely the easiest way for new scripts to create faces,
|
||||
since faces can be added one by one and the api has features intended for mesh manipulation.
|
||||
While :class:`bmesh.types.BMesh` uses more memory it can be managed by only operating on one mesh at a time.
|
||||
|
||||
|
||||
Editing
|
||||
@@ -192,18 +252,24 @@ Editing
|
||||
|
||||
Editing is where the 3 data types vary most.
|
||||
|
||||
* polygons are very limited for editing, changing materials and options like smooth works but for anything else they are too inflexible and are only intended for storage.
|
||||
* tessfaces should not be used for editing geometry because doing so will cause existing ngons to be tessellated.
|
||||
* bmesh-faces are by far the best way to manipulate geometry.
|
||||
- Polygons are very limited for editing,
|
||||
changing materials and options like smooth works but for anything else
|
||||
they are too inflexible and are only intended for storage.
|
||||
- Tessfaces should not be used for editing geometry because doing so will cause existing ngons to be tessellated.
|
||||
- BMesh-Faces are by far the best way to manipulate geometry.
|
||||
|
||||
|
||||
Exporting
|
||||
---------
|
||||
|
||||
All 3 data types can be used for exporting, the choice mostly depends on whether the target format supports ngons or not.
|
||||
All 3 data types can be used for exporting,
|
||||
the choice mostly depends on whether the target format supports ngons or not.
|
||||
|
||||
* polygons are the most direct & efficient way to export providing they convert into the output format easily enough.
|
||||
* tessfaces work well for exporting to formats which dont support ngons, in fact this is the only place where their use is encouraged.
|
||||
* bmesh-faces can work for exporting too but may not be necessary if polygons can be used since using bmesh gives some overhead because its not the native storage format in object mode.
|
||||
- Polygons are the most direct & efficient way to export providing they convert into the output format easily enough.
|
||||
- Tessfaces work well for exporting to formats which dont support ngons,
|
||||
in fact this is the only place where their use is encouraged.
|
||||
- BMesh-Faces can work for exporting too but may not be necessary if polygons can be used
|
||||
since using bmesh gives some overhead because its not the native storage format in object mode.
|
||||
|
||||
|
||||
Upgrading Importers from 2.62
|
||||
@@ -213,9 +279,9 @@ Importers can be upgraded to work with only minor changes.
|
||||
|
||||
The main change to be made is used the tessellation versions of each attribute.
|
||||
|
||||
* mesh.faces --> :class:`bpy.types.Mesh.tessfaces`
|
||||
* mesh.uv_textures --> :class:`bpy.types.Mesh.tessface_uv_textures`
|
||||
* mesh.vertex_colors --> :class:`bpy.types.Mesh.tessface_vertex_colors`
|
||||
- mesh.faces --> :class:`bpy.types.Mesh.tessfaces`
|
||||
- mesh.uv_textures --> :class:`bpy.types.Mesh.tessface_uv_textures`
|
||||
- mesh.vertex_colors --> :class:`bpy.types.Mesh.tessface_vertex_colors`
|
||||
|
||||
Once the data is created call :class:`bpy.types.Mesh.update` to convert the tessfaces into polygons.
|
||||
|
||||
@@ -223,7 +289,9 @@ Once the data is created call :class:`bpy.types.Mesh.update` to convert the tess
|
||||
Upgrading Exporters from 2.62
|
||||
-----------------------------
|
||||
|
||||
For exporters the most direct way to upgrade is to use tessfaces as with importing however its important to know that tessfaces may **not** exist for a mesh, the array will be empty as if there are no faces.
|
||||
For exporters the most direct way to upgrade is to use tessfaces as with importing
|
||||
however its important to know that tessfaces may **not** exist for a mesh,
|
||||
the array will be empty as if there are no faces.
|
||||
|
||||
So before accessing tessface data call: :class:`bpy.types.Mesh.update` ``(calc_tessface=True)``.
|
||||
|
||||
@@ -231,7 +299,8 @@ So before accessing tessface data call: :class:`bpy.types.Mesh.update` ``(calc_t
|
||||
EditBones, PoseBones, Bone... Bones
|
||||
===================================
|
||||
|
||||
Armature Bones in Blender have three distinct data structures that contain them. If you are accessing the bones through one of them, you may not have access to the properties you really need.
|
||||
Armature Bones in Blender have three distinct data structures that contain them.
|
||||
If you are accessing the bones through one of them, you may not have access to the properties you really need.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -241,7 +310,9 @@ Armature Bones in Blender have three distinct data structures that contain them.
|
||||
Edit Bones
|
||||
----------
|
||||
|
||||
``bpy.context.object.data.edit_bones`` contains a editbones; to access them you must set the armature mode to edit mode first (editbones do not exist in object or pose mode). Use these to create new bones, set their head/tail or roll, change their parenting relationships to other bones, etc.
|
||||
``bpy.context.object.data.edit_bones`` contains a editbones;
|
||||
to access them you must set the armature mode to edit mode first (editbones do not exist in object or pose mode).
|
||||
Use these to create new bones, set their head/tail or roll, change their parenting relationships to other bones, etc.
|
||||
|
||||
Example using :class:`bpy.types.EditBone` in armature editmode:
|
||||
|
||||
@@ -261,7 +332,9 @@ Returns an editbone only in edit mode.
|
||||
Bones (Object Mode)
|
||||
-------------------
|
||||
|
||||
``bpy.context.object.data.bones`` contains bones. These *live* in object mode, and have various properties you can change, note that the head and tail properties are read-only.
|
||||
``bpy.context.object.data.bones`` contains bones.
|
||||
These *live* in object mode, and have various properties you can change,
|
||||
note that the head and tail properties are read-only.
|
||||
|
||||
Example using :class:`bpy.types.Bone` in object or pose mode:
|
||||
|
||||
@@ -281,7 +354,9 @@ Accessible but read-only
|
||||
Pose Bones
|
||||
----------
|
||||
|
||||
``bpy.context.object.pose.bones`` contains pose bones. This is where animation data resides, i.e. animatable transformations are applied to pose bones, as are constraints and ik-settings.
|
||||
``bpy.context.object.pose.bones`` contains pose bones.
|
||||
This is where animation data resides, i.e. animatable transformations
|
||||
are applied to pose bones, as are constraints and ik-settings.
|
||||
|
||||
Examples using :class:`bpy.types.PoseBone` in object or pose mode:
|
||||
|
||||
@@ -296,19 +371,27 @@ Examples using :class:`bpy.types.PoseBone` in object or pose mode:
|
||||
|
||||
.. note::
|
||||
|
||||
Notice the pose is accessed from the object rather than the object data, this is why blender can have 2 or more objects sharing the same armature in different poses.
|
||||
Notice the pose is accessed from the object rather than the object data,
|
||||
this is why blender can have 2 or more objects sharing the same armature in different poses.
|
||||
|
||||
.. note::
|
||||
|
||||
Strictly speaking PoseBone's are not bones, they are just the state of the armature, stored in the :class:`bpy.types.Object` rather than the :class:`bpy.types.Armature`, the real bones are however accessible from the pose bones - :class:`bpy.types.PoseBone.bone`
|
||||
Strictly speaking PoseBone's are not bones, they are just the state of the armature,
|
||||
stored in the :class:`bpy.types.Object` rather than the :class:`bpy.types.Armature`,
|
||||
the real bones are however accessible from the pose bones - :class:`bpy.types.PoseBone.bone`
|
||||
|
||||
|
||||
Armature Mode Switching
|
||||
-----------------------
|
||||
|
||||
While writing scripts that deal with armatures you may find you have to switch between modes, when doing so take care when switching out of editmode not to keep references to the edit-bones or their head/tail vectors. Further access to these will crash blender so its important the script clearly separates sections of the code which operate in different modes.
|
||||
While writing scripts that deal with armatures you may find you have to switch between modes,
|
||||
when doing so take care when switching out of edit-mode not to keep references
|
||||
to the edit-bones or their head/tail vectors.
|
||||
Further access to these will crash blender so its important the script
|
||||
clearly separates sections of the code which operate in different modes.
|
||||
|
||||
This is mainly an issue with editmode since pose data can be manipulated without having to be in pose mode, however for operator access you may still need to enter pose mode.
|
||||
This is mainly an issue with editmode since pose data can be manipulated without having to be in pose mode,
|
||||
however for operator access you may still need to enter pose mode.
|
||||
|
||||
|
||||
Data Names
|
||||
@@ -343,10 +426,13 @@ Or with name assignment...
|
||||
Data names may not match the assigned values if they exceed the maximum length, are already used or an empty string.
|
||||
|
||||
|
||||
Its better practice not to reference objects by names at all, once created you can store the data in a list, dictionary, on a class etc, there is rarely a reason to have to keep searching for the same data by name.
|
||||
Its better practice not to reference objects by names at all,
|
||||
once created you can store the data in a list, dictionary, on a class etc,
|
||||
there is rarely a reason to have to keep searching for the same data by name.
|
||||
|
||||
|
||||
If you do need to use name references, its best to use a dictionary to maintain a mapping between the names of the imported assets and the newly created data, this way you don't run this risk of referencing existing data from the blend file, or worse modifying it.
|
||||
If you do need to use name references, its best to use a dictionary to maintain
|
||||
a mapping between the names of the imported assets and the newly created data,
|
||||
this way you don't run this risk of referencing existing data from the blend file, or worse modifying it.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -358,18 +444,22 @@ If you do need to use name references, its best to use a dictionary to maintain
|
||||
|
||||
# normally some code, or function calls...
|
||||
|
||||
# use own dictionary rather then bpy.data
|
||||
# use own dictionary rather than bpy.data
|
||||
mesh = mesh_name_mapping[meshid]
|
||||
|
||||
|
||||
Library Collisions
|
||||
------------------
|
||||
|
||||
Blender keeps data names unique - :class:`bpy.types.ID.name` so you can't name two objects, meshes, scenes etc the same thing by accident.
|
||||
Blender keeps data names unique - :class:`bpy.types.ID.name` so you can't name two objects,
|
||||
meshes, scenes etc the same thing by accident.
|
||||
|
||||
However when linking in library data from another blend file naming collisions can occur, so its best to avoid referencing data by name at all.
|
||||
However when linking in library data from another blend file naming collisions can occur,
|
||||
so its best to avoid referencing data by name at all.
|
||||
|
||||
This can be tricky at times and not even blender handles this correctly in some case (when selecting the modifier object for eg you can't select between multiple objects with the same name), but its still good to try avoid problems in this area.
|
||||
This can be tricky at times and not even blender handles this correctly in some case
|
||||
(when selecting the modifier object for eg you can't select between multiple objects with the same name),
|
||||
but its still good to try avoid problems in this area.
|
||||
|
||||
|
||||
If you need to select between local and library data, there is a feature in ``bpy.data`` members to allow for this.
|
||||
@@ -394,21 +484,23 @@ If you need to select between local and library data, there is a feature in ``bp
|
||||
Relative File Paths
|
||||
===================
|
||||
|
||||
Blenders relative file paths are not compatible with standard python modules such as ``sys`` and ``os``.
|
||||
Blenders relative file paths are not compatible with standard Python modules such as ``sys`` and ``os``.
|
||||
|
||||
Built in python functions don't understand blenders ``//`` prefix which denotes the blend file path.
|
||||
Built in Python functions don't understand blenders ``//`` prefix which denotes the blend file path.
|
||||
|
||||
A common case where you would run into this problem is when exporting a material with associated image paths.
|
||||
|
||||
>>> bpy.path.abspath(image.filepath)
|
||||
>>> bpy.path.abspath(image.filepath)
|
||||
|
||||
|
||||
When using blender data from linked libraries there is an unfortunate complication since the path will be relative to the library rather then the open blend file. When the data block may be from an external blend file pass the library argument from the :class:`bpy.types.ID`.
|
||||
When using blender data from linked libraries there is an unfortunate complication
|
||||
since the path will be relative to the library rather than the open blend file.
|
||||
When the data block may be from an external blend file pass the library argument from the :class:`bpy.types.ID`.
|
||||
|
||||
>>> bpy.path.abspath(image.filepath, library=image.library)
|
||||
>>> bpy.path.abspath(image.filepath, library=image.library)
|
||||
|
||||
|
||||
These returns the absolute path which can be used with native python modules.
|
||||
These returns the absolute path which can be used with native Python modules.
|
||||
|
||||
|
||||
Unicode Problems
|
||||
@@ -449,23 +541,28 @@ Here are 2 ways around filesystem encoding issues:
|
||||
>>> bpy.context.object.name = filepath_utf8
|
||||
|
||||
|
||||
Unicode encoding/decoding is a big topic with comprehensive python documentation, to avoid getting stuck too deep in encoding problems - here are some suggestions:
|
||||
Unicode encoding/decoding is a big topic with comprehensive Python documentation,
|
||||
to avoid getting stuck too deep in encoding problems - here are some suggestions:
|
||||
|
||||
* Always use utf-8 encoiding or convert to utf-8 where the input is unknown.
|
||||
- Always use utf-8 encoding or convert to utf-8 where the input is unknown.
|
||||
- Avoid manipulating filepaths as strings directly, use ``os.path`` functions instead.
|
||||
- Use ``os.fsencode()`` / ``os.fsdecode()`` instead of built in string decoding functions when operating on paths.
|
||||
- To print paths or to include them in the user interface use ``repr(path)`` first
|
||||
or ``"%r" % path`` with string formatting.
|
||||
|
||||
* Avoid manipulating filepaths as strings directly, use ``os.path`` functions instead.
|
||||
.. note::
|
||||
|
||||
* Use ``os.fsencode()`` / ``os.fsdecode()`` rather then the built in string decoding functions when operating on paths.
|
||||
|
||||
* To print paths or to include them in the user interface use ``repr(path)`` first or ``"%r" % path`` with string formatting.
|
||||
|
||||
* **Possibly** - use bytes instead of python strings, when reading some input its less trouble to read it as binary data though you will still need to decide how to treat any strings you want to use with Blender, some importers do this.
|
||||
Sometimes it's preferrable to avoid string encoding issues by using bytes instead of Python strings,
|
||||
when reading some input its less trouble to read it as binary data
|
||||
though you will still need to decide how to treat any strings you want to use with Blender,
|
||||
some importers do this.
|
||||
|
||||
|
||||
Strange errors using 'threading' module
|
||||
=======================================
|
||||
|
||||
Python threading with Blender only works properly when the threads finish up before the script does. By using ``threading.join()`` for example.
|
||||
Python threading with Blender only works properly when the threads finish up before the script does.
|
||||
By using ``threading.join()`` for example.
|
||||
|
||||
Heres an example of threading supported by Blender:
|
||||
|
||||
@@ -504,7 +601,8 @@ Heres an example of threading supported by Blender:
|
||||
t.join()
|
||||
|
||||
|
||||
This an example of a timer which runs many times a second and moves the default cube continuously while Blender runs **(Unsupported)**.
|
||||
This an example of a timer which runs many times a second and moves
|
||||
the default cube continuously while Blender runs **(Unsupported)**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -521,38 +619,48 @@ This an example of a timer which runs many times a second and moves the default
|
||||
|
||||
my_timer()
|
||||
|
||||
Use cases like the one above which leave the thread running once the script finishes may seem to work for a while but end up causing random crashes or errors in Blender's own drawing code.
|
||||
Use cases like the one above which leave the thread running once the script finishes
|
||||
may seem to work for a while but end up causing random crashes or errors in Blender's own drawing code.
|
||||
|
||||
So far, no work has gone into making Blender's python integration thread safe, so until its properly supported, best not make use of this.
|
||||
So far, no work has gone into making Blender's Python integration thread safe,
|
||||
so until its properly supported, best not make use of this.
|
||||
|
||||
.. note::
|
||||
|
||||
Pythons threads only allow co-currency and won't speed up your scripts on multi-processor systems, the ``subprocess`` and ``multiprocess`` modules can be used with Blender and make use of multiple CPU's too.
|
||||
Pythons threads only allow co-currency and won't speed up your scripts on multi-processor systems,
|
||||
the ``subprocess`` and ``multiprocess`` modules can be used with Blender and make use of multiple CPU's too.
|
||||
|
||||
|
||||
Help! My script crashes Blender
|
||||
===============================
|
||||
|
||||
Ideally it would be impossible to crash Blender from python however there are some problems with the API where it can be made to crash.
|
||||
Ideally it would be impossible to crash Blender from Python
|
||||
however there are some problems with the API where it can be made to crash.
|
||||
|
||||
Strictly speaking this is a bug in the API but fixing it would mean adding memory verification on every access since most crashes are caused by the python objects referencing Blenders memory directly, whenever the memory is freed, further python access to it can crash the script. But fixing this would make the scripts run very slow, or writing a very different kind of API which doesn't reference the memory directly.
|
||||
Strictly speaking this is a bug in the API but fixing it would mean adding memory verification
|
||||
on every access since most crashes are caused by the Python objects referencing Blenders memory directly,
|
||||
whenever the memory is freed, further Python access to it can crash the script.
|
||||
But fixing this would make the scripts run very slow,
|
||||
or writing a very different kind of API which doesn't reference the memory directly.
|
||||
|
||||
Here are some general hints to avoid running into these problems.
|
||||
|
||||
* Be aware of memory limits, especially when working with large lists since Blender can crash simply by running out of memory.
|
||||
|
||||
* Many hard to fix crashes end up being because of referencing freed data, when removing data be sure not to hold any references to it.
|
||||
|
||||
* Modules or classes that remain active while Blender is used, should not hold references to data the user may remove, instead, fetch data from the context each time the script is activated.
|
||||
|
||||
* Crashes may not happen every time, they may happen more on some configurations/operating-systems.
|
||||
- Be aware of memory limits,
|
||||
especially when working with large lists since Blender can crash simply by running out of memory.
|
||||
- Many hard to fix crashes end up being because of referencing freed data,
|
||||
when removing data be sure not to hold any references to it.
|
||||
- Modules or classes that remain active while Blender is used,
|
||||
should not hold references to data the user may remove, instead,
|
||||
fetch data from the context each time the script is activated.
|
||||
- Crashes may not happen every time, they may happen more on some configurations/operating-systems.
|
||||
|
||||
.. note::
|
||||
|
||||
To find the line of your script that crashes you can use the ``faulthandler`` module.
|
||||
See `faulthandler docs <http://docs.python.org/dev/library/faulthandler.html>`_.
|
||||
|
||||
While the crash may be in Blenders C/C++ code, this can help a lot to track down the area of the script that causes the crash.
|
||||
While the crash may be in Blenders C/C++ code,
|
||||
this can help a lot to track down the area of the script that causes the crash.
|
||||
|
||||
|
||||
Undo/Redo
|
||||
@@ -572,28 +680,36 @@ This example shows how you can tell undo changes the memory locations.
|
||||
>>> hash(bpy.context.object)
|
||||
-9223372036849951740
|
||||
|
||||
As suggested above, simply not holding references to data when Blender is used interactively by the user is the only way to ensure the script doesn't become unstable.
|
||||
As suggested above, simply not holding references to data when Blender is used
|
||||
interactively by the user is the only way to ensure the script doesn't become unstable.
|
||||
|
||||
|
||||
Undo & Library Data
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
One of the advantages with Blenders library linking system that undo can skip checking changes in library data since it is assumed to be static.
|
||||
One of the advantages with Blenders library linking system that undo
|
||||
can skip checking changes in library data since it is assumed to be static.
|
||||
|
||||
Tools in Blender are not allowed to modify library data.
|
||||
|
||||
Python however does not enforce this restriction.
|
||||
|
||||
This can be useful in some cases, using a script to adjust material values for example.
|
||||
But its also possible to use a script to make library data point to newly created local data, which is not supported since a call to undo will remove the local data but leave the library referencing it and likely crash.
|
||||
But its also possible to use a script to make library data point to newly created local data,
|
||||
which is not supported since a call to undo will remove the local data
|
||||
but leave the library referencing it and likely crash.
|
||||
|
||||
So it's best to consider modifying library data an advanced usage of the API and only to use it when you know what you're doing.
|
||||
So it's best to consider modifying library data an advanced usage of the API
|
||||
and only to use it when you know what you're doing.
|
||||
|
||||
|
||||
Edit Mode / Memory Access
|
||||
-------------------------
|
||||
|
||||
Switching edit-mode ``bpy.ops.object.mode_set(mode='EDIT')`` / ``bpy.ops.object.mode_set(mode='OBJECT')`` will re-allocate objects data, any references to a meshes vertices/polygons/uvs, armatures bones, curves points etc cannot be accessed after switching edit-mode.
|
||||
Switching edit-mode ``bpy.ops.object.mode_set(mode='EDIT')`` / ``bpy.ops.object.mode_set(mode='OBJECT')``
|
||||
will re-allocate objects data,
|
||||
any references to a meshes vertices/polygons/uvs, armatures bones,
|
||||
curves points etc cannot be accessed after switching edit-mode.
|
||||
|
||||
Only the reference to the data its self can be re-accessed, the following example will crash.
|
||||
|
||||
@@ -608,7 +724,8 @@ Only the reference to the data its self can be re-accessed, the following exampl
|
||||
print(polygons)
|
||||
|
||||
|
||||
So after switching edit-mode you need to re-access any object data variables, the following example shows how to avoid the crash above.
|
||||
So after switching edit-mode you need to re-access any object data variables,
|
||||
the following example shows how to avoid the crash above.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -622,13 +739,15 @@ So after switching edit-mode you need to re-access any object data variables, th
|
||||
print(polygons)
|
||||
|
||||
|
||||
These kinds of problems can happen for any functions which re-allocate the object data but are most common when switching edit-mode.
|
||||
These kinds of problems can happen for any functions which re-allocate
|
||||
the object data but are most common when switching edit-mode.
|
||||
|
||||
|
||||
Array Re-Allocation
|
||||
-------------------
|
||||
|
||||
When adding new points to a curve or vertices's/edges/polygons to a mesh, internally the array which stores this data is re-allocated.
|
||||
When adding new points to a curve or vertices's/edges/polygons to a mesh,
|
||||
internally the array which stores this data is re-allocated.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -639,15 +758,20 @@ When adding new points to a curve or vertices's/edges/polygons to a mesh, intern
|
||||
# this will crash!
|
||||
point.co = 1.0, 2.0, 3.0
|
||||
|
||||
This can be avoided by re-assigning the point variables after adding the new one or by storing indices's to the points rather then the points themselves.
|
||||
This can be avoided by re-assigning the point variables after adding the new one or by storing
|
||||
indices's to the points rather than the points themselves.
|
||||
|
||||
The best way is to sidestep the problem altogether add all the points to the curve at once. This means you don't have to worry about array re-allocation and its faster too since reallocating the entire array for every point added is inefficient.
|
||||
The best way is to sidestep the problem altogether add all the points to the curve at once.
|
||||
This means you don't have to worry about array re-allocation and its faster too
|
||||
since reallocating the entire array for every point added is inefficient.
|
||||
|
||||
|
||||
Removing Data
|
||||
-------------
|
||||
|
||||
**Any** data that you remove shouldn't be modified or accessed afterwards, this includes f-curves, drivers, render layers, timeline markers, modifiers, constraints along with objects, scenes, groups, bones.. etc.
|
||||
**Any** data that you remove shouldn't be modified or accessed afterwards,
|
||||
this includes f-curves, drivers, render layers, timeline markers, modifiers, constraints
|
||||
along with objects, scenes, groups, bones.. etc.
|
||||
|
||||
The ``remove()`` api calls will invalidate the data they free to prevent common mistakes.
|
||||
|
||||
@@ -658,12 +782,13 @@ The following example shows how this precortion works.
|
||||
mesh = bpy.data.meshes.new(name="MyMesh")
|
||||
# normally the script would use the mesh here...
|
||||
bpy.data.meshes.remove(mesh)
|
||||
print(mesh.name) # <- give an exception rather then crashing:
|
||||
print(mesh.name) # <- give an exception rather than crashing:
|
||||
|
||||
# ReferenceError: StructRNA of type Mesh has been removed
|
||||
|
||||
|
||||
But take care because this is limited to scripts accessing the variable which is removed, the next example will still crash.
|
||||
But take care because this is limited to scripts accessing the variable which is removed,
|
||||
the next example will still crash.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -676,9 +801,11 @@ But take care because this is limited to scripts accessing the variable which is
|
||||
sys.exit
|
||||
========
|
||||
|
||||
Some python modules will call ``sys.exit()`` themselves when an error occurs, while not common behavior this is something to watch out for because it may seem as if blender is crashing since ``sys.exit()`` will quit blender immediately.
|
||||
Some Python modules will call ``sys.exit()`` themselves when an error occurs,
|
||||
while not common behavior this is something to watch out for because it may seem
|
||||
as if Blender is crashing since ``sys.exit()`` will close Blender immediately.
|
||||
|
||||
For example, the ``optparse`` module will print an error and exit if the arguments are invalid.
|
||||
|
||||
An ugly way of troubleshooting this is to set ``sys.exit = None`` and see what line of python code is quitting, you could of course replace ``sys.exit`` with your own function but manipulating python in this way is bad practice.
|
||||
For example, the ``argparse`` module will print an error and exit if the arguments are invalid.
|
||||
|
||||
An ugly way of troubleshooting this is to set ``sys.exit = None`` and see what line of Python code is quitting,
|
||||
you could of course replace ``sys.exit`` with your own function but manipulating Python in this way is bad practice.
|
||||
|
@@ -1,18 +1,25 @@
|
||||
|
||||
.. _info_overview:
|
||||
|
||||
*******************
|
||||
Python API Overview
|
||||
*******************
|
||||
|
||||
This document is to give an understanding of how python and blender fit together, covering some of the functionality that isn't obvious from reading the API reference and example scripts.
|
||||
This document is to give an understanding of how Python and Blender fit together,
|
||||
covering some of the functionality that isn't obvious from reading the API reference and example scripts.
|
||||
|
||||
|
||||
Python in Blender
|
||||
=================
|
||||
|
||||
Blender embeds a python interpreter which is started with blender and stays active. This interpreter runs scripts to draw the user interface and is used for some of Blender's internal tools too.
|
||||
Blender embeds a Python interpreter which is started with Blender and stays active.
|
||||
This interpreter runs scripts to draw the user interface and is used for some of Blender's internal tools too.
|
||||
|
||||
This is a typical python environment so tutorials on how to write python scripts will work running the scripts in blender too. Blender provides the :mod:`bpy` module to the python interpreter. This module can be imported in a script and gives access to blender data, classes, and functions. Scripts that deal with blender data will need to import this module.
|
||||
This is a typical Python environment so tutorials on how to write Python scripts
|
||||
will work running the scripts in Blender too.
|
||||
Blender provides the :mod:`bpy` module to the Python interpreter.
|
||||
This module can be imported in a script and gives access to Blender data, classes, and functions.
|
||||
Scripts that deal with Blender data will need to import this module.
|
||||
|
||||
Here is a simple example of moving a vertex of the object named **Cube**:
|
||||
|
||||
@@ -21,84 +28,96 @@ Here is a simple example of moving a vertex of the object named **Cube**:
|
||||
import bpy
|
||||
bpy.data.objects["Cube"].data.vertices[0].co.x += 1.0
|
||||
|
||||
This modifies Blender's internal data directly. When you run this in the interactive console you will see the 3D viewport update.
|
||||
This modifies Blender's internal data directly.
|
||||
When you run this in the interactive console you will see the 3D viewport update.
|
||||
|
||||
|
||||
The Default Environment
|
||||
=======================
|
||||
|
||||
When developing your own scripts it may help to understand how blender sets up its python environment. Many python scripts come bundled with blender and can be used as a reference because they use the same API that script authors write tools in. Typical usage for scripts include: user interface, import/export, scene manipulation, automation, defining your own toolset and customization.
|
||||
When developing your own scripts it may help to understand how Blender sets up its Python environment.
|
||||
Many Python scripts come bundled with Blender and can be used as a reference
|
||||
because they use the same API that script authors write tools in.
|
||||
Typical usage for scripts include: user interface, import/export,
|
||||
scene manipulation, automation, defining your own toolset and customization.
|
||||
|
||||
On startup blender scans the ``scripts/startup/`` directory for python modules and imports them. The exact location of this directory depends on your installation. `See the directory layout docs <http://wiki.blender.org/index.php/Doc:2.6/Manual/Introduction/Installing_Blender/DirectoryLayout>`_
|
||||
On startup Blender scans the ``scripts/startup/`` directory for Python modules and imports them.
|
||||
The exact location of this directory depends on your installation.
|
||||
`See the directory layout docs
|
||||
<https://www.blender.org/manual/getting_started/installing_blender/directorylayout.html>`__
|
||||
|
||||
|
||||
Script Loading
|
||||
==============
|
||||
|
||||
This may seem obvious but it's important to note the difference between executing a script directly or importing it as a module.
|
||||
This may seem obvious but it's important to note the difference
|
||||
between executing a script directly or importing it as a module.
|
||||
|
||||
Scripts that extend blender - define classes that exist beyond the scripts execution, this makes future access to these classes (to unregister for example) more difficult than importing as a module where class instance is kept in the module and can be accessed by importing that module later on.
|
||||
Scripts that extend Blender - define classes that exist beyond the scripts execution,
|
||||
this makes future access to these classes (to unregister for example)
|
||||
more difficult than importing as a module where class instance is kept
|
||||
in the module and can be accessed by importing that module later on.
|
||||
|
||||
For this reason it's preferable to only use directly execute scripts that don't extend blender by registering classes.
|
||||
For this reason it's preferable to only use directly execute scripts that don't extend Blender by registering classes.
|
||||
|
||||
|
||||
Here are some ways to run scripts directly in blender.
|
||||
Here are some ways to run scripts directly in Blender.
|
||||
|
||||
* Loaded in the text editor and press **Run Script**.
|
||||
- Loaded in the text editor and press **Run Script**.
|
||||
- Typed or pasted into the interactive console.
|
||||
- Execute a Python file from the command line with Blender, eg:
|
||||
|
||||
* Typed or pasted into the interactive console.
|
||||
.. code-block:: sh
|
||||
|
||||
* Execute a python file from the command line with blender, eg:
|
||||
|
||||
``blender --python /home/me/my_script.py``
|
||||
blender --python /home/me/my_script.py
|
||||
|
||||
|
||||
To run as modules:
|
||||
|
||||
* The obvious way, ``import some_module`` command from the text window or interactive console.
|
||||
|
||||
* Open as a text block and tick "Register" option, this will load with the blend file.
|
||||
|
||||
* copy into one of the directories ``scripts/startup``, where they will be automatically imported on startup.
|
||||
|
||||
* define as an addon, enabling the addon will load it as a python module.
|
||||
- The obvious way, ``import some_module`` command from the text window or interactive console.
|
||||
- Open as a text block and tick "Register" option, this will load with the blend file.
|
||||
- copy into one of the directories ``scripts/startup``, where they will be automatically imported on startup.
|
||||
- define as an addon, enabling the addon will load it as a Python module.
|
||||
|
||||
|
||||
Addons
|
||||
------
|
||||
|
||||
Some of blenders functionality is best kept optional, alongside scripts loaded at startup we have addons which are kept in their own directory ``scripts/addons``, and only load on startup if selected from the user preferences.
|
||||
Some of Blenders functionality is best kept optional,
|
||||
alongside scripts loaded at startup we have addons which are kept in their own directory ``scripts/addons``,
|
||||
and only load on startup if selected from the user preferences.
|
||||
|
||||
The only difference between addons and built-in python modules is that addons must contain a **bl_info** variable which blender uses to read metadata such as name, author, category and URL.
|
||||
The only difference between addons and built-in Python modules is that addons must contain a ``bl_info``
|
||||
variable which Blender uses to read metadata such as name, author, category and URL.
|
||||
|
||||
The user preferences addon listing uses **bl_info** to display information about each addon.
|
||||
|
||||
`See Addons <http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons>`_ for details on the **bl_info** dictionary.
|
||||
`See Addons <http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons>`__
|
||||
for details on the ``bl_info`` dictionary.
|
||||
|
||||
|
||||
Integration through Classes
|
||||
===========================
|
||||
|
||||
Running python scripts in the text editor is useful for testing but you’ll want to extend blender to make tools accessible like other built-in functionality.
|
||||
Running Python scripts in the text editor is useful for testing but you'll
|
||||
want to extend Blender to make tools accessible like other built-in functionality.
|
||||
|
||||
The blender python api allows integration for:
|
||||
The Blender Python api allows integration for:
|
||||
|
||||
* :class:`bpy.types.Panel`
|
||||
|
||||
* :class:`bpy.types.Menu`
|
||||
|
||||
* :class:`bpy.types.Operator`
|
||||
|
||||
* :class:`bpy.types.PropertyGroup`
|
||||
|
||||
* :class:`bpy.types.KeyingSet`
|
||||
|
||||
* :class:`bpy.types.RenderEngine`
|
||||
- :class:`bpy.types.Panel`
|
||||
- :class:`bpy.types.Menu`
|
||||
- :class:`bpy.types.Operator`
|
||||
- :class:`bpy.types.PropertyGroup`
|
||||
- :class:`bpy.types.KeyingSet`
|
||||
- :class:`bpy.types.RenderEngine`
|
||||
|
||||
|
||||
This is intentionally limited. Currently, for more advanced features such as mesh modifiers, object types, or shader nodes, C/C++ must be used.
|
||||
This is intentionally limited. Currently, for more advanced features such as mesh modifiers,
|
||||
object types, or shader nodes, C/C++ must be used.
|
||||
|
||||
For python intergration Blender defines methods which are common to all types. This works by creating a python subclass of a Blender class which contains variables and functions specified by the parent class which are pre-defined to interface with Blender.
|
||||
For Python integration Blender defines methods which are common to all types.
|
||||
This works by creating a Python subclass of a Blender class which contains variables and functions
|
||||
specified by the parent class which are pre-defined to interface with Blender.
|
||||
|
||||
For example:
|
||||
|
||||
@@ -115,15 +134,20 @@ For example:
|
||||
|
||||
bpy.utils.register_class(SimpleOperator)
|
||||
|
||||
First note that we subclass a member of :mod:`bpy.types`, this is common for all classes which can be integrated with blender and used so we know if this is an Operator and not a Panel when registering.
|
||||
First note that we subclass a member of :mod:`bpy.types`,
|
||||
this is common for all classes which can be integrated with Blender and
|
||||
used so we know if this is an Operator and not a Panel when registering.
|
||||
|
||||
Both class properties start with a **bl_** prefix. This is a convention used to distinguish blender properties from those you add yourself.
|
||||
Both class properties start with a ``bl_`` prefix.
|
||||
This is a convention used to distinguish Blender properties from those you add yourself.
|
||||
|
||||
Next see the execute function, which takes an instance of the operator and the current context. A common prefix is not used for functions.
|
||||
Next see the execute function, which takes an instance of the operator and the current context.
|
||||
A common prefix is not used for functions.
|
||||
|
||||
Lastly the register function is called, this takes the class and loads it into blender. See `Class Registration`_.
|
||||
Lastly the register function is called, this takes the class and loads it into Blender. See `Class Registration`_.
|
||||
|
||||
Regarding inheritance, blender doesn't impose restrictions on the kinds of class inheritance used, the registration checks will use attributes and functions defined in parent classes.
|
||||
Regarding inheritance, Blender doesn't impose restrictions on the kinds of class inheritance used,
|
||||
the registration checks will use attributes and functions defined in parent classes.
|
||||
|
||||
class mix-in example:
|
||||
|
||||
@@ -141,11 +165,20 @@ class mix-in example:
|
||||
|
||||
bpy.utils.register_class(SimpleOperator)
|
||||
|
||||
Notice these classes don't define an ``__init__(self)`` function. While ``__init__()`` and ``__del__()`` will be called if defined, the class instances lifetime only spans the execution. So a panel for example will have a new instance for every redraw, for this reason there is rarely a cause to store variables in the panel instance. Instead, persistent variables should be stored in Blenders data so that the state can be restored when blender is restarted.
|
||||
Notice these classes don't define an ``__init__(self)`` function.
|
||||
While ``__init__()`` and ``__del__()`` will be called if defined,
|
||||
the class instances lifetime only spans the execution.
|
||||
So a panel for example will have a new instance for every redraw,
|
||||
for this reason there is rarely a cause to store variables in the panel instance.
|
||||
Instead, persistent variables should be stored in Blenders
|
||||
ata so that the state can be restored when Blender is restarted.
|
||||
|
||||
.. note:: Modal operators are an exception, keeping their instance variable as blender runs, see modal operator template.
|
||||
.. note::
|
||||
|
||||
So once the class is registered with blender, instancing the class and calling the functions is left up to blender. In fact you cannot instance these classes from the script as you would expect with most python API's.
|
||||
Modal operators are an exception, keeping their instance variable as Blender runs, see modal operator template.
|
||||
|
||||
So once the class is registered with Blender, instancing the class and calling the functions is left up to Blender.
|
||||
In fact you cannot instance these classes from the script as you would expect with most Python API's.
|
||||
|
||||
To run operators you can call them through the operator api, eg:
|
||||
|
||||
@@ -154,7 +187,8 @@ To run operators you can call them through the operator api, eg:
|
||||
import bpy
|
||||
bpy.ops.object.simple_operator()
|
||||
|
||||
User interface classes are given a context in which to draw, buttons window, file header, toolbar etc, then they are drawn when that area is displayed so they are never called by python scripts directly.
|
||||
User interface classes are given a context in which to draw, buttons window, file header, toolbar etc,
|
||||
then they are drawn when that area is displayed so they are never called by Python scripts directly.
|
||||
|
||||
|
||||
Registration
|
||||
@@ -164,9 +198,10 @@ Registration
|
||||
Module Registration
|
||||
-------------------
|
||||
|
||||
Blender modules loaded at startup require ``register()`` and ``unregister()`` functions. These are the *only* functions that blender calls from your code, which is otherwise a regular python module.
|
||||
Blender modules loaded at startup require ``register()`` and ``unregister()`` functions.
|
||||
These are the *only* functions that Blender calls from your code, which is otherwise a regular Python module.
|
||||
|
||||
A simple blender/python module can look like this:
|
||||
A simple Blender/Python module can look like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -184,12 +219,16 @@ A simple blender/python module can look like this:
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
These functions usually appear at the bottom of the script containing class registration sometimes adding menu items. You can also use them for internal purposes setting up data for your own tools but take care since register won't re-run when a new blend file is loaded.
|
||||
These functions usually appear at the bottom of the script containing class registration sometimes adding menu items.
|
||||
You can also use them for internal purposes setting up data for your own tools but take care
|
||||
since register won't re-run when a new blend file is loaded.
|
||||
|
||||
The register/unregister calls are used so it's possible to toggle addons and reload scripts while blender runs.
|
||||
If the register calls were placed in the body of the script, registration would be called on import, meaning there would be no distinction between importing a module or loading its classes into blender.
|
||||
The register/unregister calls are used so it's possible to toggle addons and reload scripts while Blender runs.
|
||||
If the register calls were placed in the body of the script, registration would be called on import,
|
||||
meaning there would be no distinction between importing a module or loading its classes into Blender.
|
||||
|
||||
This becomes problematic when a script imports classes from another module making it difficult to manage which classes are being loaded and when.
|
||||
This becomes problematic when a script imports classes from another module
|
||||
making it difficult to manage which classes are being loaded and when.
|
||||
|
||||
The last 2 lines are only for testing:
|
||||
|
||||
@@ -199,19 +238,24 @@ The last 2 lines are only for testing:
|
||||
register()
|
||||
|
||||
This allows the script to be run directly in the text editor to test changes.
|
||||
This ``register()`` call won't run when the script is imported as a module since ``__main__`` is reserved for direct execution.
|
||||
This ``register()`` call won't run when the script is imported as a module
|
||||
since ``__main__`` is reserved for direct execution.
|
||||
|
||||
|
||||
Class Registration
|
||||
------------------
|
||||
|
||||
Registering a class with blender results in the class definition being loaded into blender, where it becomes available alongside existing functionality.
|
||||
Registering a class with Blender results in the class definition being loaded into Blender,
|
||||
where it becomes available alongside existing functionality.
|
||||
|
||||
Once this class is loaded you can access it from :mod:`bpy.types`, using the bl_idname rather than the classes original name.
|
||||
Once this class is loaded you can access it from :mod:`bpy.types`,
|
||||
using the bl_idname rather than the classes original name.
|
||||
|
||||
When loading a class, blender performs sanity checks making sure all required properties and functions are found, that properties have the correct type, and that functions have the right number of arguments.
|
||||
When loading a class, Blender performs sanity checks making sure all required properties and functions are found,
|
||||
that properties have the correct type, and that functions have the right number of arguments.
|
||||
|
||||
Mostly you will not need concern yourself with this but if there is a problem with the class definition it will be raised on registering:
|
||||
Mostly you will not need concern yourself with this but if there is a problem
|
||||
with the class definition it will be raised on registering:
|
||||
|
||||
Using the function arguments ``def execute(self, context, spam)``, will raise an exception:
|
||||
|
||||
@@ -225,9 +269,13 @@ Using ``bl_idname = 1`` will raise.
|
||||
Multiple-Classes
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Loading classes into blender is described above, for simple cases calling :mod:`bpy.utils.register_class` (SomeClass) is sufficient, but when there are many classes or a packages submodule has its own classes it can be tedious to list them all for registration.
|
||||
Loading classes into Blender is described above,
|
||||
for simple cases calling :mod:`bpy.utils.register_class` (SomeClass) is sufficient,
|
||||
but when there are many classes or a packages submodule has its own
|
||||
classes it can be tedious to list them all for registration.
|
||||
|
||||
For more convenient loading/unloading :mod:`bpy.utils.register_module` (module) and :mod:`bpy.utils.unregister_module` (module) functions exist.
|
||||
For more convenient loading/unloading :mod:`bpy.utils.register_module` (module)
|
||||
and :mod:`bpy.utils.unregister_module` (module) functions exist.
|
||||
|
||||
A script which defines many of its own operators, panels menus etc. you only need to write:
|
||||
|
||||
@@ -239,13 +287,19 @@ A script which defines many of its own operators, panels menus etc. you only nee
|
||||
def unregister():
|
||||
bpy.utils.unregister_module(__name__)
|
||||
|
||||
Internally blender collects subclasses on registrable types, storing them by the module in which they are defined. By passing the module name to :mod:`bpy.utils.register_module` blender can register all classes created by this module and its submodules.
|
||||
Internally Blender collects subclasses on registrable types, storing them by the module in which they are defined.
|
||||
By passing the module name to :mod:`bpy.utils.register_module`
|
||||
Blender can register all classes created by this module and its submodules.
|
||||
|
||||
|
||||
Inter Classes Dependencies
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When customizing blender you may want to group your own settings together, after all, they will likely have to co-exist with other scripts. To group these properties classes need to be defined, for groups within groups or collections within groups you can find yourself having to deal with order of registration/unregistration.
|
||||
When customizing Blender you may want to group your own settings together,
|
||||
after all, they will likely have to co-exist with other scripts.
|
||||
To group these properties classes need to be defined,
|
||||
for groups within groups or collections within groups
|
||||
you can find yourself having to deal with order of registration/unregistration.
|
||||
|
||||
Custom properties groups are themselves classes which need to be registered.
|
||||
|
||||
@@ -311,7 +365,9 @@ Say you want to store material settings for a custom engine.
|
||||
Manipulating Classes
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Properties can be added and removed as blender runs, normally happens on register or unregister but for some special cases it may be useful to modify types as the script runs.
|
||||
Properties can be added and removed as Blender runs,
|
||||
normally happens on register or unregister but for some
|
||||
special cases it may be useful to modify types as the script runs.
|
||||
|
||||
For example:
|
||||
|
||||
@@ -341,7 +397,8 @@ This works just as well for PropertyGroup subclasses you define yourself.
|
||||
Dynamic Defined-Classes (Advanced)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In some cases the specifier for data may not be in blender, renderman shader definitions for example and it may be useful to define types and remove them on the fly.
|
||||
In some cases the specifier for data may not be in Blender,
|
||||
renderman shader definitions for example and it may be useful to define types and remove them on the fly.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -360,7 +417,8 @@ In some cases the specifier for data may not be in blender, renderman shader def
|
||||
|
||||
.. note::
|
||||
|
||||
Notice ``type()`` is called to define the class. This is an alternative syntax for class creation in python, better suited to constructing classes dynamically.
|
||||
``type()`` is called to define the class.
|
||||
This is an alternative syntax for class creation in Python, better suited to constructing classes dynamically.
|
||||
|
||||
|
||||
Calling these operators:
|
||||
|
@@ -1,3 +1,4 @@
|
||||
|
||||
.. _info_quickstart:
|
||||
|
||||
***********************
|
||||
@@ -32,13 +33,15 @@ The Blender/Python API **can't** (yet)...
|
||||
Before Starting
|
||||
===============
|
||||
|
||||
This document isn't intended to fully cover each topic. Rather, its purpose is to familiarize you with Blender Python API.
|
||||
This document isn't intended to fully cover each topic.
|
||||
Rather, its purpose is to familiarize you with Blender Python API.
|
||||
|
||||
|
||||
A quick list of helpful things to know before starting:
|
||||
|
||||
- Blender uses Python 3.x; some online documentation still assumes 2.x.
|
||||
- The interactive console is great for testing one-liners, It also has autocompletion so you can inspect the API quickly.
|
||||
- The interactive console is great for testing one-liners.
|
||||
It also has autocompletion so you can inspect the API quickly.
|
||||
- Button tool tips show Python attributes and operator names.
|
||||
- Right clicking on buttons and menu items directly links to API documentation.
|
||||
- For more examples, the text menu has a templates section where some example operators can be found.
|
||||
@@ -51,15 +54,19 @@ A quick list of helpful things to know before starting:
|
||||
Running Scripts
|
||||
---------------
|
||||
|
||||
The two most common ways to execute Python scripts are using the built-in text editor or entering commands in the Python console.
|
||||
The two most common ways to execute Python scripts are using the built-in
|
||||
text editor or entering commands in the Python console.
|
||||
|
||||
Both the **Text Editor** and **Python Console** are space types you can select from the view header.
|
||||
Both the *Text Editor* and *Python Console* are space types you can select from the view header.
|
||||
|
||||
Rather then manually configuring your spaces for Python development, you may prefer to use the **Scripting** screen, included default with Blender, accessible from the top headers screen selector.
|
||||
Rather than manually configuring your spaces for Python development,
|
||||
you may prefer to use the *Scripting* screen, included default with Blender,
|
||||
accessible from the top headers screen selector.
|
||||
|
||||
From the text editor you can open ``.py`` files or paste then from the clipboard, then test using **Run Script**.
|
||||
From the text editor you can open ``.py`` files or paste then from the clipboard, then test using *Run Script*.
|
||||
|
||||
The Python Console is typically used for typing in snippets and for testing to get immediate feedback, but can also have entire scripts pasted into it.
|
||||
The Python Console is typically used for typing in snippets and for testing to get immediate feedback,
|
||||
but can also have entire scripts pasted into it.
|
||||
|
||||
Scripts can also run from the command line with Blender but to learn Blender/Python this isn't essential.
|
||||
|
||||
@@ -73,9 +80,11 @@ Data Access
|
||||
Accessing DataBlocks
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Python accesses Blender's data in the same way as the animation system and user interface; this implies that any setting that can be changed via a button can also be changed from Python.
|
||||
Python accesses Blender's data in the same way as the animation system and user interface;
|
||||
this implies that any setting that can be changed via a button can also be changed from Python.
|
||||
|
||||
Accessing data from the currently loaded blend file is done with the module :mod:`bpy.data`. This gives access to library data. For example:
|
||||
Accessing data from the currently loaded blend file is done with the module :mod:`bpy.data`.
|
||||
This gives access to library data. For example:
|
||||
|
||||
>>> bpy.data.objects
|
||||
<bpy_collection[3], BlendDataObjects>
|
||||
@@ -92,7 +101,8 @@ About Collections
|
||||
|
||||
You'll notice that an index as well as a string can be used to access members of the collection.
|
||||
|
||||
Unlike Python's dictionaries, both methods are acceptable; however, the index of a member may change while running Blender.
|
||||
Unlike Python's dictionaries, both methods are acceptable;
|
||||
however, the index of a member may change while running Blender.
|
||||
|
||||
>>> list(bpy.data.objects)
|
||||
[bpy.data.objects["Cube"], bpy.data.objects["Plane"]]
|
||||
@@ -107,7 +117,10 @@ Unlike Python's dictionaries, both methods are acceptable; however, the index of
|
||||
Accessing Attributes
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Once you have a data block, such as a material, object, groups etc., its attributes can be accessed much like you would change a setting using the graphical interface. In fact, the tooltip for each button also displays the Python attribute which can help in finding what settings to change in a script.
|
||||
Once you have a data block, such as a material, object, groups etc.,
|
||||
its attributes can be accessed much like you would change a setting using the graphical interface.
|
||||
In fact, the tooltip for each button also displays the Python attribute
|
||||
which can help in finding what settings to change in a script.
|
||||
|
||||
>>> bpy.data.objects[0].name
|
||||
'Camera'
|
||||
@@ -119,7 +132,8 @@ Once you have a data block, such as a material, object, groups etc., its attribu
|
||||
bpy.data.materials['MyMaterial']
|
||||
|
||||
|
||||
For testing what data to access it's useful to use the "Console", which is its own space type. This supports auto-complete, giving you a fast way to dig into different data in your file.
|
||||
For testing what data to access it's useful to use the "Console", which is its own space type.
|
||||
This supports auto-complete, giving you a fast way to dig into different data in your file.
|
||||
|
||||
Example of a data path that can be quickly found via the console:
|
||||
|
||||
@@ -132,7 +146,8 @@ Example of a data path that can be quickly found via the console:
|
||||
Data Creation/Removal
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Those of you familiar with other Python API's may be surprised that new datablocks in the bpy API can't be created by calling the class:
|
||||
Those of you familiar with other Python API's may be surprised that
|
||||
new datablocks in the bpy API can't be created by calling the class:
|
||||
|
||||
>>> bpy.types.Mesh()
|
||||
Traceback (most recent call last):
|
||||
@@ -141,7 +156,8 @@ Those of you familiar with other Python API's may be surprised that new databloc
|
||||
|
||||
|
||||
This is an intentional part of the API design.
|
||||
The Blender/Python API can't create Blender data that exists outside the main Blender database (accessed through :mod:`bpy.data`), because this data is managed by Blender (save/load/undo/append... etc).
|
||||
The Blender/Python API can't create Blender data that exists outside the main Blender database
|
||||
(accessed through :mod:`bpy.data`), because this data is managed by Blender (save/load/undo/append... etc).
|
||||
|
||||
Data is added and removed via methods on the collections in :mod:`bpy.data`, eg:
|
||||
|
||||
@@ -155,8 +171,10 @@ Data is added and removed via methods on the collections in :mod:`bpy.data`, eg:
|
||||
Custom Properties
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Python can access properties on any datablock that has an ID (data that can be linked in and accessed from :mod:`bpy.data`.
|
||||
When assigning a property, you can make up your own names, these will be created when needed or overwritten if they exist.
|
||||
Python can access properties on any datablock that has an ID
|
||||
(data that can be linked in and accessed from :mod:`bpy.data`.
|
||||
When assigning a property, you can make up your own names,
|
||||
these will be created when needed or overwritten if they exist.
|
||||
|
||||
This data is saved with the blend file and copied with objects.
|
||||
|
||||
@@ -192,8 +210,10 @@ These properties are valid outside of Python. They can be animated by curves or
|
||||
Context
|
||||
-------
|
||||
|
||||
While it's useful to be able to access data directly by name or as a list, it's more common to operate on the user's selection.
|
||||
The context is always available from ``bpy.context`` and can be used to get the active object, scene, tool settings along with many other attributes.
|
||||
While it's useful to be able to access data directly by name or as a list,
|
||||
it's more common to operate on the user's selection.
|
||||
The context is always available from ``bpy.context`` and can be used to get the active object, scene,
|
||||
tool settings along with many other attributes.
|
||||
|
||||
Common-use cases:
|
||||
|
||||
@@ -201,7 +221,9 @@ Common-use cases:
|
||||
>>> bpy.context.selected_objects
|
||||
>>> bpy.context.visible_bones
|
||||
|
||||
Note that the context is read-only. These values cannot be modified directly, though they may be changed by running API functions or by using the data API.
|
||||
Note that the context is read-only.
|
||||
These values cannot be modified directly,
|
||||
though they may be changed by running API functions or by using the data API.
|
||||
|
||||
So ``bpy.context.object = obj`` will raise an error.
|
||||
|
||||
@@ -209,7 +231,8 @@ But ``bpy.context.scene.objects.active = obj`` will work as expected.
|
||||
|
||||
|
||||
The context attributes change depending on where they are accessed.
|
||||
The 3D view has different context members than the console, so take care when accessing context attributes that the user state is known.
|
||||
The 3D view has different context members than the console,
|
||||
so take care when accessing context attributes that the user state is known.
|
||||
|
||||
See :mod:`bpy.context` API reference.
|
||||
|
||||
@@ -217,7 +240,9 @@ See :mod:`bpy.context` API reference.
|
||||
Operators (Tools)
|
||||
-----------------
|
||||
|
||||
Operators are tools generally accessed by the user from buttons, menu items or key shortcuts. From the user perspective they are a tool but Python can run these with its own settings through the :mod:`bpy.ops` module.
|
||||
Operators are tools generally accessed by the user from buttons, menu items or key shortcuts.
|
||||
From the user perspective they are a tool but Python can run these with its own settings
|
||||
through the :mod:`bpy.ops` module.
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -230,14 +255,16 @@ Examples:
|
||||
|
||||
.. note::
|
||||
|
||||
The menu item: :menuselection:`Help --> Operator Cheat Sheet` gives a list of all operators and their default values in Python syntax, along with the generated docs.
|
||||
The menu item: :menuselection:`Help --> Operator Cheat Sheet`
|
||||
gives a list of all operators and their default values in Python syntax, along with the generated docs.
|
||||
This is a good way to get an overview of all Blender's operators.
|
||||
|
||||
|
||||
Operator Poll()
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Many operators have a "poll" function which may check that the mouse is in a valid area or that the object is in the correct mode (Edit Mode, Weight Paint etc).
|
||||
Many operators have a "poll" function which may check that the cursor
|
||||
is in a valid area or that the object is in the correct mode (Edit Mode, Weight Paint etc).
|
||||
When an operator's poll function fails within Python, an exception is raised.
|
||||
|
||||
For example, calling ``bpy.ops.view3d.render_border()`` from the console raises the following error:
|
||||
@@ -248,7 +275,8 @@ For example, calling ``bpy.ops.view3d.render_border()`` from the console raises
|
||||
|
||||
In this case the context must be the 3d view with an active camera.
|
||||
|
||||
To avoid using try/except clauses wherever operators are called you can call the operators own .poll() function to check if it can run in the current context.
|
||||
To avoid using try/except clauses wherever operators are called you can call the operators
|
||||
own ``poll()`` function to check if it can run in the current context.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -275,7 +303,8 @@ Example Operator
|
||||
|
||||
.. literalinclude:: ../../../release/scripts/templates_py/operator_simple.py
|
||||
|
||||
Once this script runs, ``SimpleOperator`` is registered with Blender and can be called from the operator search popup or added to the toolbar.
|
||||
Once this script runs, ``SimpleOperator`` is registered with Blender
|
||||
and can be called from the operator search popup or added to the toolbar.
|
||||
|
||||
To run the script:
|
||||
|
||||
@@ -285,19 +314,23 @@ To run the script:
|
||||
#. Click the button labeled ``New`` and the confirmation pop up in order to create a new text block.
|
||||
#. Press :kbd:`Ctrl-V` to paste the code into the text panel (the upper left frame).
|
||||
#. Click on the button **Run Script**.
|
||||
#. Move your mouse into the 3D view, press spacebar for the operator search menu, and type "Simple".
|
||||
#. Move your cursor into the 3D view, press spacebar for the operator search menu, and type "Simple".
|
||||
#. Click on the "Simple Operator" item found in search.
|
||||
|
||||
|
||||
.. seealso:: The class members with the ``bl_`` prefix are documented in the API
|
||||
reference :class:`bpy.types.Operator`
|
||||
|
||||
.. note:: The output from the ``main`` function is sent to the terminal; in order to see this, be sure to :ref:`use the terminal <use_the_terminal>`.
|
||||
.. note::
|
||||
|
||||
The output from the ``main`` function is sent to the terminal;
|
||||
in order to see this, be sure to :ref:`use the terminal <use_the_terminal>`.
|
||||
|
||||
Example Panel
|
||||
-------------
|
||||
|
||||
Panels register themselves as a class, like an operator. Notice the extra ``bl_`` variables used to set the context they display in.
|
||||
Panels register themselves as a class, like an operator.
|
||||
Notice the extra ``bl_`` variables used to set the context they display in.
|
||||
|
||||
.. literalinclude:: ../../../release/scripts/templates_py/ui_panel_simple.py
|
||||
|
||||
@@ -334,7 +367,8 @@ Blender's Python API can be split up into 3 categories.
|
||||
Native Types
|
||||
------------
|
||||
|
||||
In simple cases returning a number or a string as a custom type would be cumbersome, so these are accessed as normal Python types.
|
||||
In simple cases returning a number or a string as a custom type would be cumbersome,
|
||||
so these are accessed as normal Python types.
|
||||
|
||||
- Blender float/int/boolean -> float/int/boolean
|
||||
- Blender enumerator -> string
|
||||
@@ -359,7 +393,8 @@ Used for Blender datablocks and collections: :class:`bpy.types.bpy_struct`
|
||||
|
||||
For data that contains its own attributes groups/meshes/bones/scenes... etc.
|
||||
|
||||
There are 2 main types that wrap Blenders data, one for datablocks (known internally as ``bpy_struct``), another for properties.
|
||||
There are 2 main types that wrap Blenders data, one for datablocks
|
||||
(known internally as ``bpy_struct``), another for properties.
|
||||
|
||||
>>> bpy.context.object
|
||||
bpy.data.objects['Cube']
|
||||
@@ -375,7 +410,9 @@ Mathutils Types
|
||||
|
||||
Used for vectors, quaternion, eulers, matrix and color types, accessible from :mod:`mathutils`
|
||||
|
||||
Some attributes such as :class:`bpy.types.Object.location`, :class:`bpy.types.PoseBone.rotation_euler` and :class:`bpy.types.Scene.cursor_location` can be accessed as special math types which can be used together and manipulated in various useful ways.
|
||||
Some attributes such as :class:`bpy.types.Object.location`,
|
||||
:class:`bpy.types.PoseBone.rotation_euler` and :class:`bpy.types.Scene.cursor_location`
|
||||
can be accessed as special math types which can be used together and manipulated in various useful ways.
|
||||
|
||||
Example of a matrix, vector multiplication:
|
||||
|
||||
@@ -410,7 +447,9 @@ Animation
|
||||
|
||||
There are 2 ways to add keyframes through Python.
|
||||
|
||||
The first is through key properties directly, which is similar to inserting a keyframe from the button as a user. You can also manually create the curves and keyframe data, then set the path to the property. Here are examples of both methods.
|
||||
The first is through key properties directly, which is similar to inserting a keyframe from the button as a user.
|
||||
You can also manually create the curves and keyframe data, then set the path to the property.
|
||||
Here are examples of both methods.
|
||||
|
||||
Both examples insert a keyframe on the active object's Z axis.
|
||||
|
||||
|
@@ -1,10 +1,12 @@
|
||||
|
||||
***************
|
||||
Tips and Tricks
|
||||
***************
|
||||
|
||||
Here are various suggestions that you might find useful when writing scripts.
|
||||
|
||||
Some of these are just python features that scripters may not have thought to use with blender, others are blender specific.
|
||||
Some of these are just Python features that scripters may not have thought to use with Blender,
|
||||
others are Blender specific.
|
||||
|
||||
|
||||
.. _use_the_terminal:
|
||||
@@ -12,18 +14,21 @@ Some of these are just python features that scripters may not have thought to us
|
||||
Use The Terminal
|
||||
================
|
||||
|
||||
When writing python scripts, it's useful to have a terminal open, this is not the built-in python console but a terminal application which is used to start blender.
|
||||
When writing Python scripts, it's useful to have a terminal open,
|
||||
this is not the built-in Python console but a terminal application which is used to start Blender.
|
||||
|
||||
There are 3 main uses for the terminal, these are:
|
||||
|
||||
* You can see the output of ``print()`` as your script runs, which is useful to view debug info.
|
||||
|
||||
* The error trace-back is printed in full to the terminal which won't always generate an error popup in blender's user interface (depending on how the script is executed).
|
||||
|
||||
* If the script runs for too long or you accidentally enter an infinite loop, Ctrl+C in the terminal (Ctrl+Break on Windows) will quit the script early.
|
||||
- You can see the output of ``print()`` as your script runs, which is useful to view debug info.
|
||||
- The error trace-back is printed in full to the terminal which won't always generate an error popup in
|
||||
Blender's user interface (depending on how the script is executed).
|
||||
- If the script runs for too long or you accidentally enter an infinite loop,
|
||||
:kbd:`Ctrl-C` in the terminal (:kbd:`Ctrl-Break` on Windows) will quit the script early.
|
||||
|
||||
.. note::
|
||||
For Linux and OSX users this means starting the terminal first, then running blender from within it. On Windows the terminal can be enabled from the help menu.
|
||||
|
||||
For Linux and OSX users this means starting the terminal first, then running Blender from within it.
|
||||
On Windows the terminal can be enabled from the help menu.
|
||||
|
||||
|
||||
Interface Tricks
|
||||
@@ -33,43 +38,56 @@ Interface Tricks
|
||||
Access Operator Commands
|
||||
------------------------
|
||||
|
||||
You may have noticed that the tooltip for menu items and buttons includes the ``bpy.ops``... command to run that button, a handy (hidden) feature is that you can press Ctrl+C over any menu item/button to copy this command into the clipboard.
|
||||
You may have noticed that the tooltip for menu items and buttons includes the ``bpy.ops.[...])`` command
|
||||
to run that button, a handy (hidden) feature is that you can press :kbd:`Ctrl-C` over
|
||||
any menu item/button to copy this command into the clipboard.
|
||||
|
||||
|
||||
Access Data Path
|
||||
----------------
|
||||
|
||||
To find the path from an :class:`ID` datablock to its setting isn't always so simple since it may be nested away. To get this quickly you can right click on the setting and select select **Copy Data Path**,
|
||||
To find the path from an :class:`ID` datablock to its setting isn't always so simple since it may be nested away.
|
||||
To get this quickly you can right click on the setting and select select **Copy Data Path**,
|
||||
if this can't be generated, only the property name is copied.
|
||||
|
||||
.. note::
|
||||
|
||||
This uses the same method for creating the animation path used by :class:`bpy.types.FCurve.data_path` and :class:`bpy.types.DriverTarget.data_path` drivers.
|
||||
This uses the same method for creating the animation path used by
|
||||
:class:`bpy.types.FCurve.data_path` and
|
||||
:class:`bpy.types.DriverTarget.data_path` drivers.
|
||||
|
||||
|
||||
.. _info_show_all_operators
|
||||
.. _info_show_all_operators:
|
||||
|
||||
Show All Operators
|
||||
==================
|
||||
|
||||
While blender logs operators in the Info space, this only reports operators with the ``REGISTER`` option enabeld so as not to flood the Info view with calls to ``bpy.ops.view3d.smoothview`` and ``bpy.ops.view3d.zoom``.
|
||||
While Blender logs operators in the Info space,
|
||||
this only reports operators with the ``REGISTER`` option enabeld so as not to flood the *Info* view
|
||||
with calls to ``bpy.ops.view3d.smoothview`` and ``bpy.ops.view3d.zoom``.
|
||||
|
||||
However, for testing it can be useful to see **every** operator called in a terminal, do this by enabling the debug option either by passing the ``--debug-wm`` argument when starting blender or by setting :mod:`bpy.app.debug_wm` to True while blender is running.
|
||||
However, for testing it can be useful to see **every** operator called in a terminal,
|
||||
do this by enabling the debug option either by passing the ``--debug-wm`` argument when starting Blender
|
||||
or by setting :mod:`bpy.app.debug_wm` to ``True`` while Blender is running.
|
||||
|
||||
|
||||
Use an External Editor
|
||||
======================
|
||||
|
||||
Blenders text editor is fine for small changes and writing tests but its not full featured, for larger projects you'll probably want to use a standalone editor or python IDE.
|
||||
Blenders text editor is fine for small changes and writing tests but its not full featured,
|
||||
for larger projects you'll probably want to use a standalone editor or Python IDE.
|
||||
|
||||
Editing a text file externally and having the same text open in blender does work but isn't that optimal so here are 2 ways you can easily use an external file from blender.
|
||||
Editing a text file externally and having the same text open in Blender does work but isn't that optimal
|
||||
so here are 2 ways you can easily use an external file from Blender.
|
||||
|
||||
Using the following examples you'll still need textblock in Blender to execute,
|
||||
but reference an external file rather than including it directly.
|
||||
|
||||
Using the following examples you'll still need textblock in blender to execute, but reference an external file rather then including it directly.
|
||||
|
||||
Executing External Scripts
|
||||
--------------------------
|
||||
|
||||
This is the equivalent to running the script directly, referencing a scripts path from a 2 line textblock.
|
||||
This is the equivalent to running the script directly, referencing a scripts path from a 2 line text-block.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -102,12 +120,17 @@ This example shows loading a script in as a module and executing a module functi
|
||||
myscript.main()
|
||||
|
||||
|
||||
Notice that the script is reloaded every time, this forces use of the modified version, otherwise the cached one in ``sys.modules`` would be used until blender was restarted.
|
||||
Notice that the script is reloaded every time, this forces use of the modified version,
|
||||
otherwise the cached one in ``sys.modules`` would be used until Blender was restarted.
|
||||
|
||||
The important difference between this and executing the script directly is it has to call a function in the module, in this case ``main()`` but it can be any function, an advantage with this is you can pass arguments to the function from this small script which is often useful for testing different settings quickly.
|
||||
The important difference between this and executing the script directly is it
|
||||
has to call a function in the module, in this case ``main()`` but it can be any function,
|
||||
an advantage with this is you can pass arguments to the function from this
|
||||
small script which is often useful for testing different settings quickly.
|
||||
|
||||
The other issue with this is the script has to be in pythons module search path.
|
||||
While this is not best practice - for testing you can extend the search path, this example adds the current blend files directory to the search path, then loads the script as a module.
|
||||
The other issue with this is the script has to be in Pythons module search path.
|
||||
While this is not best practice - for testing you can extend the search path,
|
||||
this example adds the current blend files directory to the search path, then loads the script as a module.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -128,71 +151,86 @@ While this is not best practice - for testing you can extend the search path, th
|
||||
Don't Use Blender!
|
||||
==================
|
||||
|
||||
While developing your own scripts blenders interface can get in the way, manually reloading, running the scripts, opening file import etc. adds overhead.
|
||||
While developing your own scripts Blenders interface can get in the way,
|
||||
manually reloading, running the scripts, opening file import etc. adds overhead.
|
||||
|
||||
For scripts that are not interactive it can end up being more efficient not to use blenders interface at all and instead execute the script on the command line.
|
||||
For scripts that are not interactive it can end up being more efficient not to use
|
||||
Blenders interface at all and instead execute the script on the command line.
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: sh
|
||||
|
||||
blender --background --python myscript.py
|
||||
|
||||
|
||||
You might want to run this with a blend file so the script has some data to operate on.
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: sh
|
||||
|
||||
blender myscene.blend --background --python myscript.py
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Depending on your setup you might have to enter the full path to the blender executable.
|
||||
Depending on your setup you might have to enter the full path to the Blender executable.
|
||||
|
||||
|
||||
Once the script is running properly in background mode, you'll want to check the output of the script, this depends completely on the task at hand however here are some suggestions.
|
||||
Once the script is running properly in background mode, you'll want to check the output of the script,
|
||||
this depends completely on the task at hand however here are some suggestions.
|
||||
|
||||
* render the output to an image, use an image viewer and keep writing over the same image each time.
|
||||
|
||||
* save a new blend file, or export the file using one of blenders exporters.
|
||||
|
||||
* if the results can be displayed as text - print them or write them to a file.
|
||||
- render the output to an image, use an image viewer and keep writing over the same image each time.
|
||||
- save a new blend file, or export the file using one of Blenders exporters.
|
||||
- if the results can be displayed as text - print them or write them to a file.
|
||||
|
||||
|
||||
This can take a little time to setup, but it can be well worth the effort to reduce the time it takes to test changes - you can even have blender running the script ever few seconds with a viewer updating the results, so no need to leave your text editor to see changes.
|
||||
While this can take a little time to setup, it can be well worth the effort
|
||||
to reduce the time it takes to test changes - you can even have
|
||||
Blender running the script every few seconds with a viewer updating the results,
|
||||
so no need to leave your text editor to see changes.
|
||||
|
||||
|
||||
Use External Tools
|
||||
==================
|
||||
|
||||
When there are no readily available python modules to perform specific tasks it's worth keeping in mind you may be able to have python execute an external command on your data and read the result back in.
|
||||
When there are no readily available Python modules to perform specific tasks it's
|
||||
worth keeping in mind you may be able to have Python execute an external command
|
||||
on your data and read the result back in.
|
||||
|
||||
Using external programs adds an extra dependency and may limit who can use the script but to quickly setup your own custom pipeline or writing one-off scripts this can be handy.
|
||||
Using external programs adds an extra dependency and may limit who can use the script
|
||||
but to quickly setup your own custom pipeline or writing one-off scripts this can be handy.
|
||||
|
||||
Examples include:
|
||||
|
||||
* Run The Gimp in batch mode to execute custom scripts for advanced image processing.
|
||||
|
||||
* Write out 3D models to use external mesh manipulation tools and read back in the results.
|
||||
|
||||
* Convert files into recognizable formats before reading.
|
||||
- Run The Gimp in batch mode to execute custom scripts for advanced image processing.
|
||||
- Write out 3D models to use external mesh manipulation tools and read back in the results.
|
||||
- Convert files into recognizable formats before reading.
|
||||
|
||||
|
||||
Bundled Python & Extensions
|
||||
===========================
|
||||
|
||||
The Blender releases distributed from blender.org include a complete python installation on all platforms, this has the disadvantage that any extensions you have installed in your systems python wont be found by blender.
|
||||
The Blender releases distributed from blender.org include a complete Python installation on all platforms,
|
||||
this has the disadvantage that any extensions you have installed in your systems Python wont be found by Blender.
|
||||
|
||||
There are 2 ways around this:
|
||||
|
||||
* remove blender python sub-directory, blender will then fallback on the systems python and use that instead **python version must match the one that blender comes with**.
|
||||
- remove Blender Python sub-directory, Blender will then fallback on the systems Python and use that instead
|
||||
.. warning::
|
||||
|
||||
* copy the extensions into blender's python sub-directory so blender can access them, you could also copy the entire python installation into blenders sub-directory, replacing the one blender comes with. This works as long as the python versions match and the paths are created in the same relative locations. Doing this has the advantage that you can redistribute this bundle to others with blender and/or the game player, including any extensions you rely on.
|
||||
The Python version must match the one that Blender comes with.
|
||||
|
||||
- copy the extensions into Blender's Python sub-directory so Blender can access them,
|
||||
you could also copy the entire Python installation into Blenders sub-directory,
|
||||
replacing the one Blender comes with.
|
||||
This works as long as the Python versions match and the paths are created in the same relative locations.
|
||||
Doing this has the advantage that you can redistribute this bundle to others with Blender and/or the game player,
|
||||
including any extensions you rely on.
|
||||
|
||||
|
||||
Drop Into a Python Interpreter in Your Script
|
||||
=============================================
|
||||
|
||||
In the middle of a script you may want to inspect some variables, run some function and generally dig about to see whats going on.
|
||||
In the middle of a script you may want to inspect some variables,
|
||||
run some function and generally dig about to see whats going on.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -217,10 +255,13 @@ The next example is an equivalent single line version of the script above which
|
||||
__import__('code').interact(local=dict(globals(), **locals()))
|
||||
|
||||
|
||||
``code.interact`` can be added at any line in the script and will pause the script an launch an interactive interpreter in the terminal, when you're done you can quit the interpreter and the script will continue execution.
|
||||
``code.interact`` can be added at any line in the script
|
||||
and will pause the script an launch an interactive interpreter in the terminal,
|
||||
when you're done you can quit the interpreter and the script will continue execution.
|
||||
|
||||
|
||||
If you have **IPython** installed you can use their ``embed()`` function which will implicitly use the current namespace, this has autocomplete and some useful features that the standard python eval-loop doesn't have.
|
||||
If you have **IPython** installed you can use its ``embed()`` function which uses the current namespace.
|
||||
The IPython prompt has auto-complete and some useful features that the standard Python eval-loop doesn't have.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -228,7 +269,7 @@ If you have **IPython** installed you can use their ``embed()`` function which w
|
||||
IPython.embed()
|
||||
|
||||
|
||||
Admittedly this highlights the lack of any python debugging support built into blender, but its still handy to know.
|
||||
Admittedly this highlights the lack of any Python debugging support built into Blender, but its still handy to know.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -242,27 +283,32 @@ Advanced
|
||||
Blender as a module
|
||||
-------------------
|
||||
|
||||
From a python perspective it's nicer to have everything as an extension which lets the python script combine many components.
|
||||
From a Python perspective it's nicer to have everything as an extension
|
||||
which lets the Python script combine many components.
|
||||
|
||||
Advantages include:
|
||||
|
||||
* you can use external editors/IDE's with blenders python API and execute scripts within the IDE (step over code, inspect variables as the script runs).
|
||||
|
||||
* editors/IDE's can auto complete blender modules & variables.
|
||||
|
||||
* existing scripts can import blender API's without having to run inside blender.
|
||||
- you can use external editors/IDE's with Blenders Python API and execute scripts within the IDE
|
||||
(step over code, inspect variables as the script runs).
|
||||
- editors/IDE's can auto complete Blender modules & variables.
|
||||
- existing scripts can import Blender API's without having to run inside Blender.
|
||||
|
||||
|
||||
This is marked advanced because to run blender as a python module requires a special build option.
|
||||
This is marked advanced because to run Blender as a Python module requires a special build option.
|
||||
|
||||
For instructions on building see `Building blender as a python module <http://wiki.blender.org/index.php/User:Ideasman42/BlenderAsPyModule>`_
|
||||
For instructions on building see
|
||||
`Building Blender as a Python module <http://wiki.blender.org/index.php/User:Ideasman42/BlenderAsPyModule>`_
|
||||
|
||||
|
||||
Python Safety (Build Option)
|
||||
----------------------------
|
||||
|
||||
Since it's possible to access data which has been removed (see Gotcha's), this can be hard to track down the cause of crashes.
|
||||
Since it's possible to access data which has been removed (see Gotcha's),
|
||||
this can be hard to track down the cause of crashes.
|
||||
|
||||
To raise python exceptions on accessing freed data (rather then crashing), enable the CMake build option WITH_PYTHON_SAFETY.
|
||||
To raise Python exceptions on accessing freed data (rather than crashing),
|
||||
enable the CMake build option WITH_PYTHON_SAFETY.
|
||||
|
||||
This enables data tracking which makes data access about 2x slower
|
||||
which is why the option isn't enabled in release builds.
|
||||
|
||||
This enables data tracking which makes data access about 2x slower which is why the option is not enabled in release builds.
|
||||
|
@@ -208,6 +208,7 @@ The objects should move as before.
|
||||
|
||||
*Keep this addon open in Blender for the next step - Installing.*
|
||||
|
||||
|
||||
Install The Addon
|
||||
-----------------
|
||||
|
||||
@@ -221,10 +222,11 @@ restrictions that apply to Python modules and end with a ``.py`` extension.
|
||||
|
||||
Once the file is on disk, you can install it as you would for an addon downloaded online.
|
||||
|
||||
Open the user **File -> User Preferences**, Select the **Addon** section, press **Install Addon...** and select the file.
|
||||
Open the user :menuselection:`File -> User Preferences`,
|
||||
Select the *Addon* section, press *Install Addon...* and select the file.
|
||||
|
||||
Now the addon will be listed and you can enable it by pressing the check-box, if you want it to be enabled on restart,
|
||||
press **Save as Default**.
|
||||
Now the addon will be listed and you can enable it by pressing the check-box,
|
||||
if you want it to be enabled on restart, press *Save as Default*.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -238,7 +240,7 @@ press **Save as Default**.
|
||||
print(addon_utils.paths())
|
||||
|
||||
More is written on this topic here:
|
||||
`Directory Layout <http://wiki.blender.org/index.php/Doc:2.6/Manual/Introduction/Installing_Blender/DirectoryLayout>`_
|
||||
`Directory Layout <https://www.blender.org/manual/getting_started/installing_blender/directorylayout.html>`_
|
||||
|
||||
|
||||
Your Second Addon
|
||||
|
@@ -234,6 +234,7 @@ else:
|
||||
EXCLUDE_MODULES = [
|
||||
"aud",
|
||||
"bge",
|
||||
"bge.app"
|
||||
"bge.constraints",
|
||||
"bge.events",
|
||||
"bge.logic",
|
||||
@@ -262,6 +263,7 @@ else:
|
||||
"gpu",
|
||||
"mathutils",
|
||||
"mathutils.geometry",
|
||||
"mathutils.bvhtree",
|
||||
"mathutils.kdtree",
|
||||
"mathutils.noise",
|
||||
"freestyle",
|
||||
@@ -630,7 +632,7 @@ def pyfunc2sphinx(ident, fw, module_name, type_name, identifier, py_func, is_cla
|
||||
if type(py_func) == MethodType:
|
||||
return
|
||||
|
||||
arg_str = inspect.formatargspec(*inspect.getargspec(py_func))
|
||||
arg_str = inspect.formatargspec(*inspect.getfullargspec(py_func))
|
||||
|
||||
if not is_class:
|
||||
func_type = "function"
|
||||
@@ -1598,7 +1600,7 @@ def write_rst_contents(basepath):
|
||||
fw("\n")
|
||||
|
||||
# fw("`A PDF version of this document is also available <%s>`_\n" % BLENDER_PDF_FILENAME)
|
||||
fw("`A compressed ZIP file of this site is available <%s>`_\n" % BLENDER_ZIP_FILENAME)
|
||||
fw("This site can be downloaded for offline use `Download the full Documentation (zipped HTML files)<%s>`_\n" % BLENDER_ZIP_FILENAME)
|
||||
|
||||
fw("\n")
|
||||
|
||||
@@ -1643,7 +1645,7 @@ def write_rst_contents(basepath):
|
||||
|
||||
standalone_modules = (
|
||||
# mathutils
|
||||
"mathutils", "mathutils.geometry", "mathutils.kdtree", "mathutils.noise",
|
||||
"mathutils", "mathutils.geometry", "mathutils.bvhtree", "mathutils.kdtree", "mathutils.noise",
|
||||
# misc
|
||||
"freestyle", "bgl", "blf", "gpu", "aud", "bpy_extras",
|
||||
# bmesh, submodules are in own page
|
||||
@@ -1669,6 +1671,7 @@ def write_rst_contents(basepath):
|
||||
fw(" bge.texture.rst\n\n")
|
||||
fw(" bge.events.rst\n\n")
|
||||
fw(" bge.constraints.rst\n\n")
|
||||
fw(" bge.app.rst\n\n")
|
||||
|
||||
# rna generated change log
|
||||
fw(title_string("API Info", "=", double=True))
|
||||
@@ -1794,6 +1797,7 @@ def write_rst_importable_modules(basepath):
|
||||
"bpy.props" : "Property Definitions",
|
||||
"mathutils" : "Math Types & Utilities",
|
||||
"mathutils.geometry" : "Geometry Utilities",
|
||||
"mathutils.bvhtree" : "BVHTree Utilities",
|
||||
"mathutils.kdtree" : "KDTree Utilities",
|
||||
"mathutils.noise" : "Noise Utilities",
|
||||
"freestyle" : "Freestyle Module",
|
||||
@@ -1825,6 +1829,7 @@ def copy_handwritten_rsts(basepath):
|
||||
"bge.texture",
|
||||
"bge.events",
|
||||
"bge.constraints",
|
||||
"bge.app",
|
||||
"bgl", # "Blender OpenGl wrapper"
|
||||
"gpu", # "GPU Shader Module"
|
||||
|
||||
|
3
extern/CMakeLists.txt
vendored
3
extern/CMakeLists.txt
vendored
@@ -29,6 +29,7 @@ remove_strict_flags()
|
||||
add_subdirectory(rangetree)
|
||||
add_subdirectory(wcwidth)
|
||||
add_subdirectory(libmv)
|
||||
add_subdirectory(Eigen3)
|
||||
|
||||
if(WITH_OPENNL)
|
||||
add_subdirectory(colamd)
|
||||
@@ -77,7 +78,7 @@ if(WITH_LZMA)
|
||||
add_subdirectory(lzma)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES OR WITH_COMPOSITOR)
|
||||
if(WITH_CYCLES OR WITH_COMPOSITOR OR WITH_OPENSUBDIV)
|
||||
add_subdirectory(clew)
|
||||
add_subdirectory(cuew)
|
||||
endif()
|
||||
|
41
extern/Eigen3/CMakeLists.txt
vendored
Normal file
41
extern/Eigen3/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2015, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): Bastien Montagne.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
eigen3_capi.h
|
||||
|
||||
intern/eigenvalues.cc
|
||||
|
||||
intern/eigenvalues.h
|
||||
)
|
||||
|
||||
blender_add_lib(extern_eigen3 "${SRC}" "${INC}" "${INC_SYS}")
|
35
extern/Eigen3/SConscript
vendored
Normal file
35
extern/Eigen3/SConscript
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2015, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): Bastien Montagne.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
Import('env')
|
||||
|
||||
sources = env.Glob('intern/*.cc')
|
||||
|
||||
incs = '.'
|
||||
defs = []
|
||||
|
||||
env.BlenderLib('extern_eigen3', sources, Split(incs), defs, libtype=['extern','player'], priority=[10, 185])
|
32
extern/Eigen3/eigen3_capi.h
vendored
Normal file
32
extern/Eigen3/eigen3_capi.h
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2015 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Blender Foundation,
|
||||
* Bastien Montagne
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __EIGEN3_C_API_H__
|
||||
#define __EIGEN3_C_API_H__
|
||||
|
||||
#include "intern/eigenvalues.h"
|
||||
|
||||
#endif /* __EIGEN3_C_API_H__ */
|
70
extern/Eigen3/intern/eigenvalues.cc
vendored
Normal file
70
extern/Eigen3/intern/eigenvalues.cc
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2015 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Blender Foundation,
|
||||
* Bastien Montagne
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __EIGEN3_EIGENVALUES_C_API_CC__
|
||||
#define __EIGEN3_EIGENVALUES_C_API_CC__
|
||||
|
||||
/* Eigen gives annoying huge amount of warnings here, silence them! */
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wlogical-op"
|
||||
#endif
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Eigenvalues>
|
||||
|
||||
#include "eigenvalues.h"
|
||||
|
||||
using Eigen::SelfAdjointEigenSolver;
|
||||
|
||||
using Eigen::MatrixXf;
|
||||
using Eigen::VectorXf;
|
||||
using Eigen::Map;
|
||||
|
||||
using Eigen::Success;
|
||||
|
||||
bool EG3_self_adjoint_eigen_solve(const int size, const float *matrix, float *r_eigen_values, float *r_eigen_vectors)
|
||||
{
|
||||
SelfAdjointEigenSolver<MatrixXf> eigen_solver;
|
||||
|
||||
/* Blender and Eigen matrices are both column-major. */
|
||||
eigen_solver.compute(Map<MatrixXf>((float *)matrix, size, size));
|
||||
|
||||
if (eigen_solver.info() != Success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (r_eigen_values) {
|
||||
Map<VectorXf>(r_eigen_values, size) = eigen_solver.eigenvalues().transpose();
|
||||
}
|
||||
|
||||
if (r_eigen_vectors) {
|
||||
Map<MatrixXf>(r_eigen_vectors, size, size) = eigen_solver.eigenvectors();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* __EIGEN3_EIGENVALUES_C_API_CC__ */
|
40
extern/Eigen3/intern/eigenvalues.h
vendored
Normal file
40
extern/Eigen3/intern/eigenvalues.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2015 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Blender Foundation,
|
||||
* Bastien Montagne
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __EIGEN3_EIGENVALUES_C_API_H__
|
||||
#define __EIGEN3_EIGENVALUES_C_API_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool EG3_self_adjoint_eigen_solve(const int size, const float *matrix, float *r_eigen_values, float *r_eigen_vectors);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EIGEN3_EIGENVALUES_C_API_H__ */
|
3
extern/SConscript
vendored
3
extern/SConscript
vendored
@@ -11,6 +11,7 @@ SConscript(['colamd/SConscript'])
|
||||
SConscript(['rangetree/SConscript'])
|
||||
SConscript(['wcwidth/SConscript'])
|
||||
SConscript(['libmv/SConscript'])
|
||||
SConscript(['Eigen3/SConscript'])
|
||||
|
||||
if env['WITH_BF_GAMEENGINE']:
|
||||
SConscript(['recastnavigation/SConscript'])
|
||||
@@ -24,7 +25,7 @@ if env['WITH_BF_ELTOPO']:
|
||||
if env['WITH_BF_BULLET']:
|
||||
SConscript(['bullet2/src/SConscript'])
|
||||
|
||||
if env['WITH_BF_COMPOSITOR'] or env['WITH_BF_CYCLES']:
|
||||
if env['WITH_BF_COMPOSITOR'] or env['WITH_BF_CYCLES'] or env['WITH_BF_OPENSUBDIV']:
|
||||
SConscript (['clew/SConscript'])
|
||||
SConscript (['cuew/SConscript'])
|
||||
|
||||
|
4
extern/glew-es/SConscript
vendored
4
extern/glew-es/SConscript
vendored
@@ -6,7 +6,9 @@ Import('env')
|
||||
|
||||
sources = ['src/glew.c']
|
||||
|
||||
defs = env['BF_GL_DEFINITIONS']
|
||||
defs = []
|
||||
defs += env['BF_GL_DEFINITIONS']
|
||||
|
||||
if env['WITH_BF_GLEW_MX']:
|
||||
defs += ['GLEW_MX']
|
||||
incs = ['include']
|
||||
|
4
extern/glew/SConscript
vendored
4
extern/glew/SConscript
vendored
@@ -6,7 +6,9 @@ Import('env')
|
||||
|
||||
sources = ['src/glew.c']
|
||||
|
||||
defs = env['BF_GL_DEFINITIONS']
|
||||
defs = []
|
||||
defs += env['BF_GL_DEFINITIONS']
|
||||
|
||||
if env['WITH_BF_GLEW_MX']:
|
||||
defs += ['GLEW_MX']
|
||||
|
||||
|
7
extern/gtest/CMakeLists.txt
vendored
7
extern/gtest/CMakeLists.txt
vendored
@@ -21,6 +21,13 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
# avoid noisy warnings
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
remove_cc_flag(
|
||||
"-Wmissing-declarations"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(INC
|
||||
.
|
||||
include
|
||||
|
@@ -77,8 +77,11 @@ if(WITH_OPENNL)
|
||||
add_subdirectory(opennl)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
add_subdirectory(opensubdiv)
|
||||
endif()
|
||||
|
||||
# only windows needs utf16 converter
|
||||
if(WIN32)
|
||||
add_subdirectory(utfconv)
|
||||
endif()
|
||||
|
||||
|
@@ -27,8 +27,7 @@
|
||||
|
||||
Import ('env')
|
||||
|
||||
SConscript(['audaspace/SConscript',
|
||||
'string/SConscript',
|
||||
SConscript(['string/SConscript',
|
||||
'ghost/SConscript',
|
||||
'glew-mx/SConscript',
|
||||
'guardedalloc/SConscript',
|
||||
@@ -45,6 +44,9 @@ SConscript(['audaspace/SConscript',
|
||||
# currently only contains headers
|
||||
# SConscript('container/SConscript')
|
||||
|
||||
if env['WITH_BF_AUDASPACE']:
|
||||
SConscript(['audaspace/SConscript'])
|
||||
|
||||
if env ['WITH_BF_REMESH']:
|
||||
SConscript(['dualcon/SConscript'])
|
||||
|
||||
@@ -63,3 +65,5 @@ if env['WITH_BF_BULLET']:
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-mingw', 'linuxcross', 'win64-vc'):
|
||||
SConscript(['utfconv/SConscript'])
|
||||
|
||||
if env['WITH_BF_OPENSUBDIV']:
|
||||
SConscript (['opensubdiv/SConscript'])
|
||||
|
@@ -123,13 +123,13 @@ atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
|
||||
ATOMIC_INLINE uint64_t
|
||||
atomic_add_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd64((int64_t *)p, (int64_t)x);
|
||||
return InterlockedExchangeAdd64((int64_t *)p, (int64_t)x) + x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t
|
||||
atomic_sub_uint64(uint64_t *p, uint64_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd64((int64_t *)p, -((int64_t)x));
|
||||
return InterlockedExchangeAdd64((int64_t *)p, -((int64_t)x)) - x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t
|
||||
@@ -215,7 +215,7 @@ atomic_sub_uint64(uint64_t *p, uint64_t x)
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t
|
||||
atomic_cas_uint32(uint64_t *v, uint64_t old, uint64_t _new)
|
||||
atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
|
||||
{
|
||||
assert(sizeof(uint64_t) == sizeof(unsigned long));
|
||||
|
||||
@@ -235,7 +235,7 @@ atomic_sub_uint64(uint64_t *p, uint64_t x)
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint64_t
|
||||
atomic_cas_uint32(uint64_t *v, uint64_t old, uint64_t _new)
|
||||
atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
|
||||
{
|
||||
return __sync_val_compare_and_swap(v, old, _new);
|
||||
}
|
||||
@@ -268,13 +268,13 @@ atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
|
||||
ATOMIC_INLINE uint32_t
|
||||
atomic_add_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd(p, x);
|
||||
return InterlockedExchangeAdd(p, x) + x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t
|
||||
atomic_sub_uint32(uint32_t *p, uint32_t x)
|
||||
{
|
||||
return InterlockedExchangeAdd(p, -((int32_t)x));
|
||||
return InterlockedExchangeAdd(p, -((int32_t)x)) - x;
|
||||
}
|
||||
|
||||
ATOMIC_INLINE uint32_t
|
||||
|
@@ -21,6 +21,35 @@
|
||||
|
||||
remove_extra_strict_flags()
|
||||
|
||||
if(WITH_SYSTEM_AUDASPACE)
|
||||
|
||||
set(INC
|
||||
.
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${AUDASPACE_C_INCLUDE_DIRS}
|
||||
${AUDASPACE_PY_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/AUD_Set.cpp
|
||||
intern/AUD_Set.h
|
||||
)
|
||||
|
||||
if(WITH_PYTHON)
|
||||
list(APPEND INC_SYS
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
)
|
||||
list(APPEND SRC
|
||||
intern/AUD_PyInit.cpp
|
||||
intern/AUD_PyInit.h
|
||||
)
|
||||
add_definitions(-DWITH_PYTHON)
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
set(INC
|
||||
.
|
||||
FX
|
||||
@@ -316,5 +345,6 @@ if(WITH_PYTHON)
|
||||
)
|
||||
add_definitions(-DWITH_PYTHON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
blender_add_lib(bf_intern_audaspace "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
@@ -21,9 +21,15 @@
|
||||
#
|
||||
# ***** END LGPL LICENSE BLOCK *****
|
||||
|
||||
from os import path
|
||||
Import ('env')
|
||||
|
||||
sources = env.Glob('intern/*.cpp') + env.Glob('FX/*.cpp')
|
||||
|
||||
# AUD_PyInit is for external audaspace only
|
||||
sources.remove(path.join('intern', 'AUD_PyInit.cpp'))
|
||||
|
||||
|
||||
incs = '. intern FX ' + env['BF_PTHREADS_INC'] + ' ' + env['BF_BOOST_INC']
|
||||
defs = []
|
||||
|
||||
|
@@ -99,7 +99,7 @@ extern "C" {
|
||||
#include <cassert>
|
||||
|
||||
typedef boost::shared_ptr<AUD_IFactory> AUD_Sound;
|
||||
typedef boost::shared_ptr<AUD_ReadDevice> AUD_Device;
|
||||
typedef boost::shared_ptr<AUD_IDevice> AUD_Device;
|
||||
typedef boost::shared_ptr<AUD_IHandle> AUD_Handle;
|
||||
typedef boost::shared_ptr<AUD_SequencerEntry> AUD_SEntry;
|
||||
|
||||
@@ -130,70 +130,69 @@ void AUD_exitOnce()
|
||||
#endif
|
||||
}
|
||||
|
||||
int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
|
||||
AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name)
|
||||
{
|
||||
boost::shared_ptr<AUD_IDevice> dev;
|
||||
|
||||
if (AUD_device.get()) {
|
||||
AUD_exit();
|
||||
AUD_exit(NULL);
|
||||
}
|
||||
|
||||
std::string dname = device;
|
||||
|
||||
try {
|
||||
switch(device) {
|
||||
case AUD_NULL_DEVICE:
|
||||
if(dname == "Null") {
|
||||
dev = boost::shared_ptr<AUD_IDevice>(new AUD_NULLDevice());
|
||||
break;
|
||||
}
|
||||
#ifdef WITH_SDL
|
||||
case AUD_SDL_DEVICE:
|
||||
if (SDL_Init == (void *)0) {
|
||||
printf("Warning: SDL libraries are not installed\n");
|
||||
// No break, fall through to default, to return false
|
||||
}
|
||||
else {
|
||||
dev = boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
|
||||
break;
|
||||
}
|
||||
else if(dname == "SDL")
|
||||
{
|
||||
dev = boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_OPENAL
|
||||
case AUD_OPENAL_DEVICE:
|
||||
else if(dname == "OpenAL")
|
||||
{
|
||||
dev = boost::shared_ptr<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_JACK
|
||||
case AUD_JACK_DEVICE:
|
||||
else if(dname == "Jack")
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
struct stat st;
|
||||
if (stat("/Library/Frameworks/Jackmp.framework", &st) != 0) {
|
||||
printf("Warning: Jack Framework not installed\n");
|
||||
// No break, fall through to default, to return false
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!AUD_jack_supported()) {
|
||||
printf("Warning: Jack client not installed\n");
|
||||
// No break, fall through to default, to return false
|
||||
printf("Warning: Jack cllient not installed\n");
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
dev = boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice("Blender", specs, buffersize));
|
||||
break;
|
||||
dev = boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AUD_device = dev;
|
||||
AUD_3ddevice = dynamic_cast<AUD_I3DDevice *>(AUD_device.get());
|
||||
|
||||
return true;
|
||||
return (AUD_Device*)1;
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_exit()
|
||||
void AUD_exit(AUD_Device* device)
|
||||
{
|
||||
AUD_device = boost::shared_ptr<AUD_IDevice>();
|
||||
AUD_3ddevice = NULL;
|
||||
@@ -266,7 +265,7 @@ PyObject *AUD_initPython()
|
||||
return module;
|
||||
}
|
||||
|
||||
void *AUD_getPythonFactory(AUD_Sound *sound)
|
||||
void *AUD_getPythonSound(AUD_Sound *sound)
|
||||
{
|
||||
if (sound) {
|
||||
Factory *obj = (Factory *) Factory_empty();
|
||||
@@ -279,7 +278,7 @@ void *AUD_getPythonFactory(AUD_Sound *sound)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_getPythonSound(void *sound)
|
||||
AUD_Sound *AUD_getSoundFromPython(void *sound)
|
||||
{
|
||||
Factory *factory = checkFactory((PyObject *)sound);
|
||||
|
||||
@@ -291,16 +290,26 @@ AUD_Sound *AUD_getPythonSound(void *sound)
|
||||
|
||||
#endif
|
||||
|
||||
void AUD_lock()
|
||||
void AUD_Device_lock(AUD_Device* device)
|
||||
{
|
||||
AUD_device->lock();
|
||||
}
|
||||
|
||||
void AUD_unlock()
|
||||
void AUD_Device_unlock(AUD_Device* device)
|
||||
{
|
||||
AUD_device->unlock();
|
||||
}
|
||||
|
||||
AUD_Channels AUD_Device_getChannels(AUD_Device* device)
|
||||
{
|
||||
return AUD_device->getSpecs().channels;
|
||||
}
|
||||
|
||||
AUD_SampleRate AUD_Device_getRate(AUD_Device* device)
|
||||
{
|
||||
return AUD_device->getSpecs().rate;
|
||||
}
|
||||
|
||||
AUD_SoundInfo AUD_getInfo(AUD_Sound *sound)
|
||||
{
|
||||
assert(sound);
|
||||
@@ -326,19 +335,19 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound *sound)
|
||||
return info;
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_load(const char *filename)
|
||||
AUD_Sound *AUD_Sound_file(const char *filename)
|
||||
{
|
||||
assert(filename);
|
||||
return new AUD_Sound(new AUD_FileFactory(filename));
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_loadBuffer(unsigned char *buffer, int size)
|
||||
AUD_Sound *AUD_Sound_bufferFile(unsigned char *buffer, int size)
|
||||
{
|
||||
assert(buffer);
|
||||
return new AUD_Sound(new AUD_FileFactory(buffer, size));
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_bufferSound(AUD_Sound *sound)
|
||||
AUD_Sound *AUD_Sound_cache(AUD_Sound *sound)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
@@ -351,13 +360,13 @@ AUD_Sound *AUD_bufferSound(AUD_Sound *sound)
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_monoSound(AUD_Sound *sound)
|
||||
AUD_Sound *AUD_Sound_rechannel(AUD_Sound *sound, AUD_Channels channels)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
try {
|
||||
AUD_DeviceSpecs specs;
|
||||
specs.channels = AUD_CHANNELS_MONO;
|
||||
specs.channels = channels;
|
||||
specs.rate = AUD_RATE_INVALID;
|
||||
specs.format = AUD_FORMAT_INVALID;
|
||||
return new AUD_Sound(new AUD_ChannelMapperFactory(*sound, specs));
|
||||
@@ -368,7 +377,7 @@ AUD_Sound *AUD_monoSound(AUD_Sound *sound)
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_delaySound(AUD_Sound *sound, float delay)
|
||||
AUD_Sound *AUD_Sound_delay(AUD_Sound *sound, float delay)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
@@ -381,7 +390,7 @@ AUD_Sound *AUD_delaySound(AUD_Sound *sound, float delay)
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_limitSound(AUD_Sound *sound, float start, float end)
|
||||
AUD_Sound *AUD_Sound_limit(AUD_Sound *sound, float start, float end)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
@@ -394,7 +403,7 @@ AUD_Sound *AUD_limitSound(AUD_Sound *sound, float start, float end)
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_pingpongSound(AUD_Sound *sound)
|
||||
AUD_Sound *AUD_Sound_pingpong(AUD_Sound *sound)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
@@ -407,7 +416,7 @@ AUD_Sound *AUD_pingpongSound(AUD_Sound *sound)
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_loopSound(AUD_Sound *sound)
|
||||
AUD_Sound *AUD_Sound_loop(AUD_Sound *sound)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
@@ -420,7 +429,7 @@ AUD_Sound *AUD_loopSound(AUD_Sound *sound)
|
||||
}
|
||||
}
|
||||
|
||||
int AUD_setLoop(AUD_Handle *handle, int loops)
|
||||
int AUD_Handle_setLoopCount(AUD_Handle *handle, int loops)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
@@ -447,13 +456,13 @@ AUD_Sound *AUD_rectifySound(AUD_Sound *sound)
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_unload(AUD_Sound *sound)
|
||||
void AUD_Sound_free(AUD_Sound *sound)
|
||||
{
|
||||
assert(sound);
|
||||
delete sound;
|
||||
}
|
||||
|
||||
AUD_Handle *AUD_play(AUD_Sound *sound, int keep)
|
||||
AUD_Handle *AUD_Device_play(AUD_Device* device, AUD_Sound *sound, int keep)
|
||||
{
|
||||
assert(sound);
|
||||
try {
|
||||
@@ -468,19 +477,19 @@ AUD_Handle *AUD_play(AUD_Sound *sound, int keep)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int AUD_pause(AUD_Handle *handle)
|
||||
int AUD_Handle_pause(AUD_Handle *handle)
|
||||
{
|
||||
assert(handle);
|
||||
return (*handle)->pause();
|
||||
}
|
||||
|
||||
int AUD_resume(AUD_Handle *handle)
|
||||
int AUD_Handle_resume(AUD_Handle *handle)
|
||||
{
|
||||
assert(handle);
|
||||
return (*handle)->resume();
|
||||
}
|
||||
|
||||
int AUD_stop(AUD_Handle *handle)
|
||||
int AUD_Handle_stop(AUD_Handle *handle)
|
||||
{
|
||||
assert(handle);
|
||||
int result = (*handle)->stop();
|
||||
@@ -488,31 +497,36 @@ int AUD_stop(AUD_Handle *handle)
|
||||
return result;
|
||||
}
|
||||
|
||||
int AUD_setKeep(AUD_Handle *handle, int keep)
|
||||
void AUD_Device_stopAll(void* device)
|
||||
{
|
||||
AUD_device->stopAll();
|
||||
}
|
||||
|
||||
int AUD_Handle_setKeep(AUD_Handle *handle, int keep)
|
||||
{
|
||||
assert(handle);
|
||||
return (*handle)->setKeep(keep);
|
||||
}
|
||||
|
||||
int AUD_seek(AUD_Handle *handle, float seekTo)
|
||||
int AUD_Handle_setPosition(AUD_Handle *handle, float seekTo)
|
||||
{
|
||||
assert(handle);
|
||||
return (*handle)->seek(seekTo);
|
||||
}
|
||||
|
||||
float AUD_getPosition(AUD_Handle *handle)
|
||||
float AUD_Handle_getPosition(AUD_Handle *handle)
|
||||
{
|
||||
assert(handle);
|
||||
return (*handle)->getPosition();
|
||||
}
|
||||
|
||||
AUD_Status AUD_getStatus(AUD_Handle *handle)
|
||||
AUD_Status AUD_Handle_getStatus(AUD_Handle *handle)
|
||||
{
|
||||
assert(handle);
|
||||
return (*handle)->getStatus();
|
||||
}
|
||||
|
||||
int AUD_setListenerLocation(const float location[3])
|
||||
int AUD_Device_setListenerLocation(const float location[3])
|
||||
{
|
||||
if (AUD_3ddevice) {
|
||||
AUD_Vector3 v(location[0], location[1], location[2]);
|
||||
@@ -523,7 +537,7 @@ int AUD_setListenerLocation(const float location[3])
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setListenerVelocity(const float velocity[3])
|
||||
int AUD_Device_setListenerVelocity(const float velocity[3])
|
||||
{
|
||||
if (AUD_3ddevice) {
|
||||
AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
|
||||
@@ -534,7 +548,7 @@ int AUD_setListenerVelocity(const float velocity[3])
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setListenerOrientation(const float orientation[4])
|
||||
int AUD_Device_setListenerOrientation(const float orientation[4])
|
||||
{
|
||||
if (AUD_3ddevice) {
|
||||
AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
|
||||
@@ -545,7 +559,7 @@ int AUD_setListenerOrientation(const float orientation[4])
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setSpeedOfSound(float speed)
|
||||
int AUD_Device_setSpeedOfSound(void* device, float speed)
|
||||
{
|
||||
if (AUD_3ddevice) {
|
||||
AUD_3ddevice->setSpeedOfSound(speed);
|
||||
@@ -555,7 +569,7 @@ int AUD_setSpeedOfSound(float speed)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setDopplerFactor(float factor)
|
||||
int AUD_Device_setDopplerFactor(void* device, float factor)
|
||||
{
|
||||
if (AUD_3ddevice) {
|
||||
AUD_3ddevice->setDopplerFactor(factor);
|
||||
@@ -565,7 +579,7 @@ int AUD_setDopplerFactor(float factor)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setDistanceModel(AUD_DistanceModel model)
|
||||
int AUD_Device_setDistanceModel(void* device, AUD_DistanceModel model)
|
||||
{
|
||||
if (AUD_3ddevice) {
|
||||
AUD_3ddevice->setDistanceModel(model);
|
||||
@@ -575,7 +589,7 @@ int AUD_setDistanceModel(AUD_DistanceModel model)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setSourceLocation(AUD_Handle *handle, const float location[3])
|
||||
int AUD_Handle_setLocation(AUD_Handle *handle, const float location[3])
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -588,7 +602,7 @@ int AUD_setSourceLocation(AUD_Handle *handle, const float location[3])
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setSourceVelocity(AUD_Handle *handle, const float velocity[3])
|
||||
int AUD_Handle_setVelocity(AUD_Handle *handle, const float velocity[3])
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -601,7 +615,7 @@ int AUD_setSourceVelocity(AUD_Handle *handle, const float velocity[3])
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setSourceOrientation(AUD_Handle *handle, const float orientation[4])
|
||||
int AUD_Handle_setOrientation(AUD_Handle *handle, const float orientation[4])
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -614,7 +628,7 @@ int AUD_setSourceOrientation(AUD_Handle *handle, const float orientation[4])
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setRelative(AUD_Handle *handle, int relative)
|
||||
int AUD_Handle_setRelative(AUD_Handle *handle, int relative)
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -626,7 +640,7 @@ int AUD_setRelative(AUD_Handle *handle, int relative)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setVolumeMaximum(AUD_Handle *handle, float volume)
|
||||
int AUD_Handle_setVolumeMaximum(AUD_Handle *handle, float volume)
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -638,7 +652,7 @@ int AUD_setVolumeMaximum(AUD_Handle *handle, float volume)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setVolumeMinimum(AUD_Handle *handle, float volume)
|
||||
int AUD_Handle_setVolumeMinimum(AUD_Handle *handle, float volume)
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -650,7 +664,7 @@ int AUD_setVolumeMinimum(AUD_Handle *handle, float volume)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setDistanceMaximum(AUD_Handle *handle, float distance)
|
||||
int AUD_Handle_setDistanceMaximum(AUD_Handle *handle, float distance)
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -662,7 +676,7 @@ int AUD_setDistanceMaximum(AUD_Handle *handle, float distance)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setDistanceReference(AUD_Handle *handle, float distance)
|
||||
int AUD_Handle_setDistanceReference(AUD_Handle *handle, float distance)
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -674,7 +688,7 @@ int AUD_setDistanceReference(AUD_Handle *handle, float distance)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setAttenuation(AUD_Handle *handle, float factor)
|
||||
int AUD_Handle_setAttenuation(AUD_Handle *handle, float factor)
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -686,7 +700,7 @@ int AUD_setAttenuation(AUD_Handle *handle, float factor)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setConeAngleOuter(AUD_Handle *handle, float angle)
|
||||
int AUD_Handle_setConeAngleOuter(AUD_Handle *handle, float angle)
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -698,7 +712,7 @@ int AUD_setConeAngleOuter(AUD_Handle *handle, float angle)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setConeAngleInner(AUD_Handle *handle, float angle)
|
||||
int AUD_Handle_setConeAngleInner(AUD_Handle *handle, float angle)
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -710,7 +724,7 @@ int AUD_setConeAngleInner(AUD_Handle *handle, float angle)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setConeVolumeOuter(AUD_Handle *handle, float volume)
|
||||
int AUD_Handle_setConeVolumeOuter(AUD_Handle *handle, float volume)
|
||||
{
|
||||
assert(handle);
|
||||
boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
|
||||
@@ -722,7 +736,7 @@ int AUD_setConeVolumeOuter(AUD_Handle *handle, float volume)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setSoundVolume(AUD_Handle *handle, float volume)
|
||||
int AUD_Handle_setVolume(AUD_Handle *handle, float volume)
|
||||
{
|
||||
assert(handle);
|
||||
try {
|
||||
@@ -732,7 +746,7 @@ int AUD_setSoundVolume(AUD_Handle *handle, float volume)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setSoundPitch(AUD_Handle *handle, float pitch)
|
||||
int AUD_Handle_setPitch(AUD_Handle *handle, float pitch)
|
||||
{
|
||||
assert(handle);
|
||||
try {
|
||||
@@ -784,13 +798,13 @@ int AUD_setDeviceVolume(AUD_Device *device, float volume)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_readDevice(AUD_Device *device, data_t *buffer, int length)
|
||||
int AUD_Device_read(AUD_Device *device, data_t *buffer, int length)
|
||||
{
|
||||
assert(device);
|
||||
assert(buffer);
|
||||
|
||||
try {
|
||||
return (*device)->read(buffer, length);
|
||||
return boost::dynamic_pointer_cast<AUD_ReadDevice>(*device)->read(buffer, length);
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
@@ -798,12 +812,11 @@ int AUD_readDevice(AUD_Device *device, data_t *buffer, int length)
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_closeReadDevice(AUD_Device *device)
|
||||
void AUD_Device_free(AUD_Device *device)
|
||||
{
|
||||
assert(device);
|
||||
|
||||
try {
|
||||
delete device;
|
||||
if(device != &AUD_device)
|
||||
delete device;
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
@@ -901,7 +914,7 @@ AUD_Handle *AUD_pauseAfter(AUD_Handle *handle, float seconds)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_createSequencer(float fps, int muted)
|
||||
AUD_Sound *AUD_Sequence_create(float fps, int muted)
|
||||
{
|
||||
// specs are changed at a later point!
|
||||
AUD_Specs specs;
|
||||
@@ -911,22 +924,22 @@ AUD_Sound *AUD_createSequencer(float fps, int muted)
|
||||
return sequencer;
|
||||
}
|
||||
|
||||
void AUD_destroySequencer(AUD_Sound *sequencer)
|
||||
void AUD_Sequence_free(AUD_Sound *sequencer)
|
||||
{
|
||||
delete sequencer;
|
||||
}
|
||||
|
||||
void AUD_setSequencerMuted(AUD_Sound *sequencer, int muted)
|
||||
void AUD_Sequence_setMuted(AUD_Sound *sequencer, int muted)
|
||||
{
|
||||
dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->mute(muted);
|
||||
}
|
||||
|
||||
void AUD_setSequencerFPS(AUD_Sound *sequencer, float fps)
|
||||
void AUD_Sequence_setFPS(AUD_Sound *sequencer, float fps)
|
||||
{
|
||||
dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setFPS(fps);
|
||||
}
|
||||
|
||||
AUD_SEntry *AUD_addSequence(AUD_Sound *sequencer, AUD_Sound *sound,
|
||||
AUD_SEntry *AUD_Sequence_add(AUD_Sound *sequencer, AUD_Sound *sound,
|
||||
float begin, float end, float skip)
|
||||
{
|
||||
if (!sound)
|
||||
@@ -934,28 +947,23 @@ AUD_SEntry *AUD_addSequence(AUD_Sound *sequencer, AUD_Sound *sound,
|
||||
return new AUD_SEntry(((AUD_SequencerFactory *)sequencer->get())->add(*sound, begin, end, skip));
|
||||
}
|
||||
|
||||
void AUD_removeSequence(AUD_Sound *sequencer, AUD_SEntry *entry)
|
||||
void AUD_Sequence_remove(AUD_Sound *sequencer, AUD_SEntry *entry)
|
||||
{
|
||||
dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->remove(*entry);
|
||||
delete entry;
|
||||
}
|
||||
|
||||
void AUD_moveSequence(AUD_SEntry *entry, float begin, float end, float skip)
|
||||
void AUD_SequenceEntry_move(AUD_SEntry *entry, float begin, float end, float skip)
|
||||
{
|
||||
(*entry)->move(begin, end, skip);
|
||||
}
|
||||
|
||||
void AUD_muteSequence(AUD_SEntry *entry, char mute)
|
||||
void AUD_SequenceEntry_setMuted(AUD_SEntry *entry, char mute)
|
||||
{
|
||||
(*entry)->mute(mute);
|
||||
}
|
||||
|
||||
void AUD_setRelativeSequence(AUD_SEntry *entry, char relative)
|
||||
{
|
||||
(*entry)->setRelative(relative);
|
||||
}
|
||||
|
||||
void AUD_updateSequenceSound(AUD_SEntry *entry, AUD_Sound *sound)
|
||||
void AUD_SequenceEntry_setSound(AUD_SEntry *entry, AUD_Sound *sound)
|
||||
{
|
||||
if (sound)
|
||||
(*entry)->setSound(*sound);
|
||||
@@ -963,7 +971,7 @@ void AUD_updateSequenceSound(AUD_SEntry *entry, AUD_Sound *sound)
|
||||
(*entry)->setSound(AUD_Sound());
|
||||
}
|
||||
|
||||
void AUD_setSequenceAnimData(AUD_SEntry *entry, AUD_AnimateablePropertyType type, int frame, float *data, char animated)
|
||||
void AUD_SequenceEntry_setAnimationData(AUD_SEntry *entry, AUD_AnimateablePropertyType type, int frame, float *data, char animated)
|
||||
{
|
||||
AUD_AnimateableProperty *prop = (*entry)->getAnimProperty(type);
|
||||
if (animated) {
|
||||
@@ -975,7 +983,7 @@ void AUD_setSequenceAnimData(AUD_SEntry *entry, AUD_AnimateablePropertyType type
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_setSequencerAnimData(AUD_Sound *sequencer, AUD_AnimateablePropertyType type, int frame, float *data, char animated)
|
||||
void AUD_Sequence_setAnimationData(AUD_Sound *sequencer, AUD_AnimateablePropertyType type, int frame, float *data, char animated)
|
||||
{
|
||||
AUD_AnimateableProperty *prop = dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->getAnimProperty(type);
|
||||
if (animated) {
|
||||
@@ -988,21 +996,76 @@ void AUD_setSequencerAnimData(AUD_Sound *sequencer, AUD_AnimateablePropertyType
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_updateSequenceData(AUD_SEntry *entry, float volume_max, float volume_min,
|
||||
float distance_max, float distance_reference, float attenuation,
|
||||
float cone_angle_outer, float cone_angle_inner, float cone_volume_outer)
|
||||
void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value)
|
||||
{
|
||||
(*entry)->updateAll(volume_max, volume_min, distance_max, distance_reference, attenuation,
|
||||
cone_angle_outer, cone_angle_inner, cone_volume_outer);
|
||||
assert(sequence);
|
||||
dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setDistanceModel(static_cast<AUD_DistanceModel>(value));
|
||||
}
|
||||
|
||||
void AUD_updateSequencerData(AUD_Sound *sequencer, float speed_of_sound,
|
||||
float factor, AUD_DistanceModel model)
|
||||
void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value)
|
||||
{
|
||||
AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sequencer->get());
|
||||
f->setSpeedOfSound(speed_of_sound);
|
||||
f->setDopplerFactor(factor);
|
||||
f->setDistanceModel(model);
|
||||
assert(sequence);
|
||||
dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setDopplerFactor(value);
|
||||
}
|
||||
|
||||
void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value)
|
||||
{
|
||||
assert(sequence);
|
||||
dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setSpeedOfSound(value);
|
||||
}
|
||||
|
||||
void AUD_SequenceEntry_setAttenuation(AUD_SEntry* sequence_entry, float value)
|
||||
{
|
||||
assert(sequence_entry);
|
||||
(*sequence_entry)->setAttenuation(value);
|
||||
}
|
||||
|
||||
void AUD_SequenceEntry_setConeAngleInner(AUD_SEntry* sequence_entry, float value)
|
||||
{
|
||||
assert(sequence_entry);
|
||||
(*sequence_entry)->setConeAngleInner(value);
|
||||
}
|
||||
|
||||
void AUD_SequenceEntry_setConeAngleOuter(AUD_SEntry* sequence_entry, float value)
|
||||
{
|
||||
assert(sequence_entry);
|
||||
(*sequence_entry)->setConeAngleOuter(value);
|
||||
}
|
||||
|
||||
void AUD_SequenceEntry_setConeVolumeOuter(AUD_SEntry* sequence_entry, float value)
|
||||
{
|
||||
assert(sequence_entry);
|
||||
(*sequence_entry)->setConeVolumeOuter(value);
|
||||
}
|
||||
|
||||
void AUD_SequenceEntry_setDistanceMaximum(AUD_SEntry* sequence_entry, float value)
|
||||
{
|
||||
assert(sequence_entry);
|
||||
(*sequence_entry)->setDistanceMaximum(value);
|
||||
}
|
||||
|
||||
void AUD_SequenceEntry_setDistanceReference(AUD_SEntry* sequence_entry, float value)
|
||||
{
|
||||
assert(sequence_entry);
|
||||
(*sequence_entry)->setDistanceReference(value);
|
||||
}
|
||||
|
||||
void AUD_SequenceEntry_setRelative(AUD_SEntry* sequence_entry, int value)
|
||||
{
|
||||
assert(sequence_entry);
|
||||
(*sequence_entry)->setRelative(value);
|
||||
}
|
||||
|
||||
void AUD_SequenceEntry_setVolumeMaximum(AUD_SEntry* sequence_entry, float value)
|
||||
{
|
||||
assert(sequence_entry);
|
||||
(*sequence_entry)->setVolumeMaximum(value);
|
||||
}
|
||||
|
||||
void AUD_SequenceEntry_setVolumeMinimum(AUD_SEntry* sequence_entry, float value)
|
||||
{
|
||||
assert(sequence_entry);
|
||||
(*sequence_entry)->setVolumeMinimum(value);
|
||||
}
|
||||
|
||||
void AUD_setSequencerDeviceSpecs(AUD_Sound *sequencer)
|
||||
@@ -1010,12 +1073,12 @@ void AUD_setSequencerDeviceSpecs(AUD_Sound *sequencer)
|
||||
dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setSpecs(AUD_device->getSpecs().specs);
|
||||
}
|
||||
|
||||
void AUD_setSequencerSpecs(AUD_Sound *sequencer, AUD_Specs specs)
|
||||
void AUD_Sequence_setSpecs(AUD_Sound *sequencer, AUD_Specs specs)
|
||||
{
|
||||
dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setSpecs(specs);
|
||||
}
|
||||
|
||||
void AUD_seekSequencer(AUD_Handle *handle, float time)
|
||||
void AUD_seekSynchronizer(AUD_Handle *handle, float time)
|
||||
{
|
||||
#ifdef WITH_JACK
|
||||
AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
|
||||
@@ -1030,7 +1093,7 @@ void AUD_seekSequencer(AUD_Handle *handle, float time)
|
||||
}
|
||||
}
|
||||
|
||||
float AUD_getSequencerPosition(AUD_Handle *handle)
|
||||
float AUD_getSynchronizerPosition(AUD_Handle *handle)
|
||||
{
|
||||
#ifdef WITH_JACK
|
||||
AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
|
||||
@@ -1045,7 +1108,7 @@ float AUD_getSequencerPosition(AUD_Handle *handle)
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_startPlayback()
|
||||
void AUD_playSynchronizer()
|
||||
{
|
||||
#ifdef WITH_JACK
|
||||
AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
|
||||
@@ -1055,7 +1118,7 @@ void AUD_startPlayback()
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUD_stopPlayback()
|
||||
void AUD_stopSynchronizer()
|
||||
{
|
||||
#ifdef WITH_JACK
|
||||
AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
|
||||
@@ -1066,7 +1129,7 @@ void AUD_stopPlayback()
|
||||
}
|
||||
|
||||
#ifdef WITH_JACK
|
||||
void AUD_setSyncCallback(AUD_syncFunction function, void *data)
|
||||
void AUD_setSynchronizerCallback(AUD_syncFunction function, void *data)
|
||||
{
|
||||
AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
|
||||
if (device) {
|
||||
@@ -1075,7 +1138,7 @@ void AUD_setSyncCallback(AUD_syncFunction function, void *data)
|
||||
}
|
||||
#endif
|
||||
|
||||
int AUD_doesPlayback()
|
||||
int AUD_isSynchronizerPlaying()
|
||||
{
|
||||
#ifdef WITH_JACK
|
||||
AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
|
||||
@@ -1151,12 +1214,12 @@ int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_pe
|
||||
return length;
|
||||
}
|
||||
|
||||
AUD_Sound *AUD_copy(AUD_Sound *sound)
|
||||
AUD_Sound *AUD_Sound_copy(AUD_Sound *sound)
|
||||
{
|
||||
return new boost::shared_ptr<AUD_IFactory>(*sound);
|
||||
}
|
||||
|
||||
void AUD_freeHandle(AUD_Handle *handle)
|
||||
void AUD_Handle_free(AUD_Handle *handle)
|
||||
{
|
||||
delete handle;
|
||||
}
|
||||
@@ -1283,14 +1346,9 @@ AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *sequencer, f
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<AUD_IDevice> AUD_getDevice()
|
||||
AUD_Device *AUD_Device_getCurrent(void)
|
||||
{
|
||||
return AUD_device;
|
||||
}
|
||||
|
||||
AUD_I3DDevice *AUD_get3DDevice()
|
||||
{
|
||||
return AUD_3ddevice;
|
||||
return &AUD_device;
|
||||
}
|
||||
|
||||
int AUD_isJackSupported(void)
|
||||
|
@@ -77,22 +77,26 @@ extern void AUD_exitOnce(void);
|
||||
* \param buffersize The buffersize for the device.
|
||||
* \return Whether the device has been initialized.
|
||||
*/
|
||||
extern int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize);
|
||||
extern AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name);
|
||||
|
||||
/**
|
||||
* Unitinitializes an audio device.
|
||||
*/
|
||||
extern void AUD_exit(void);
|
||||
extern void AUD_exit(AUD_Device* device);
|
||||
|
||||
/**
|
||||
* Locks the playback device.
|
||||
*/
|
||||
extern void AUD_lock(void);
|
||||
extern void AUD_Device_lock(AUD_Device* device);
|
||||
|
||||
/**
|
||||
* Unlocks the device.
|
||||
*/
|
||||
extern void AUD_unlock(void);
|
||||
extern void AUD_Device_unlock(AUD_Device* device);
|
||||
|
||||
extern AUD_Channels AUD_Device_getChannels(AUD_Device* device);
|
||||
|
||||
extern AUD_SampleRate AUD_Device_getRate(AUD_Device* device);
|
||||
|
||||
/**
|
||||
* Returns information about a sound.
|
||||
@@ -106,7 +110,7 @@ extern AUD_SoundInfo AUD_getInfo(AUD_Sound *sound);
|
||||
* \param filename The filename of the sound file.
|
||||
* \return A handle of the sound file.
|
||||
*/
|
||||
extern AUD_Sound *AUD_load(const char *filename);
|
||||
extern AUD_Sound *AUD_Sound_file(const char *filename);
|
||||
|
||||
/**
|
||||
* Loads a sound file.
|
||||
@@ -114,21 +118,21 @@ extern AUD_Sound *AUD_load(const char *filename);
|
||||
* \param size The size of the buffer.
|
||||
* \return A handle of the sound file.
|
||||
*/
|
||||
extern AUD_Sound *AUD_loadBuffer(unsigned char *buffer, int size);
|
||||
extern AUD_Sound *AUD_Sound_bufferFile(unsigned char *buffer, int size);
|
||||
|
||||
/**
|
||||
* Buffers a sound.
|
||||
* \param sound The sound to buffer.
|
||||
* \return A handle of the sound buffer.
|
||||
*/
|
||||
extern AUD_Sound *AUD_bufferSound(AUD_Sound *sound);
|
||||
extern AUD_Sound *AUD_Sound_cache(AUD_Sound *sound);
|
||||
|
||||
/**
|
||||
* Rechannels the sound to be mono.
|
||||
* \param sound The sound to rechannel.
|
||||
* \return The mono sound.
|
||||
*/
|
||||
extern AUD_Sound *AUD_monoSound(AUD_Sound *sound);
|
||||
extern AUD_Sound *AUD_Sound_rechannel(AUD_Sound *sound, AUD_Channels channels);
|
||||
|
||||
/**
|
||||
* Delays a sound.
|
||||
@@ -136,7 +140,7 @@ extern AUD_Sound *AUD_monoSound(AUD_Sound *sound);
|
||||
* \param delay The delay in seconds.
|
||||
* \return A handle of the delayed sound.
|
||||
*/
|
||||
extern AUD_Sound *AUD_delaySound(AUD_Sound *sound, float delay);
|
||||
extern AUD_Sound *AUD_Sound_delay(AUD_Sound *sound, float delay);
|
||||
|
||||
/**
|
||||
* Limits a sound.
|
||||
@@ -145,21 +149,21 @@ extern AUD_Sound *AUD_delaySound(AUD_Sound *sound, float delay);
|
||||
* \param end The stop time in seconds.
|
||||
* \return A handle of the limited sound.
|
||||
*/
|
||||
extern AUD_Sound *AUD_limitSound(AUD_Sound *sound, float start, float end);
|
||||
extern AUD_Sound *AUD_Sound_limit(AUD_Sound *sound, float start, float end);
|
||||
|
||||
/**
|
||||
* Ping pongs a sound.
|
||||
* \param sound The sound to ping pong.
|
||||
* \return A handle of the ping pong sound.
|
||||
*/
|
||||
extern AUD_Sound *AUD_pingpongSound(AUD_Sound *sound);
|
||||
extern AUD_Sound *AUD_Sound_pingpong(AUD_Sound *sound);
|
||||
|
||||
/**
|
||||
* Loops a sound.
|
||||
* \param sound The sound to loop.
|
||||
* \return A handle of the looped sound.
|
||||
*/
|
||||
extern AUD_Sound *AUD_loopSound(AUD_Sound *sound);
|
||||
extern AUD_Sound *AUD_Sound_loop(AUD_Sound *sound);
|
||||
|
||||
/**
|
||||
* Sets a remaining loop count of a looping sound that currently plays.
|
||||
@@ -167,7 +171,7 @@ extern AUD_Sound *AUD_loopSound(AUD_Sound *sound);
|
||||
* \param loops The count of remaining loops, -1 for infinity.
|
||||
* \return Whether the handle is valid.
|
||||
*/
|
||||
extern int AUD_setLoop(AUD_Handle *handle, int loops);
|
||||
extern int AUD_Handle_setLoopCount(AUD_Handle *handle, int loops);
|
||||
|
||||
/**
|
||||
* Rectifies a sound.
|
||||
@@ -180,7 +184,7 @@ extern AUD_Sound *AUD_rectifySound(AUD_Sound *sound);
|
||||
* Unloads a sound of any type.
|
||||
* \param sound The handle of the sound.
|
||||
*/
|
||||
extern void AUD_unload(AUD_Sound *sound);
|
||||
extern void AUD_Sound_free(AUD_Sound *sound);
|
||||
|
||||
/**
|
||||
* Plays back a sound file.
|
||||
@@ -189,28 +193,30 @@ extern void AUD_unload(AUD_Sound *sound);
|
||||
* paused when its end has been reached.
|
||||
* \return A handle to the played back sound.
|
||||
*/
|
||||
extern AUD_Handle *AUD_play(AUD_Sound *sound, int keep);
|
||||
extern AUD_Handle *AUD_Device_play(AUD_Device* device, AUD_Sound *sound, int keep);
|
||||
|
||||
/**
|
||||
* Pauses a played back sound.
|
||||
* \param handle The handle to the sound.
|
||||
* \return Whether the handle has been playing or not.
|
||||
*/
|
||||
extern int AUD_pause(AUD_Handle *handle);
|
||||
extern int AUD_Handle_pause(AUD_Handle *handle);
|
||||
|
||||
/**
|
||||
* Resumes a paused sound.
|
||||
* \param handle The handle to the sound.
|
||||
* \return Whether the handle has been paused or not.
|
||||
*/
|
||||
extern int AUD_resume(AUD_Handle *handle);
|
||||
extern int AUD_Handle_resume(AUD_Handle *handle);
|
||||
|
||||
/**
|
||||
* Stops a playing or paused sound.
|
||||
* \param handle The handle to the sound.
|
||||
* \return Whether the handle has been valid or not.
|
||||
*/
|
||||
extern int AUD_stop(AUD_Handle *handle);
|
||||
extern int AUD_Handle_stop(AUD_Handle *handle);
|
||||
|
||||
extern void AUD_Device_stopAll(void* device);
|
||||
|
||||
/**
|
||||
* Sets the end behaviour of a playing or paused sound.
|
||||
@@ -219,7 +225,7 @@ extern int AUD_stop(AUD_Handle *handle);
|
||||
* paused when its end has been reached.
|
||||
* \return Whether the handle has been valid or not.
|
||||
*/
|
||||
extern int AUD_setKeep(AUD_Handle *handle, int keep);
|
||||
extern int AUD_Handle_setKeep(AUD_Handle *handle, int keep);
|
||||
|
||||
/**
|
||||
* Seeks a playing or paused sound.
|
||||
@@ -227,7 +233,7 @@ extern int AUD_setKeep(AUD_Handle *handle, int keep);
|
||||
* \param seekTo From where the sound file should be played back in seconds.
|
||||
* \return Whether the handle has been valid or not.
|
||||
*/
|
||||
extern int AUD_seek(AUD_Handle *handle, float seekTo);
|
||||
extern int AUD_Handle_setPosition(AUD_Handle *handle, float seekTo);
|
||||
|
||||
/**
|
||||
* Retrieves the playback position of a handle.
|
||||
@@ -235,39 +241,39 @@ extern int AUD_seek(AUD_Handle *handle, float seekTo);
|
||||
* \return The current playback position in seconds or 0.0 if the handle is
|
||||
* invalid.
|
||||
*/
|
||||
extern float AUD_getPosition(AUD_Handle *handle);
|
||||
extern float AUD_Handle_getPosition(AUD_Handle *handle);
|
||||
|
||||
/**
|
||||
* Returns the status of a playing, paused or stopped sound.
|
||||
* \param handle The handle to the sound.
|
||||
* \return The status of the sound behind the handle.
|
||||
*/
|
||||
extern AUD_Status AUD_getStatus(AUD_Handle *handle);
|
||||
extern AUD_Status AUD_Handle_getStatus(AUD_Handle *handle);
|
||||
|
||||
/**
|
||||
* Sets the listener location.
|
||||
* \param location The new location.
|
||||
*/
|
||||
extern int AUD_setListenerLocation(const float location[3]);
|
||||
extern int AUD_Device_setListenerLocation(const float location[3]);
|
||||
|
||||
/**
|
||||
* Sets the listener velocity.
|
||||
* \param velocity The new velocity.
|
||||
*/
|
||||
extern int AUD_setListenerVelocity(const float velocity[3]);
|
||||
extern int AUD_Device_setListenerVelocity(const float velocity[3]);
|
||||
|
||||
/**
|
||||
* Sets the listener orientation.
|
||||
* \param orientation The new orientation as quaternion.
|
||||
*/
|
||||
extern int AUD_setListenerOrientation(const float orientation[4]);
|
||||
extern int AUD_Device_setListenerOrientation(const float orientation[4]);
|
||||
|
||||
/**
|
||||
* Sets the speed of sound.
|
||||
* This value is needed for doppler effect calculation.
|
||||
* \param speed The new speed of sound.
|
||||
*/
|
||||
extern int AUD_setSpeedOfSound(float speed);
|
||||
extern int AUD_Device_setSpeedOfSound(void* device, float speed);
|
||||
|
||||
/**
|
||||
* Sets the doppler factor.
|
||||
@@ -275,13 +281,13 @@ extern int AUD_setSpeedOfSound(float speed);
|
||||
* listener which is used while calculating the doppler effect.
|
||||
* \param factor The new doppler factor.
|
||||
*/
|
||||
extern int AUD_setDopplerFactor(float factor);
|
||||
extern int AUD_Device_setDopplerFactor(void* device, float factor);
|
||||
|
||||
/**
|
||||
* Sets the distance model.
|
||||
* \param model distance model.
|
||||
*/
|
||||
extern int AUD_setDistanceModel(AUD_DistanceModel model);
|
||||
extern int AUD_Device_setDistanceModel(void* device, AUD_DistanceModel model);
|
||||
|
||||
/**
|
||||
* Sets the location of a source.
|
||||
@@ -289,7 +295,7 @@ extern int AUD_setDistanceModel(AUD_DistanceModel model);
|
||||
* \param location The new location.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setSourceLocation(AUD_Handle *handle, const float location[3]);
|
||||
extern int AUD_Handle_setLocation(AUD_Handle *handle, const float location[3]);
|
||||
|
||||
/**
|
||||
* Sets the velocity of a source.
|
||||
@@ -297,7 +303,7 @@ extern int AUD_setSourceLocation(AUD_Handle *handle, const float location[3]);
|
||||
* \param velocity The new velocity.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setSourceVelocity(AUD_Handle *handle, const float velocity[3]);
|
||||
extern int AUD_Handle_setVelocity(AUD_Handle *handle, const float velocity[3]);
|
||||
|
||||
/**
|
||||
* Sets the orientation of a source.
|
||||
@@ -305,7 +311,7 @@ extern int AUD_setSourceVelocity(AUD_Handle *handle, const float velocity[3]);
|
||||
* \param orientation The new orientation as quaternion.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setSourceOrientation(AUD_Handle *handle, const float orientation[4]);
|
||||
extern int AUD_Handle_setOrientation(AUD_Handle *handle, const float orientation[4]);
|
||||
|
||||
/**
|
||||
* Sets whether the source location, velocity and orientation are relative
|
||||
@@ -314,7 +320,7 @@ extern int AUD_setSourceOrientation(AUD_Handle *handle, const float orientation[
|
||||
* \param relative Whether the source is relative.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setRelative(AUD_Handle *handle, int relative);
|
||||
extern int AUD_Handle_setRelative(AUD_Handle *handle, int relative);
|
||||
|
||||
/**
|
||||
* Sets the maximum volume of a source.
|
||||
@@ -322,7 +328,7 @@ extern int AUD_setRelative(AUD_Handle *handle, int relative);
|
||||
* \param volume The new maximum volume.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setVolumeMaximum(AUD_Handle *handle, float volume);
|
||||
extern int AUD_Handle_setVolumeMaximum(AUD_Handle *handle, float volume);
|
||||
|
||||
/**
|
||||
* Sets the minimum volume of a source.
|
||||
@@ -330,7 +336,7 @@ extern int AUD_setVolumeMaximum(AUD_Handle *handle, float volume);
|
||||
* \param volume The new minimum volume.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setVolumeMinimum(AUD_Handle *handle, float volume);
|
||||
extern int AUD_Handle_setVolumeMinimum(AUD_Handle *handle, float volume);
|
||||
|
||||
/**
|
||||
* Sets the maximum distance of a source.
|
||||
@@ -340,7 +346,7 @@ extern int AUD_setVolumeMinimum(AUD_Handle *handle, float volume);
|
||||
* \param distance The new maximum distance.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setDistanceMaximum(AUD_Handle *handle, float distance);
|
||||
extern int AUD_Handle_setDistanceMaximum(AUD_Handle *handle, float distance);
|
||||
|
||||
/**
|
||||
* Sets the reference distance of a source.
|
||||
@@ -348,7 +354,7 @@ extern int AUD_setDistanceMaximum(AUD_Handle *handle, float distance);
|
||||
* \param distance The new reference distance.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setDistanceReference(AUD_Handle *handle, float distance);
|
||||
extern int AUD_Handle_setDistanceReference(AUD_Handle *handle, float distance);
|
||||
|
||||
/**
|
||||
* Sets the attenuation of a source.
|
||||
@@ -357,7 +363,7 @@ extern int AUD_setDistanceReference(AUD_Handle *handle, float distance);
|
||||
* \param factor The new attenuation.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setAttenuation(AUD_Handle *handle, float factor);
|
||||
extern int AUD_Handle_setAttenuation(AUD_Handle *handle, float factor);
|
||||
|
||||
/**
|
||||
* Sets the outer angle of the cone of a source.
|
||||
@@ -365,7 +371,7 @@ extern int AUD_setAttenuation(AUD_Handle *handle, float factor);
|
||||
* \param angle The new outer angle of the cone.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setConeAngleOuter(AUD_Handle *handle, float angle);
|
||||
extern int AUD_Handle_setConeAngleOuter(AUD_Handle *handle, float angle);
|
||||
|
||||
/**
|
||||
* Sets the inner angle of the cone of a source.
|
||||
@@ -373,7 +379,7 @@ extern int AUD_setConeAngleOuter(AUD_Handle *handle, float angle);
|
||||
* \param angle The new inner angle of the cone.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setConeAngleInner(AUD_Handle *handle, float angle);
|
||||
extern int AUD_Handle_setConeAngleInner(AUD_Handle *handle, float angle);
|
||||
|
||||
/**
|
||||
* Sets the outer volume of the cone of a source.
|
||||
@@ -383,7 +389,7 @@ extern int AUD_setConeAngleInner(AUD_Handle *handle, float angle);
|
||||
* \param volume The new outer volume of the cone.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setConeVolumeOuter(AUD_Handle *handle, float volume);
|
||||
extern int AUD_Handle_setConeVolumeOuter(AUD_Handle *handle, float volume);
|
||||
|
||||
/**
|
||||
* Sets the volume of a played back sound.
|
||||
@@ -391,7 +397,7 @@ extern int AUD_setConeVolumeOuter(AUD_Handle *handle, float volume);
|
||||
* \param volume The new volume, must be between 0.0 and 1.0.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setSoundVolume(AUD_Handle *handle, float volume);
|
||||
extern int AUD_Handle_setVolume(AUD_Handle *handle, float volume);
|
||||
|
||||
/**
|
||||
* Sets the pitch of a played back sound.
|
||||
@@ -399,7 +405,7 @@ extern int AUD_setSoundVolume(AUD_Handle *handle, float volume);
|
||||
* \param pitch The new pitch.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setSoundPitch(AUD_Handle *handle, float pitch);
|
||||
extern int AUD_Handle_setPitch(AUD_Handle *handle, float pitch);
|
||||
|
||||
/**
|
||||
* Opens a read device, with which audio data can be read.
|
||||
@@ -434,13 +440,13 @@ extern AUD_Handle *AUD_playDevice(AUD_Device *device, AUD_Sound *sound, float se
|
||||
* played back currently, in that case the buffer is filled with
|
||||
* silence.
|
||||
*/
|
||||
extern int AUD_readDevice(AUD_Device *device, data_t *buffer, int length);
|
||||
extern int AUD_Device_read(AUD_Device *device, data_t *buffer, int length);
|
||||
|
||||
/**
|
||||
* Closes a read device.
|
||||
* \param device The read device.
|
||||
*/
|
||||
extern void AUD_closeReadDevice(AUD_Device *device);
|
||||
extern void AUD_Device_free(AUD_Device *device);
|
||||
|
||||
/**
|
||||
* Reads a sound file into a newly created float buffer.
|
||||
@@ -466,27 +472,27 @@ extern AUD_Handle *AUD_pauseAfter(AUD_Handle *handle, float seconds);
|
||||
* \param muted Whether the scene is muted.
|
||||
* \return The new sound scene.
|
||||
*/
|
||||
extern AUD_Sound *AUD_createSequencer(float fps, int muted);
|
||||
extern AUD_Sound *AUD_Sequence_create(float fps, int muted);
|
||||
|
||||
/**
|
||||
* Deletes a sound scene.
|
||||
* \param sequencer The sound scene.
|
||||
*/
|
||||
extern void AUD_destroySequencer(AUD_Sound *sequencer);
|
||||
extern void AUD_Sequence_free(AUD_Sound *sequencer);
|
||||
|
||||
/**
|
||||
* Sets the muting state of the scene.
|
||||
* \param sequencer The sound scene.
|
||||
* \param muted Whether the scene is muted.
|
||||
*/
|
||||
extern void AUD_setSequencerMuted(AUD_Sound *sequencer, int muted);
|
||||
extern void AUD_Sequence_setMuted(AUD_Sound *sequencer, int muted);
|
||||
|
||||
/**
|
||||
* Sets the scene's FPS.
|
||||
* \param sequencer The sound scene.
|
||||
* \param fps The new FPS.
|
||||
*/
|
||||
extern void AUD_setSequencerFPS(AUD_Sound *sequencer, float fps);
|
||||
extern void AUD_Sequence_setFPS(AUD_Sound *sequencer, float fps);
|
||||
|
||||
/**
|
||||
* Adds a new entry to the scene.
|
||||
@@ -497,7 +503,7 @@ extern void AUD_setSequencerFPS(AUD_Sound *sequencer, float fps);
|
||||
* \param skip How much seconds should be skipped at the beginning.
|
||||
* \return The entry added.
|
||||
*/
|
||||
extern AUD_SEntry *AUD_addSequence(AUD_Sound *sequencer, AUD_Sound *sound,
|
||||
extern AUD_SEntry *AUD_Sequence_add(AUD_Sound *sequencer, AUD_Sound *sound,
|
||||
float begin, float end, float skip);
|
||||
|
||||
/**
|
||||
@@ -505,7 +511,7 @@ extern AUD_SEntry *AUD_addSequence(AUD_Sound *sequencer, AUD_Sound *sound,
|
||||
* \param sequencer The sound scene.
|
||||
* \param entry The entry to remove.
|
||||
*/
|
||||
extern void AUD_removeSequence(AUD_Sound *sequencer, AUD_SEntry *entry);
|
||||
extern void AUD_Sequence_remove(AUD_Sound *sequencer, AUD_SEntry *entry);
|
||||
|
||||
/**
|
||||
* Moves the entry.
|
||||
@@ -514,30 +520,21 @@ extern void AUD_removeSequence(AUD_Sound *sequencer, AUD_SEntry *entry);
|
||||
* \param end The new end time or a negative value if unknown.
|
||||
* \param skip How many seconds to skip at the beginning.
|
||||
*/
|
||||
extern void AUD_moveSequence(AUD_SEntry *entry, float begin, float end, float skip);
|
||||
extern void AUD_SequenceEntry_move(AUD_SEntry *entry, float begin, float end, float skip);
|
||||
|
||||
/**
|
||||
* Sets the muting state of the entry.
|
||||
* \param entry The sequenced entry.
|
||||
* \param mute Whether the entry should be muted or not.
|
||||
*/
|
||||
extern void AUD_muteSequence(AUD_SEntry *entry, char mute);
|
||||
|
||||
/**
|
||||
* Sets whether the entrie's location, velocity and orientation are relative
|
||||
* to the listener.
|
||||
* \param entry The sequenced entry.
|
||||
* \param relative Whether the source is relative.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern void AUD_setRelativeSequence(AUD_SEntry *entry, char relative);
|
||||
extern void AUD_SequenceEntry_setMuted(AUD_SEntry *entry, char mute);
|
||||
|
||||
/**
|
||||
* Sets the sound of the entry.
|
||||
* \param entry The sequenced entry.
|
||||
* \param sound The new sound.
|
||||
*/
|
||||
extern void AUD_updateSequenceSound(AUD_SEntry *entry, AUD_Sound *sound);
|
||||
extern void AUD_SequenceEntry_setSound(AUD_SEntry *entry, AUD_Sound *sound);
|
||||
|
||||
/**
|
||||
* Writes animation data to a sequenced entry.
|
||||
@@ -547,7 +544,7 @@ extern void AUD_updateSequenceSound(AUD_SEntry *entry, AUD_Sound *sound);
|
||||
* \param data The data to write.
|
||||
* \param animated Whether the attribute is animated.
|
||||
*/
|
||||
extern void AUD_setSequenceAnimData(AUD_SEntry *entry, AUD_AnimateablePropertyType type, int frame, float *data, char animated);
|
||||
extern void AUD_SequenceEntry_setAnimationData(AUD_SEntry *entry, AUD_AnimateablePropertyType type, int frame, float *data, char animated);
|
||||
|
||||
/**
|
||||
* Writes animation data to a sequenced entry.
|
||||
@@ -557,33 +554,90 @@ extern void AUD_setSequenceAnimData(AUD_SEntry *entry, AUD_AnimateablePropertyTy
|
||||
* \param data The data to write.
|
||||
* \param animated Whether the attribute is animated.
|
||||
*/
|
||||
extern void AUD_setSequencerAnimData(AUD_Sound *sequencer, AUD_AnimateablePropertyType type, int frame, float *data, char animated);
|
||||
extern void AUD_Sequence_setAnimationData(AUD_Sound *sequencer, AUD_AnimateablePropertyType type, int frame, float *data, char animated);
|
||||
|
||||
/**
|
||||
* Updates all non-animated parameters of the entry.
|
||||
* \param entry The sequenced entry.
|
||||
* \param volume_max The maximum volume.
|
||||
* \param volume_min The minimum volume.
|
||||
* \param distance_max The maximum distance.
|
||||
* \param distance_reference The reference distance.
|
||||
* \param attenuation The attenuation.
|
||||
* \param cone_angle_outer The outer cone opening angle.
|
||||
* \param cone_angle_inner The inner cone opening angle.
|
||||
* \param cone_volume_outer The volume outside the outer cone.
|
||||
* Sets the distance model of a sequence.
|
||||
* param sequence The sequence to set the distance model from.
|
||||
* param value The new distance model to set.
|
||||
*/
|
||||
extern void AUD_updateSequenceData(AUD_SEntry *entry, float volume_max, float volume_min,
|
||||
float distance_max, float distance_reference, float attenuation,
|
||||
float cone_angle_outer, float cone_angle_inner, float cone_volume_outer);
|
||||
extern void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value);
|
||||
|
||||
/**
|
||||
* Updates all non-animated parameters of the entry.
|
||||
* \param sequencer The sound scene.
|
||||
* \param speed_of_sound The speed of sound for doppler calculation.
|
||||
* \param factor The doppler factor to control the effect's strength.
|
||||
* \param model The distance model for distance calculation.
|
||||
* Sets the doppler factor of a sequence.
|
||||
* param sequence The sequence to set the doppler factor from.
|
||||
* param value The new doppler factor to set.
|
||||
*/
|
||||
extern void AUD_updateSequencerData(AUD_Sound *sequencer, float speed_of_sound,
|
||||
float factor, AUD_DistanceModel model);
|
||||
extern void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value);
|
||||
|
||||
/**
|
||||
* Sets the speed of sound of a sequence.
|
||||
* param sequence The sequence to set the speed of sound from.
|
||||
* param value The new speed of sound to set.
|
||||
*/
|
||||
extern void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value);
|
||||
/**
|
||||
* Sets the attenuation of a sequence_entry.
|
||||
* param sequence_entry The sequence_entry to set the attenuation from.
|
||||
* param value The new attenuation to set.
|
||||
*/
|
||||
extern void AUD_SequenceEntry_setAttenuation(AUD_SEntry* sequence_entry, float value);
|
||||
|
||||
/**
|
||||
* Sets the cone angle inner of a sequence_entry.
|
||||
* param sequence_entry The sequence_entry to set the cone angle inner from.
|
||||
* param value The new cone angle inner to set.
|
||||
*/
|
||||
extern void AUD_SequenceEntry_setConeAngleInner(AUD_SEntry* sequence_entry, float value);
|
||||
|
||||
/**
|
||||
* Sets the cone angle outer of a sequence_entry.
|
||||
* param sequence_entry The sequence_entry to set the cone angle outer from.
|
||||
* param value The new cone angle outer to set.
|
||||
*/
|
||||
extern void AUD_SequenceEntry_setConeAngleOuter(AUD_SEntry* sequence_entry, float value);
|
||||
|
||||
/**
|
||||
* Sets the cone volume outer of a sequence_entry.
|
||||
* param sequence_entry The sequence_entry to set the cone volume outer from.
|
||||
* param value The new cone volume outer to set.
|
||||
*/
|
||||
extern void AUD_SequenceEntry_setConeVolumeOuter(AUD_SEntry* sequence_entry, float value);
|
||||
|
||||
/**
|
||||
* Sets the distance maximum of a sequence_entry.
|
||||
* param sequence_entry The sequence_entry to set the distance maximum from.
|
||||
* param value The new distance maximum to set.
|
||||
*/
|
||||
extern void AUD_SequenceEntry_setDistanceMaximum(AUD_SEntry* sequence_entry, float value);
|
||||
|
||||
/**
|
||||
* Sets the distance reference of a sequence_entry.
|
||||
* param sequence_entry The sequence_entry to set the distance reference from.
|
||||
* param value The new distance reference to set.
|
||||
*/
|
||||
extern void AUD_SequenceEntry_setDistanceReference(AUD_SEntry* sequence_entry, float value);
|
||||
|
||||
/**
|
||||
* Sets the relative of a sequence_entry.
|
||||
* param sequence_entry The sequence_entry to set the relative from.
|
||||
* param value The new relative to set.
|
||||
*/
|
||||
extern void AUD_SequenceEntry_setRelative(AUD_SEntry* sequence_entry, int value);
|
||||
|
||||
/**
|
||||
* Sets the volume maximum of a sequence_entry.
|
||||
* param sequence_entry The sequence_entry to set the volume maximum from.
|
||||
* param value The new volume maximum to set.
|
||||
*/
|
||||
extern void AUD_SequenceEntry_setVolumeMaximum(AUD_SEntry* sequence_entry, float value);
|
||||
|
||||
/**
|
||||
* Sets the volume minimum of a sequence_entry.
|
||||
* param sequence_entry The sequence_entry to set the volume minimum from.
|
||||
* param value The new volume minimum to set.
|
||||
*/
|
||||
extern void AUD_SequenceEntry_setVolumeMinimum(AUD_SEntry* sequence_entry, float value);
|
||||
|
||||
/**
|
||||
* Sets the audio output specification of the sound scene to the specs of the
|
||||
@@ -597,31 +651,31 @@ extern void AUD_setSequencerDeviceSpecs(AUD_Sound *sequencer);
|
||||
* \param sequencer The sound scene.
|
||||
* \param specs The new specification.
|
||||
*/
|
||||
extern void AUD_setSequencerSpecs(AUD_Sound *sequencer, AUD_Specs specs);
|
||||
extern void AUD_Sequence_setSpecs(AUD_Sound *sequencer, AUD_Specs specs);
|
||||
|
||||
/**
|
||||
* Seeks sequenced sound scene playback.
|
||||
* \param handle Playback handle.
|
||||
* \param time Time in seconds to seek to.
|
||||
*/
|
||||
extern void AUD_seekSequencer(AUD_Handle *handle, float time);
|
||||
extern void AUD_seekSynchronizer(AUD_Handle *handle, float time);
|
||||
|
||||
/**
|
||||
* Returns the current sound scene playback time.
|
||||
* \param handle Playback handle.
|
||||
* \return The playback time in seconds.
|
||||
*/
|
||||
extern float AUD_getSequencerPosition(AUD_Handle *handle);
|
||||
extern float AUD_getSynchronizerPosition(AUD_Handle *handle);
|
||||
|
||||
/**
|
||||
* Starts the playback of jack transport if possible.
|
||||
*/
|
||||
extern void AUD_startPlayback(void);
|
||||
extern void AUD_playSynchronizer(void);
|
||||
|
||||
/**
|
||||
* Stops the playback of jack transport if possible.
|
||||
*/
|
||||
extern void AUD_stopPlayback(void);
|
||||
extern void AUD_stopSynchronizer(void);
|
||||
|
||||
#ifdef WITH_JACK
|
||||
/**
|
||||
@@ -629,14 +683,14 @@ extern void AUD_stopPlayback(void);
|
||||
* \param function The callback function.
|
||||
* \param data The data parameter for the callback.
|
||||
*/
|
||||
extern void AUD_setSyncCallback(AUD_syncFunction function, void *data);
|
||||
extern void AUD_setSynchronizerCallback(AUD_syncFunction function, void *data);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns whether jack transport is currently playing.
|
||||
* \return Whether jack transport is currently playing.
|
||||
*/
|
||||
extern int AUD_doesPlayback(void);
|
||||
extern int AUD_isSynchronizerPlaying(void);
|
||||
|
||||
/**
|
||||
* Reads a sound into a buffer for drawing at a specific sampling rate.
|
||||
@@ -653,13 +707,13 @@ extern int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int sam
|
||||
* \param sound Sound to copy.
|
||||
* \return Copied sound.
|
||||
*/
|
||||
extern AUD_Sound *AUD_copy(AUD_Sound *sound);
|
||||
extern AUD_Sound *AUD_Sound_copy(AUD_Sound *sound);
|
||||
|
||||
/**
|
||||
* Frees a handle.
|
||||
* \param channel Handle to free.
|
||||
*/
|
||||
extern void AUD_freeHandle(AUD_Handle *channel);
|
||||
extern void AUD_Handle_free(AUD_Handle *channel);
|
||||
|
||||
/**
|
||||
* Creates a new set.
|
||||
@@ -747,36 +801,22 @@ extern AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *seque
|
||||
* \param sound The sound factory.
|
||||
* \return The python factory.
|
||||
*/
|
||||
extern void *AUD_getPythonFactory(AUD_Sound *sound);
|
||||
extern void *AUD_getPythonSound(AUD_Sound *sound);
|
||||
|
||||
/**
|
||||
* Retrieves the sound factory of a python factory.
|
||||
* \param sound The python factory.
|
||||
* \return The sound factory.
|
||||
*/
|
||||
extern AUD_Sound *AUD_getPythonSound(void *sound);
|
||||
extern AUD_Sound *AUD_getSoundFromPython(void *sound);
|
||||
#endif
|
||||
|
||||
extern AUD_Device *AUD_Device_getCurrent(void);
|
||||
|
||||
extern int AUD_isJackSupported(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
class AUD_IDevice;
|
||||
class AUD_I3DDevice;
|
||||
|
||||
/**
|
||||
* Returns the current playback device.
|
||||
* \return The playback device.
|
||||
*/
|
||||
boost::shared_ptr<AUD_IDevice> AUD_getDevice();
|
||||
|
||||
/**
|
||||
* Returns the current playback 3D device.
|
||||
* \return The playback 3D device.
|
||||
*/
|
||||
AUD_I3DDevice *AUD_get3DDevice();
|
||||
#endif
|
||||
|
||||
#endif //__AUD_C_API_H__
|
||||
|
@@ -33,16 +33,7 @@
|
||||
#include "AUD_Space.h"
|
||||
|
||||
#include <cstring>
|
||||
#ifdef _MSC_VER
|
||||
#if (_MSC_VER <= 1500)
|
||||
typedef short int16_t;
|
||||
typedef int int32_t;
|
||||
#else
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
typedef void (*AUD_convert_f)(data_t* target, data_t* source, int length);
|
||||
|
||||
|
78
intern/audaspace/intern/AUD_PyInit.cpp
Normal file
78
intern/audaspace/intern/AUD_PyInit.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009-2011 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* Audaspace is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Audaspace; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file audaspace/intern/AUD_PyInit.cpp
|
||||
* \ingroup audaspaceintern
|
||||
*/
|
||||
|
||||
#include "AUD_PyInit.h"
|
||||
|
||||
#include <AUD_Sound.h>
|
||||
#include <python/PySound.h>
|
||||
#include <python/PyAPI.h>
|
||||
|
||||
extern "C" {
|
||||
extern void *BKE_sound_get_factory(void *sound);
|
||||
}
|
||||
|
||||
static PyObject *AUD_getSoundFromPointer(PyObject *self, PyObject *args)
|
||||
{
|
||||
long int lptr;
|
||||
|
||||
if (PyArg_Parse(args, "l:_sound_from_pointer", &lptr)) {
|
||||
if (lptr) {
|
||||
AUD_Sound* sound = BKE_sound_get_factory((void *) lptr);
|
||||
|
||||
if (sound) {
|
||||
Sound *obj = (Sound *)Sound_empty();
|
||||
if (obj) {
|
||||
obj->sound = AUD_Sound_copy(sound);
|
||||
return (PyObject *) obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef meth_sound_from_pointer[] = {
|
||||
{"_sound_from_pointer", (PyCFunction)AUD_getSoundFromPointer, METH_O,
|
||||
"_sound_from_pointer(pointer)\n\n"
|
||||
"Returns the corresponding :class:`Factory` object.\n\n"
|
||||
":arg pointer: The pointer to the bSound object as long.\n"
|
||||
":type pointer: long\n"
|
||||
":return: The corresponding :class:`Factory` object.\n"
|
||||
":rtype: :class:`Factory`"}
|
||||
};
|
||||
|
||||
PyObject *AUD_initPython(void)
|
||||
{
|
||||
PyObject *module = PyInit_aud();
|
||||
PyModule_AddObject(module, "_sound_from_pointer", (PyObject *)PyCFunction_New(meth_sound_from_pointer, NULL));
|
||||
PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
|
||||
|
||||
return module;
|
||||
}
|
||||
|
69
intern/audaspace/intern/AUD_Set.cpp
Normal file
69
intern/audaspace/intern/AUD_Set.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009-2011 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* Audaspace is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Audaspace; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file audaspace/intern/AUD_Set.cpp
|
||||
* \ingroup audaspaceintern
|
||||
*/
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "AUD_Set.h"
|
||||
|
||||
void *AUD_createSet()
|
||||
{
|
||||
return new std::set<void *>();
|
||||
}
|
||||
|
||||
void AUD_destroySet(void *set)
|
||||
{
|
||||
delete reinterpret_cast<std::set<void *>*>(set);
|
||||
}
|
||||
|
||||
char AUD_removeSet(void *set, void *entry)
|
||||
{
|
||||
if (set)
|
||||
return reinterpret_cast<std::set<void *>*>(set)->erase(entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AUD_addSet(void *set, void *entry)
|
||||
{
|
||||
if (entry)
|
||||
reinterpret_cast<std::set<void *>*>(set)->insert(entry);
|
||||
}
|
||||
|
||||
void *AUD_getSet(void *set)
|
||||
{
|
||||
if (set) {
|
||||
std::set<void *>* rset = reinterpret_cast<std::set<void *>*>(set);
|
||||
if (!rset->empty()) {
|
||||
std::set<void *>::iterator it = rset->begin();
|
||||
void *result = *it;
|
||||
rset->erase(it);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return (void*) 0;
|
||||
}
|
74
intern/audaspace/intern/AUD_Set.h
Normal file
74
intern/audaspace/intern/AUD_Set.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009-2011 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* Audaspace is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Audaspace; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file AUD_Set.h
|
||||
* \ingroup audaspace
|
||||
*/
|
||||
|
||||
#ifndef __AUD_SET_H__
|
||||
#define __AUD_SET_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Creates a new set.
|
||||
* \return The new set.
|
||||
*/
|
||||
extern void *AUD_createSet(void);
|
||||
|
||||
/**
|
||||
* Deletes a set.
|
||||
* \param set The set to delete.
|
||||
*/
|
||||
extern void AUD_destroySet(void *set);
|
||||
|
||||
/**
|
||||
* Removes an entry from a set.
|
||||
* \param set The set work on.
|
||||
* \param entry The entry to remove.
|
||||
* \return Whether the entry was in the set or not.
|
||||
*/
|
||||
extern char AUD_removeSet(void *set, void *entry);
|
||||
|
||||
/**
|
||||
* Adds a new entry to a set.
|
||||
* \param set The set work on.
|
||||
* \param entry The entry to add.
|
||||
*/
|
||||
extern void AUD_addSet(void *set, void *entry);
|
||||
|
||||
/**
|
||||
* Removes one entry from a set and returns it.
|
||||
* \param set The set work on.
|
||||
* \return The entry or NULL if the set is empty.
|
||||
*/
|
||||
extern void *AUD_getSet(void *set);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__AUD_SET_H__
|
@@ -14,6 +14,11 @@ include(cmake/external_libs.cmake)
|
||||
# todo: refactor this code to match scons
|
||||
# note: CXX_HAS_SSE is needed in case passing SSE flags fails altogether (gcc-arm)
|
||||
|
||||
if(WITH_CYCLES_WERROR)
|
||||
ADD_CHECK_C_COMPILER_FLAG(CMAKE_C_FLAGS C_WERROR -Werror)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS C_WERROR -Werror)
|
||||
endif()
|
||||
|
||||
if(NOT WITH_CPU_SSE)
|
||||
set(CXX_HAS_SSE FALSE)
|
||||
set(CXX_HAS_AVX FALSE)
|
||||
@@ -154,23 +159,23 @@ add_definitions(
|
||||
|
||||
TEST_UNORDERED_MAP_SUPPORT()
|
||||
if(HAVE_STD_UNORDERED_MAP_HEADER)
|
||||
if(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
|
||||
add_definitions(-DCYCLES_STD_UNORDERED_MAP)
|
||||
else()
|
||||
if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
|
||||
add_definitions(-DCYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
|
||||
else()
|
||||
add_definitions(-DCYCLES_NO_UNORDERED_MAP)
|
||||
message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
|
||||
endif()
|
||||
endif()
|
||||
if(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
|
||||
add_definitions(-DCYCLES_STD_UNORDERED_MAP)
|
||||
else()
|
||||
if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
|
||||
add_definitions(-DCYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
|
||||
else()
|
||||
add_definitions(-DCYCLES_NO_UNORDERED_MAP)
|
||||
message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
|
||||
add_definitions(-DCYCLES_TR1_UNORDERED_MAP)
|
||||
else()
|
||||
add_definitions(-DCYCLES_NO_UNORDERED_MAP)
|
||||
message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
|
||||
endif()
|
||||
if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
|
||||
add_definitions(-DCYCLES_TR1_UNORDERED_MAP)
|
||||
else()
|
||||
add_definitions(-DCYCLES_NO_UNORDERED_MAP)
|
||||
message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Logging capabilities using GLog library.
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include "background.h"
|
||||
#include "camera.h"
|
||||
#include "film.h"
|
||||
#include "graph.h"
|
||||
@@ -850,6 +851,15 @@ static void xml_read_shader(const XMLReadState& state, pugi::xml_node node)
|
||||
|
||||
static void xml_read_background(const XMLReadState& state, pugi::xml_node node)
|
||||
{
|
||||
/* Background Settings */
|
||||
Background *bg = state.scene->background;
|
||||
|
||||
xml_read_float(&bg->ao_distance, node, "ao_distance");
|
||||
xml_read_float(&bg->ao_factor, node, "ao_factor");
|
||||
|
||||
xml_read_bool(&bg->transparent, node, "transparent");
|
||||
|
||||
/* Background Shader */
|
||||
Shader *shader = state.scene->shaders[state.scene->default_background];
|
||||
|
||||
xml_read_bool(&shader->heterogeneous_volume, node, "heterogeneous_volume");
|
||||
@@ -896,6 +906,7 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
|
||||
|
||||
/* read vertices and polygons, RIB style */
|
||||
vector<float3> P;
|
||||
vector<float> UV;
|
||||
vector<int> verts, nverts;
|
||||
|
||||
xml_read_float3_array(P, node, "P");
|
||||
@@ -967,6 +978,31 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
|
||||
|
||||
index_offset += nverts[i];
|
||||
}
|
||||
|
||||
if(xml_read_float_array(UV, node, "UV")) {
|
||||
ustring name = ustring("UVMap");
|
||||
Attribute *attr = mesh->attributes.add(ATTR_STD_UV, name);
|
||||
float3 *fdata = attr->data_float3();
|
||||
|
||||
/* loop over the triangles */
|
||||
index_offset = 0;
|
||||
for(size_t i = 0; i < nverts.size(); i++) {
|
||||
for(int j = 0; j < nverts[i]-2; j++) {
|
||||
int v0 = verts[index_offset];
|
||||
int v1 = verts[index_offset + j + 1];
|
||||
int v2 = verts[index_offset + j + 2];
|
||||
|
||||
assert(v0*2+1 < (int)UV.size());
|
||||
assert(v1*2+1 < (int)UV.size());
|
||||
assert(v2*2+1 < (int)UV.size());
|
||||
|
||||
fdata[0] = make_float3(UV[v0*2], UV[v0*2+1], 0.0);
|
||||
fdata[1] = make_float3(UV[v1*2], UV[v1*2+1], 0.0);
|
||||
fdata[2] = make_float3(UV[v2*2], UV[v2*2+1], 0.0);
|
||||
fdata += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* temporary for test compatibility */
|
||||
|
@@ -31,10 +31,12 @@ set(SRC
|
||||
blender_session.cpp
|
||||
blender_shader.cpp
|
||||
blender_sync.cpp
|
||||
blender_texture.cpp
|
||||
|
||||
CCL_api.h
|
||||
blender_sync.h
|
||||
blender_session.h
|
||||
blender_texture.h
|
||||
blender_util.h
|
||||
)
|
||||
|
||||
|
@@ -17,11 +17,56 @@
|
||||
# <pep8 compliant>
|
||||
|
||||
|
||||
def _is_using_buggy_driver():
|
||||
import bgl
|
||||
# We need to be conservative here because in multi-GPU systems display card
|
||||
# might be quite old, but others one might be just good.
|
||||
#
|
||||
# So We shouldn't disable possible good dedicated cards just because display
|
||||
# card seems weak. And instead we only blacklist configurations which are
|
||||
# proven to cause problems.
|
||||
if bgl.glGetString(bgl.GL_VENDOR) == "ATI Technologies Inc.":
|
||||
import re
|
||||
version = bgl.glGetString(bgl.GL_VERSION)
|
||||
if version.endswith("Compatibility Profile Context"):
|
||||
# Old HD 4xxx and 5xxx series drivers did not have driver version
|
||||
# in the version string, but thsoe cards do not quite work and
|
||||
# cusing crashes.
|
||||
return True
|
||||
regex = re.compile(".*Compatibility Profile Context ([0-9]+(\.[0-9]+)+)$")
|
||||
if not regex.match(version):
|
||||
# Skip cards like FireGL
|
||||
return False
|
||||
version = regex.sub("\\1", version).split('.')
|
||||
return int(version[0]) == 8
|
||||
return False
|
||||
|
||||
|
||||
def _workaround_buggy_drivers():
|
||||
if _is_using_buggy_driver():
|
||||
import _cycles
|
||||
if hasattr(_cycles, "opencl_disable"):
|
||||
print("Cycles: OpenGL driver known to be buggy, disabling OpenCL platform.")
|
||||
_cycles.opencl_disable()
|
||||
|
||||
def init():
|
||||
import bpy
|
||||
import _cycles
|
||||
import os.path
|
||||
|
||||
# Workaroud posibly buggy legacy drivers which crashes on the OpenCL
|
||||
# device enumeration.
|
||||
#
|
||||
# This checks are not really correct because they might still fail
|
||||
# in the case of multiple GPUs. However, currently buggy drivers
|
||||
# are really old and likely to be used in single GPU systems only
|
||||
# anyway.
|
||||
#
|
||||
# Can't do it in the background mode, so we hope OpenCL is no enabled
|
||||
# in the user preferences.
|
||||
if not bpy.app.background:
|
||||
_workaround_buggy_drivers()
|
||||
|
||||
path = os.path.dirname(__file__)
|
||||
user_path = os.path.dirname(os.path.abspath(bpy.utils.user_resource('CONFIG', '')))
|
||||
|
||||
|
@@ -511,6 +511,19 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
),
|
||||
)
|
||||
|
||||
cls.use_camera_cull = BoolProperty(
|
||||
name="Use Camera Cull",
|
||||
description="Allow objects to be culled based on the camera frustum",
|
||||
default=False,
|
||||
)
|
||||
|
||||
cls.camera_cull_margin = FloatProperty(
|
||||
name="Camera Cull Margin",
|
||||
description="Margin for the camera space culling",
|
||||
default=0.1,
|
||||
min=0.0, max=5.0
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def unregister(cls):
|
||||
del bpy.types.Scene.cycles
|
||||
@@ -739,6 +752,12 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
|
||||
min=1, max=10000,
|
||||
default=4,
|
||||
)
|
||||
cls.max_bounces = IntProperty(
|
||||
name="Max Bounces",
|
||||
description="Maximum number of bounces the background light will contribute to the render",
|
||||
min=0, max=1024,
|
||||
default=1024,
|
||||
)
|
||||
cls.homogeneous_volume = BoolProperty(
|
||||
name="Homogeneous Volume",
|
||||
description="When using volume rendering, assume volume has the same density everywhere"
|
||||
@@ -890,6 +909,12 @@ class CyclesObjectBlurSettings(bpy.types.PropertyGroup):
|
||||
default=1,
|
||||
)
|
||||
|
||||
cls.use_camera_cull = BoolProperty(
|
||||
name="Use Camera Cull",
|
||||
description="Allow this object and its duplicators to be culled by camera space culling",
|
||||
default=False,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def unregister(cls):
|
||||
del bpy.types.Object.cycles
|
||||
|
@@ -431,10 +431,14 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel):
|
||||
col.prop(rl, "use_pass_emit", text="Emission")
|
||||
col.prop(rl, "use_pass_environment")
|
||||
|
||||
if hasattr(rd, "debug_pass_type"):
|
||||
layout.prop(rd, "debug_pass_type")
|
||||
|
||||
|
||||
class CyclesRender_PT_views(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Views"
|
||||
bl_context = "render_layer"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_header(self, context):
|
||||
rd = context.scene.render
|
||||
@@ -644,7 +648,13 @@ class CyclesObject_PT_motion_blur(CyclesButtonsPanel, Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
return CyclesButtonsPanel.poll(context) and ob and ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META'}
|
||||
if CyclesButtonsPanel.poll(context) and ob:
|
||||
if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META'}:
|
||||
return True
|
||||
if ob.dupli_type == 'GROUP' and ob.dupli_group:
|
||||
return True
|
||||
# TODO(sergey): More duplicator types here?
|
||||
return False
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
@@ -678,8 +688,8 @@ class CyclesObject_PT_motion_blur(CyclesButtonsPanel, Panel):
|
||||
sub.prop(cob, "motion_steps", text="Steps")
|
||||
|
||||
|
||||
class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Ray Visibility"
|
||||
class CyclesObject_PT_cycles_settings(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Cycles Settings"
|
||||
bl_context = "object"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@@ -687,15 +697,19 @@ class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel):
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
return (CyclesButtonsPanel.poll(context) and
|
||||
ob and ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LAMP'} or
|
||||
ob and ob.dupli_type == 'GROUP' and ob.dupli_group)
|
||||
ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LAMP'}) or
|
||||
(ob.dupli_type == 'GROUP' and ob.dupli_group)))
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
ob = context.object
|
||||
cob = ob.cycles
|
||||
visibility = ob.cycles_visibility
|
||||
|
||||
layout.label(text="Ray Visibility:")
|
||||
flow = layout.column_flow()
|
||||
|
||||
flow.prop(visibility, "camera")
|
||||
@@ -707,6 +721,12 @@ class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel):
|
||||
if ob.type != 'LAMP':
|
||||
flow.prop(visibility, "shadow")
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Performance:")
|
||||
row = col.row()
|
||||
row.active = scene.render.use_simplify and cscene.use_camera_cull
|
||||
row.prop(cob, "use_camera_cull")
|
||||
|
||||
|
||||
class CYCLES_OT_use_shading_nodes(Operator):
|
||||
"""Enable nodes on a material, world or lamp"""
|
||||
@@ -1031,6 +1051,7 @@ class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
|
||||
sub.prop(cworld, "sample_map_resolution")
|
||||
if use_branched_path(context):
|
||||
sub.prop(cworld, "samples")
|
||||
sub.prop(cworld, "max_bounces")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Volume:")
|
||||
@@ -1216,7 +1237,8 @@ class CyclesTexture_PT_mapping(CyclesButtonsPanel, Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
node = context.texture_node
|
||||
return node and CyclesButtonsPanel.poll(context)
|
||||
# TODO(sergey): perform a faster/nicer check?
|
||||
return node and hasattr(node, 'texture_mapping') and CyclesButtonsPanel.poll(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1440,7 +1462,9 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
rd = context.scene.render
|
||||
scene = context.scene
|
||||
rd = scene.render
|
||||
cscene = scene.cycles
|
||||
|
||||
layout.active = rd.use_simplify
|
||||
split = layout.split()
|
||||
@@ -1455,6 +1479,12 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
|
||||
col.prop(rd, "simplify_subdivision_render", text="Subdivision")
|
||||
col.prop(rd, "simplify_child_particles_render", text="Child Particles")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(cscene, "use_camera_cull")
|
||||
subsub = col.column()
|
||||
subsub.active = cscene.use_camera_cull
|
||||
subsub.prop(cscene, "camera_cull_margin")
|
||||
|
||||
|
||||
def draw_device(self, context):
|
||||
scene = context.scene
|
||||
|
@@ -207,19 +207,34 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::RenderEngine b_e
|
||||
}
|
||||
}
|
||||
|
||||
static Transform blender_camera_matrix(const Transform& tfm, CameraType type)
|
||||
static Transform blender_camera_matrix(const Transform& tfm,
|
||||
const CameraType type,
|
||||
const PanoramaType panorama_type)
|
||||
{
|
||||
Transform result;
|
||||
|
||||
if(type == CAMERA_PANORAMA) {
|
||||
/* make it so environment camera needs to be pointed in the direction
|
||||
* of the positive x-axis to match an environment texture, this way
|
||||
* it is looking at the center of the texture */
|
||||
result = tfm *
|
||||
make_transform( 0.0f, -1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
if(panorama_type == PANORAMA_MIRRORBALL) {
|
||||
/* Mirror ball camera is looking into the negative Y direction
|
||||
* which matches texture mirror ball mapping.
|
||||
*/
|
||||
result = tfm *
|
||||
make_transform(1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
else {
|
||||
/* Make it so environment camera needs to be pointed in the direction
|
||||
* of the positive x-axis to match an environment texture, this way
|
||||
* it is looking at the center of the texture
|
||||
*/
|
||||
result = tfm *
|
||||
make_transform( 0.0f, -1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* note the blender camera points along the negative z-axis */
|
||||
@@ -229,8 +244,11 @@ static Transform blender_camera_matrix(const Transform& tfm, CameraType type)
|
||||
return transform_clear_scale(result);
|
||||
}
|
||||
|
||||
static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height,
|
||||
BoundBox2D *viewplane, float *aspectratio, float *sensor_size)
|
||||
static void blender_camera_viewplane(BlenderCamera *bcam,
|
||||
int width, int height,
|
||||
BoundBox2D *viewplane,
|
||||
float *aspectratio,
|
||||
float *sensor_size)
|
||||
{
|
||||
/* dimensions */
|
||||
float xratio = (float)width*bcam->pixelaspect.x;
|
||||
@@ -243,24 +261,34 @@ static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height,
|
||||
/* sensor fitting */
|
||||
if(bcam->sensor_fit == BlenderCamera::AUTO) {
|
||||
horizontal_fit = (xratio > yratio);
|
||||
*sensor_size = bcam->sensor_width;
|
||||
if(sensor_size != NULL) {
|
||||
*sensor_size = bcam->sensor_width;
|
||||
}
|
||||
}
|
||||
else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
|
||||
horizontal_fit = true;
|
||||
*sensor_size = bcam->sensor_width;
|
||||
if(sensor_size != NULL) {
|
||||
*sensor_size = bcam->sensor_width;
|
||||
}
|
||||
}
|
||||
else {
|
||||
horizontal_fit = false;
|
||||
*sensor_size = bcam->sensor_height;
|
||||
if(sensor_size != NULL) {
|
||||
*sensor_size = bcam->sensor_height;
|
||||
}
|
||||
}
|
||||
|
||||
if(horizontal_fit) {
|
||||
*aspectratio = xratio/yratio;
|
||||
if(aspectratio != NULL) {
|
||||
*aspectratio = xratio/yratio;
|
||||
}
|
||||
xaspect = *aspectratio;
|
||||
yaspect = 1.0f;
|
||||
}
|
||||
else {
|
||||
*aspectratio = yratio/xratio;
|
||||
if(aspectratio != NULL) {
|
||||
*aspectratio = yratio/xratio;
|
||||
}
|
||||
xaspect = 1.0f;
|
||||
yaspect = *aspectratio;
|
||||
}
|
||||
@@ -269,31 +297,37 @@ static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height,
|
||||
if(bcam->type == CAMERA_ORTHOGRAPHIC) {
|
||||
xaspect = xaspect*bcam->ortho_scale/(*aspectratio*2.0f);
|
||||
yaspect = yaspect*bcam->ortho_scale/(*aspectratio*2.0f);
|
||||
*aspectratio = bcam->ortho_scale/2.0f;
|
||||
if(aspectratio != NULL) {
|
||||
*aspectratio = bcam->ortho_scale/2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if(bcam->type == CAMERA_PANORAMA) {
|
||||
/* set viewplane */
|
||||
*viewplane = bcam->pano_viewplane;
|
||||
if(viewplane != NULL) {
|
||||
*viewplane = bcam->pano_viewplane;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* set viewplane */
|
||||
viewplane->left = -xaspect;
|
||||
viewplane->right = xaspect;
|
||||
viewplane->bottom = -yaspect;
|
||||
viewplane->top = yaspect;
|
||||
if(viewplane != NULL) {
|
||||
viewplane->left = -xaspect;
|
||||
viewplane->right = xaspect;
|
||||
viewplane->bottom = -yaspect;
|
||||
viewplane->top = yaspect;
|
||||
|
||||
/* zoom for 3d camera view */
|
||||
*viewplane = (*viewplane) * bcam->zoom;
|
||||
/* zoom for 3d camera view */
|
||||
*viewplane = (*viewplane) * bcam->zoom;
|
||||
|
||||
/* modify viewplane with camera shift and 3d camera view offset */
|
||||
float dx = 2.0f*(*aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f);
|
||||
float dy = 2.0f*(*aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f);
|
||||
/* modify viewplane with camera shift and 3d camera view offset */
|
||||
float dx = 2.0f*(*aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f);
|
||||
float dy = 2.0f*(*aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f);
|
||||
|
||||
viewplane->left += dx;
|
||||
viewplane->right += dx;
|
||||
viewplane->bottom += dy;
|
||||
viewplane->top += dy;
|
||||
viewplane->left += dx;
|
||||
viewplane->right += dx;
|
||||
viewplane->bottom += dy;
|
||||
viewplane->top += dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,11 +399,16 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
|
||||
cam->bladesrotation = bcam->aperturerotation;
|
||||
|
||||
/* transform */
|
||||
cam->matrix = blender_camera_matrix(bcam->matrix, bcam->type);
|
||||
cam->matrix = blender_camera_matrix(bcam->matrix,
|
||||
bcam->type,
|
||||
bcam->panorama_type);
|
||||
cam->motion.pre = cam->matrix;
|
||||
cam->motion.post = cam->matrix;
|
||||
cam->use_motion = false;
|
||||
cam->use_perspective_motion = false;
|
||||
cam->shuttertime = bcam->shuttertime;
|
||||
cam->fov_pre = cam->fov;
|
||||
cam->fov_post = cam->fov;
|
||||
|
||||
/* border */
|
||||
cam->border = bcam->border;
|
||||
@@ -418,13 +457,19 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override
|
||||
blender_camera_sync(cam, &bcam, width, height);
|
||||
}
|
||||
|
||||
void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time)
|
||||
void BlenderSync::sync_camera_motion(BL::RenderSettings b_render,
|
||||
BL::Object b_ob,
|
||||
int width, int height,
|
||||
float motion_time)
|
||||
{
|
||||
if(!b_ob)
|
||||
return;
|
||||
|
||||
Camera *cam = scene->camera;
|
||||
BL::Array<float, 16> b_ob_matrix;
|
||||
b_engine.camera_model_matrix(b_ob, b_ob_matrix);
|
||||
Transform tfm = get_transform(b_ob_matrix);
|
||||
tfm = blender_camera_matrix(tfm, cam->type);
|
||||
tfm = blender_camera_matrix(tfm, cam->type, cam->panorama_type);
|
||||
|
||||
if(tfm != cam->matrix) {
|
||||
VLOG(1) << "Camera " << b_ob.name() << " motion detected.";
|
||||
@@ -437,6 +482,31 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time)
|
||||
cam->use_motion = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(cam->type == CAMERA_PERSPECTIVE) {
|
||||
BlenderCamera bcam;
|
||||
float aspectratio, sensor_size;
|
||||
blender_camera_init(&bcam, b_render);
|
||||
blender_camera_from_object(&bcam, b_engine, b_ob);
|
||||
blender_camera_viewplane(&bcam,
|
||||
width, height,
|
||||
NULL,
|
||||
&aspectratio,
|
||||
&sensor_size);
|
||||
/* TODO(sergey): De-duplicate calculation with camera sync. */
|
||||
float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
|
||||
if(fov != cam->fov) {
|
||||
VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
|
||||
if(motion_time == -1.0f) {
|
||||
cam->fov_pre = fov;
|
||||
cam->use_perspective_motion = true;
|
||||
}
|
||||
else if(motion_time == 1.0f) {
|
||||
cam->fov_post = fov;
|
||||
cam->use_perspective_motion = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sync 3D View Camera */
|
||||
|
@@ -242,8 +242,16 @@ static void create_mesh_volume_attribute(BL::Object b_ob, Mesh *mesh, ImageManag
|
||||
bool animated = false;
|
||||
|
||||
volume_data->manager = image_manager;
|
||||
volume_data->slot = image_manager->add_image(Attribute::standard_name(std),
|
||||
b_ob.ptr.data, animated, frame, is_float, is_linear, INTERPOLATION_LINEAR, true);
|
||||
volume_data->slot = image_manager->add_image(
|
||||
Attribute::standard_name(std),
|
||||
b_ob.ptr.data,
|
||||
animated,
|
||||
frame,
|
||||
is_float,
|
||||
is_linear,
|
||||
INTERPOLATION_LINEAR,
|
||||
EXTENSION_REPEAT,
|
||||
true);
|
||||
}
|
||||
|
||||
static void create_mesh_volume_attributes(Scene *scene, BL::Object b_ob, Mesh *mesh, float frame)
|
||||
|
@@ -215,6 +215,7 @@ void BlenderSync::sync_background_light(bool use_portal)
|
||||
light->map_resolution = get_int(cworld, "sample_map_resolution");
|
||||
light->shader = scene->default_background;
|
||||
light->use_mis = sample_as_light;
|
||||
light->max_bounces = get_int(cworld, "max_bounces");
|
||||
|
||||
int samples = get_int(cworld, "samples");
|
||||
if(get_boolean(cscene, "use_square_samples"))
|
||||
@@ -234,8 +235,56 @@ void BlenderSync::sync_background_light(bool use_portal)
|
||||
|
||||
/* Object */
|
||||
|
||||
Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob,
|
||||
Transform& tfm, uint layer_flag, float motion_time, bool hide_tris, bool *use_portal)
|
||||
/* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order
|
||||
* to reduce number of objects which are wrongly considered visible.
|
||||
*/
|
||||
static bool object_boundbox_clip(Scene *scene,
|
||||
BL::Object b_ob,
|
||||
Transform& tfm,
|
||||
float margin)
|
||||
{
|
||||
Camera *cam = scene->camera;
|
||||
Transform& worldtondc = cam->worldtondc;
|
||||
BL::Array<float, 24> boundbox = b_ob.bound_box();
|
||||
float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
|
||||
bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
bool all_behind = true;
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
float3 p = make_float3(boundbox[3 * i + 0],
|
||||
boundbox[3 * i + 1],
|
||||
boundbox[3 * i + 2]);
|
||||
p = transform_point(&tfm, p);
|
||||
p = transform_point(&worldtondc, p);
|
||||
if(p.z >= -margin) {
|
||||
all_behind = false;
|
||||
}
|
||||
p /= p.z;
|
||||
bb_min = min(bb_min, p);
|
||||
bb_max = max(bb_max, p);
|
||||
}
|
||||
if(!all_behind) {
|
||||
if(bb_min.x >= 1.0f + margin ||
|
||||
bb_min.y >= 1.0f + margin ||
|
||||
bb_max.x <= -margin ||
|
||||
bb_max.y <= -margin)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Object *BlenderSync::sync_object(BL::Object b_parent,
|
||||
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
|
||||
BL::DupliObject b_dupli_ob,
|
||||
Transform& tfm,
|
||||
uint layer_flag,
|
||||
float motion_time,
|
||||
bool hide_tris,
|
||||
bool use_camera_cull,
|
||||
float camera_cull_margin,
|
||||
bool *use_portal)
|
||||
{
|
||||
BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
|
||||
bool motion = motion_time != 0.0f;
|
||||
@@ -253,6 +302,11 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
|
||||
if(!object_is_mesh(b_ob))
|
||||
return NULL;
|
||||
|
||||
/* Perform camera space culling. */
|
||||
if(use_camera_cull && object_boundbox_clip(scene, b_ob, tfm, camera_cull_margin)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* key to lookup object */
|
||||
ObjectKey key(b_parent, persistent_id, b_ob);
|
||||
Object *object;
|
||||
@@ -261,7 +315,9 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
|
||||
if(motion) {
|
||||
object = object_map.find(key);
|
||||
|
||||
if(object && (scene->need_motion() == Scene::MOTION_PASS || object_use_motion(b_ob))) {
|
||||
if(object && (scene->need_motion() == Scene::MOTION_PASS ||
|
||||
object_use_motion(b_parent, b_ob)))
|
||||
{
|
||||
/* object transformation */
|
||||
if(tfm != object->tfm) {
|
||||
VLOG(1) << "Object " << b_ob.name() << " motion detected.";
|
||||
@@ -342,8 +398,8 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
|
||||
|
||||
mesh->use_motion_blur = false;
|
||||
|
||||
if(object_use_motion(b_ob)) {
|
||||
if(object_use_deform_motion(b_ob)) {
|
||||
if(object_use_motion(b_parent, b_ob)) {
|
||||
if(object_use_deform_motion(b_parent, b_ob)) {
|
||||
mesh->motion_steps = object_motion_steps(b_ob);
|
||||
mesh->use_motion_blur = true;
|
||||
}
|
||||
@@ -478,6 +534,18 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
|
||||
mesh_motion_synced.clear();
|
||||
}
|
||||
|
||||
bool allow_camera_cull = false;
|
||||
float camera_cull_margin = 0.0f;
|
||||
if(b_scene.render().use_simplify()) {
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
allow_camera_cull = scene->camera->type != CAMERA_PANORAMA &&
|
||||
!b_scene.render().use_multiview() &&
|
||||
get_boolean(cscene, "use_camera_cull");
|
||||
if(allow_camera_cull) {
|
||||
camera_cull_margin = get_float(cscene, "camera_cull_margin");
|
||||
}
|
||||
}
|
||||
|
||||
/* object loop */
|
||||
BL::Scene::object_bases_iterator b_base;
|
||||
BL::Scene b_sce = b_scene;
|
||||
@@ -500,6 +568,12 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
|
||||
if(!hide) {
|
||||
progress.set_sync_status("Synchronizing object", b_ob.name());
|
||||
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
||||
bool use_camera_cull = allow_camera_cull && get_boolean(cobject, "use_camera_cull");
|
||||
if(use_camera_cull) {
|
||||
/* Need to have proper projection matrix. */
|
||||
scene->camera->update();
|
||||
}
|
||||
if(b_ob.is_duplicator() && !object_render_hide_duplis(b_ob)) {
|
||||
/* dupli objects */
|
||||
b_ob.dupli_list_create(b_scene, dupli_settings);
|
||||
@@ -519,7 +593,16 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
|
||||
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
|
||||
|
||||
/* sync object and mesh or light data */
|
||||
Object *object = sync_object(b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion_time, hide_tris, &use_portal);
|
||||
Object *object = sync_object(b_ob,
|
||||
persistent_id.data,
|
||||
*b_dup,
|
||||
tfm,
|
||||
ob_layer,
|
||||
motion_time,
|
||||
hide_tris,
|
||||
use_camera_cull,
|
||||
camera_cull_margin,
|
||||
&use_portal);
|
||||
|
||||
/* sync possible particle data, note particle_id
|
||||
* starts counting at 1, first is dummy particle */
|
||||
@@ -539,7 +622,16 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
|
||||
if(!object_render_hide(b_ob, true, true, hide_tris)) {
|
||||
/* object itself */
|
||||
Transform tfm = get_transform(b_ob.matrix_world());
|
||||
sync_object(b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion_time, hide_tris, &use_portal);
|
||||
sync_object(b_ob,
|
||||
NULL,
|
||||
PointerRNA_NULL,
|
||||
tfm,
|
||||
ob_layer,
|
||||
motion_time,
|
||||
hide_tris,
|
||||
use_camera_cull,
|
||||
camera_cull_margin,
|
||||
&use_portal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,7 +659,11 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
|
||||
mesh_motion_synced.clear();
|
||||
}
|
||||
|
||||
void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state)
|
||||
void BlenderSync::sync_motion(BL::RenderSettings b_render,
|
||||
BL::SpaceView3D b_v3d,
|
||||
BL::Object b_override,
|
||||
int width, int height,
|
||||
void **python_thread_state)
|
||||
{
|
||||
if(scene->need_motion() == Scene::MOTION_NONE)
|
||||
return;
|
||||
@@ -587,6 +683,9 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void
|
||||
|
||||
/* note iteration over motion_times set happens in sorted order */
|
||||
foreach(float relative_time, motion_times) {
|
||||
VLOG(1) << "Synchronizing motion for the relative time "
|
||||
<< relative_time << ".";
|
||||
|
||||
/* fixed shutter time to get previous and next frame for motion pass */
|
||||
float shuttertime;
|
||||
|
||||
@@ -606,8 +705,12 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void
|
||||
python_thread_state_save(python_thread_state);
|
||||
|
||||
/* sync camera, only supports two times at the moment */
|
||||
if(relative_time == -1.0f || relative_time == 1.0f)
|
||||
sync_camera_motion(b_cam, relative_time);
|
||||
if(relative_time == -1.0f || relative_time == 1.0f) {
|
||||
sync_camera_motion(b_render,
|
||||
b_cam,
|
||||
width, height,
|
||||
relative_time);
|
||||
}
|
||||
|
||||
/* sync object */
|
||||
sync_objects(b_v3d, relative_time);
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "blender_session.h"
|
||||
|
||||
#include "util_foreach.h"
|
||||
#include "util_logging.h"
|
||||
#include "util_md5.h"
|
||||
#include "util_opengl.h"
|
||||
#include "util_path.h"
|
||||
@@ -486,6 +487,19 @@ static PyObject *system_info_func(PyObject * /*self*/, PyObject * /*value*/)
|
||||
return PyUnicode_FromString(system_info.c_str());
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENCL
|
||||
static PyObject *opencl_disable_func(PyObject * /*self*/, PyObject * /*value*/)
|
||||
{
|
||||
VLOG(2) << "Disabling OpenCL platform.";
|
||||
#ifdef WIN32
|
||||
putenv("CYCLES_OPENCL_TEST=NONE");
|
||||
#else
|
||||
setenv("CYCLES_OPENCL_TEST", "NONE", 1);
|
||||
#endif
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyMethodDef methods[] = {
|
||||
{"init", init_func, METH_VARARGS, ""},
|
||||
{"create", create_func, METH_VARARGS, ""},
|
||||
@@ -501,6 +515,9 @@ static PyMethodDef methods[] = {
|
||||
#endif
|
||||
{"available_devices", available_devices_func, METH_NOARGS, ""},
|
||||
{"system_info", system_info_func, METH_NOARGS, ""},
|
||||
#ifdef WITH_OPENCL
|
||||
{"opencl_disable", opencl_disable_func, METH_NOARGS, ""},
|
||||
#endif
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "util_color.h"
|
||||
#include "util_foreach.h"
|
||||
#include "util_function.h"
|
||||
#include "util_logging.h"
|
||||
#include "util_progress.h"
|
||||
#include "util_time.h"
|
||||
|
||||
@@ -121,7 +122,12 @@ void BlenderSession::create_session()
|
||||
if(session_pause == false) {
|
||||
/* full data sync */
|
||||
sync->sync_view(b_v3d, b_rv3d, width, height);
|
||||
sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
|
||||
sync->sync_data(b_render,
|
||||
b_v3d,
|
||||
b_engine.camera_override(),
|
||||
width, height,
|
||||
&python_thread_state,
|
||||
b_rlay_name.c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -271,6 +277,10 @@ static PassType get_pass_type(BL::RenderPass b_pass)
|
||||
{
|
||||
if(b_pass.debug_type() == BL::RenderPass::debug_type_BVH_TRAVERSAL_STEPS)
|
||||
return PASS_BVH_TRAVERSAL_STEPS;
|
||||
if(b_pass.debug_type() == BL::RenderPass::debug_type_BVH_TRAVERSED_INSTANCES)
|
||||
return PASS_BVH_TRAVERSED_INSTANCES;
|
||||
if(b_pass.debug_type() == BL::RenderPass::debug_type_RAY_BOUNCES)
|
||||
return PASS_RAY_BOUNCES;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -437,9 +447,6 @@ void BlenderSession::render()
|
||||
/* add passes */
|
||||
vector<Pass> passes;
|
||||
Pass::add(PASS_COMBINED, passes);
|
||||
#ifdef WITH_CYCLES_DEBUG
|
||||
Pass::add(PASS_BVH_TRAVERSAL_STEPS, passes);
|
||||
#endif
|
||||
|
||||
if(session_params.device.advanced_shading) {
|
||||
|
||||
@@ -471,7 +478,12 @@ void BlenderSession::render()
|
||||
|
||||
/* update scene */
|
||||
sync->sync_camera(b_render, b_engine.camera_override(), width, height);
|
||||
sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state, b_rlay_name.c_str());
|
||||
sync->sync_data(b_render,
|
||||
b_v3d,
|
||||
b_engine.camera_override(),
|
||||
width, height,
|
||||
&python_thread_state,
|
||||
b_rlay_name.c_str());
|
||||
|
||||
/* update number of samples per layer */
|
||||
int samples = sync->get_layer_samples();
|
||||
@@ -497,6 +509,11 @@ void BlenderSession::render()
|
||||
break;
|
||||
}
|
||||
|
||||
double total_time, render_time;
|
||||
session->progress.get_time(total_time, render_time);
|
||||
VLOG(1) << "Total render time: " << total_time;
|
||||
VLOG(1) << "Render time (without synchronization): " << render_time;
|
||||
|
||||
/* clear callback */
|
||||
session->write_render_tile_cb = function_null;
|
||||
session->update_render_tile_cb = function_null;
|
||||
@@ -532,6 +549,11 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, const in
|
||||
size_t object_index = OBJECT_NONE;
|
||||
int tri_offset = 0;
|
||||
|
||||
/* Set baking flag in advance, so kernel loading can check if we need
|
||||
* any baking capabilities.
|
||||
*/
|
||||
scene->bake_manager->set_baking(true);
|
||||
|
||||
/* ensure kernels are loaded before we do any scene updates */
|
||||
session->load_kernels();
|
||||
|
||||
@@ -554,14 +576,18 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, const in
|
||||
|
||||
/* update scene */
|
||||
sync->sync_camera(b_render, b_engine.camera_override(), width, height);
|
||||
sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
|
||||
sync->sync_data(b_render,
|
||||
b_v3d,
|
||||
b_engine.camera_override(),
|
||||
width, height,
|
||||
&python_thread_state,
|
||||
b_rlay_name.c_str());
|
||||
|
||||
/* get buffer parameters */
|
||||
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
|
||||
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
|
||||
|
||||
scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y());
|
||||
scene->bake_manager->set_baking(true);
|
||||
|
||||
/* set number of samples */
|
||||
session->tile_manager.set_samples(session_params.samples);
|
||||
@@ -697,7 +723,12 @@ void BlenderSession::synchronize()
|
||||
}
|
||||
|
||||
/* data and camera synchronize */
|
||||
sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
|
||||
sync->sync_data(b_render,
|
||||
b_v3d,
|
||||
b_engine.camera_override(),
|
||||
width, height,
|
||||
&python_thread_state,
|
||||
b_rlay_name.c_str());
|
||||
|
||||
if(b_rv3d)
|
||||
sync->sync_view(b_v3d, b_rv3d, width, height);
|
||||
@@ -863,12 +894,12 @@ void BlenderSession::update_status_progress()
|
||||
scene += ", " + b_rview_name;
|
||||
}
|
||||
else {
|
||||
BLI_timestr(total_time, time_str, sizeof(time_str));
|
||||
BLI_timecode_string_from_time_simple(time_str, sizeof(time_str), total_time);
|
||||
timestatus = "Time:" + string(time_str) + " | ";
|
||||
}
|
||||
|
||||
if(remaining_time > 0) {
|
||||
BLI_timestr(remaining_time, time_str, sizeof(time_str));
|
||||
BLI_timecode_string_from_time_simple(time_str, sizeof(time_str), remaining_time);
|
||||
timestatus += "Remaining:" + string(time_str) + " | ";
|
||||
}
|
||||
|
||||
@@ -1001,6 +1032,18 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti
|
||||
|
||||
is_float = true;
|
||||
}
|
||||
else {
|
||||
/* TODO(sergey): Check we're indeed in shader node tree. */
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
|
||||
BL::Node b_node(ptr);
|
||||
if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
|
||||
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
|
||||
channels = 4;
|
||||
width = height = depth = b_point_density_node.resolution();
|
||||
is_float = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels)
|
||||
@@ -1143,6 +1186,17 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
|
||||
|
||||
fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
|
||||
}
|
||||
else {
|
||||
/* TODO(sergey): Check we're indeed in shader node tree. */
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
|
||||
BL::Node b_node(ptr);
|
||||
if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
|
||||
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
|
||||
int length;
|
||||
b_point_density_node.calc_point_density(b_scene, &length, &pixels);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "scene.h"
|
||||
#include "shader.h"
|
||||
|
||||
#include "blender_texture.h"
|
||||
#include "blender_sync.h"
|
||||
#include "blender_util.h"
|
||||
|
||||
@@ -589,14 +590,17 @@ static ShaderNode *add_node(Scene *scene,
|
||||
|
||||
/* TODO(sergey): Does not work properly when we change builtin type. */
|
||||
if(b_image.is_updated()) {
|
||||
scene->image_manager->tag_reload_image(image->filename,
|
||||
image->builtin_data,
|
||||
(InterpolationType)b_image_node.interpolation());
|
||||
scene->image_manager->tag_reload_image(
|
||||
image->filename,
|
||||
image->builtin_data,
|
||||
(InterpolationType)b_image_node.interpolation(),
|
||||
(ExtensionType)b_image_node.extension());
|
||||
}
|
||||
}
|
||||
image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
|
||||
image->projection = ImageTextureNode::projection_enum[(int)b_image_node.projection()];
|
||||
image->interpolation = (InterpolationType)b_image_node.interpolation();
|
||||
image->extension = (ExtensionType)b_image_node.extension();
|
||||
image->projection_blend = b_image_node.projection_blend();
|
||||
get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
|
||||
node = image;
|
||||
@@ -629,7 +633,8 @@ static ShaderNode *add_node(Scene *scene,
|
||||
if(b_image.is_updated()) {
|
||||
scene->image_manager->tag_reload_image(env->filename,
|
||||
env->builtin_data,
|
||||
INTERPOLATION_LINEAR);
|
||||
INTERPOLATION_LINEAR,
|
||||
EXTENSION_REPEAT);
|
||||
}
|
||||
}
|
||||
env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
|
||||
@@ -736,6 +741,36 @@ static ShaderNode *add_node(Scene *scene,
|
||||
uvm->from_dupli = b_uvmap_node.from_dupli();
|
||||
node = uvm;
|
||||
}
|
||||
else if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
|
||||
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
|
||||
PointDensityTextureNode *point_density = new PointDensityTextureNode();
|
||||
point_density->filename = b_point_density_node.name();
|
||||
point_density->space =
|
||||
PointDensityTextureNode::space_enum[(int)b_point_density_node.space()];
|
||||
point_density->interpolation =
|
||||
(InterpolationType)b_point_density_node.interpolation();
|
||||
point_density->builtin_data = b_point_density_node.ptr.data;
|
||||
|
||||
/* Transformation form world space to texture space. */
|
||||
BL::Object b_ob(b_point_density_node.object());
|
||||
if(b_ob) {
|
||||
float3 loc, size;
|
||||
point_density_texture_space(b_point_density_node, loc, size);
|
||||
point_density->tfm =
|
||||
transform_translate(-loc) * transform_scale(size) *
|
||||
transform_inverse(get_transform(b_ob.matrix_world()));
|
||||
}
|
||||
|
||||
/* TODO(sergey): Use more proper update flag. */
|
||||
if(true) {
|
||||
scene->image_manager->tag_reload_image(
|
||||
point_density->filename,
|
||||
point_density->builtin_data,
|
||||
point_density->interpolation,
|
||||
EXTENSION_REPEAT);
|
||||
}
|
||||
node = point_density;
|
||||
}
|
||||
|
||||
if(node)
|
||||
graph->add(node);
|
||||
|
@@ -145,7 +145,12 @@ bool BlenderSync::sync_recalc()
|
||||
return recalc;
|
||||
}
|
||||
|
||||
void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state, const char *layer)
|
||||
void BlenderSync::sync_data(BL::RenderSettings b_render,
|
||||
BL::SpaceView3D b_v3d,
|
||||
BL::Object b_override,
|
||||
int width, int height,
|
||||
void **python_thread_state,
|
||||
const char *layer)
|
||||
{
|
||||
sync_render_layers(b_v3d, layer);
|
||||
sync_integrator();
|
||||
@@ -157,7 +162,11 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, void *
|
||||
mesh_synced.clear(); /* use for objects and motion sync */
|
||||
|
||||
sync_objects(b_v3d);
|
||||
sync_motion(b_v3d, b_override, python_thread_state);
|
||||
sync_motion(b_render,
|
||||
b_v3d,
|
||||
b_override,
|
||||
width, height,
|
||||
python_thread_state);
|
||||
|
||||
mesh_synced.clear();
|
||||
}
|
||||
|
@@ -53,7 +53,12 @@ public:
|
||||
|
||||
/* sync */
|
||||
bool sync_recalc();
|
||||
void sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state, const char *layer = 0);
|
||||
void sync_data(BL::RenderSettings b_render,
|
||||
BL::SpaceView3D b_v3d,
|
||||
BL::Object b_override,
|
||||
int width, int height,
|
||||
void **python_thread_state,
|
||||
const char *layer = 0);
|
||||
void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer);
|
||||
void sync_integrator();
|
||||
void sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height);
|
||||
@@ -75,7 +80,11 @@ private:
|
||||
void sync_lamps(bool update_all);
|
||||
void sync_materials(bool update_all);
|
||||
void sync_objects(BL::SpaceView3D b_v3d, float motion_time = 0.0f);
|
||||
void sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state);
|
||||
void sync_motion(BL::RenderSettings b_render,
|
||||
BL::SpaceView3D b_v3d,
|
||||
BL::Object b_override,
|
||||
int width, int height,
|
||||
void **python_thread_state);
|
||||
void sync_film();
|
||||
void sync_view();
|
||||
void sync_world(bool update_all);
|
||||
@@ -85,12 +94,23 @@ private:
|
||||
void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
|
||||
Mesh *sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris);
|
||||
void sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool motion, int time_index = 0);
|
||||
Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob,
|
||||
Transform& tfm, uint layer_flag, float motion_time, bool hide_tris, bool *use_portal);
|
||||
Object *sync_object(BL::Object b_parent,
|
||||
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
|
||||
BL::DupliObject b_dupli_ob,
|
||||
Transform& tfm,
|
||||
uint layer_flag,
|
||||
float motion_time,
|
||||
bool hide_tris,
|
||||
bool use_camera_cull,
|
||||
float camera_cull_margin,
|
||||
bool *use_portal);
|
||||
void sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm, bool *use_portal);
|
||||
void sync_background_light(bool use_portal);
|
||||
void sync_mesh_motion(BL::Object b_ob, Object *object, float motion_time);
|
||||
void sync_camera_motion(BL::Object b_ob, float motion_time);
|
||||
void sync_camera_motion(BL::RenderSettings b_render,
|
||||
BL::Object b_ob,
|
||||
int width, int height,
|
||||
float motion_time);
|
||||
|
||||
/* particles */
|
||||
bool sync_dupli_particle(BL::Object b_ob, BL::DupliObject b_dup, Object *object);
|
||||
|
116
intern/cycles/blender/blender_texture.cpp
Normal file
116
intern/cycles/blender/blender_texture.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2011-2015 Blender Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "blender_texture.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
namespace {
|
||||
|
||||
/* Point density helpers. */
|
||||
|
||||
static void density_texture_space_invert(float3& loc,
|
||||
float3& size)
|
||||
{
|
||||
if(size.x != 0.0f) size.x = 0.5f/size.x;
|
||||
if(size.y != 0.0f) size.y = 0.5f/size.y;
|
||||
if(size.z != 0.0f) size.z = 0.5f/size.z;
|
||||
|
||||
loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
static void density_object_texture_space(BL::Object b_ob,
|
||||
float radius,
|
||||
float3& loc,
|
||||
float3& size)
|
||||
{
|
||||
if(b_ob.type() == BL::Object::type_MESH) {
|
||||
BL::Mesh b_mesh(b_ob.data());
|
||||
loc = get_float3(b_mesh.texspace_location());
|
||||
size = get_float3(b_mesh.texspace_size());
|
||||
}
|
||||
else {
|
||||
/* TODO(sergey): Not supported currently. */
|
||||
}
|
||||
/* Adjust texture space to include density points on the boundaries. */
|
||||
size = size + make_float3(radius, radius, radius);
|
||||
density_texture_space_invert(loc, size);
|
||||
}
|
||||
|
||||
static void density_particle_system_texture_space(
|
||||
BL::Object b_ob,
|
||||
BL::ParticleSystem b_particle_system,
|
||||
float radius,
|
||||
float3& loc,
|
||||
float3& size)
|
||||
{
|
||||
if(b_particle_system.settings().type() == BL::ParticleSettings::type_HAIR) {
|
||||
/* TODO(sergey): Not supported currently. */
|
||||
return;
|
||||
}
|
||||
Transform tfm = get_transform(b_ob.matrix_world());
|
||||
Transform itfm = transform_inverse(tfm);
|
||||
float3 min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
|
||||
max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
float3 particle_size = make_float3(radius, radius, radius);
|
||||
for(int i = 0; i < b_particle_system.particles.length(); ++i) {
|
||||
BL::Particle particle = b_particle_system.particles[i];
|
||||
float3 location = get_float3(particle.location());
|
||||
location = transform_point(&itfm, location);
|
||||
min = ccl::min(min, location - particle_size);
|
||||
max = ccl::max(max, location + particle_size);
|
||||
}
|
||||
/* Calculate texture space from the particle bounds. */
|
||||
loc = (min + max) * 0.5f;
|
||||
size = (max - min) * 0.5f;
|
||||
density_texture_space_invert(loc, size);
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
void point_density_texture_space(BL::ShaderNodeTexPointDensity b_point_density_node,
|
||||
float3& loc,
|
||||
float3& size)
|
||||
{
|
||||
/* Fallback values. */
|
||||
loc = make_float3(0.0f, 0.0f, 0.0f);
|
||||
size = make_float3(0.0f, 0.0f, 0.0f);
|
||||
BL::Object b_ob(b_point_density_node.object());
|
||||
if(!b_ob) {
|
||||
return;
|
||||
}
|
||||
if(b_point_density_node.point_source() ==
|
||||
BL::ShaderNodeTexPointDensity::point_source_PARTICLE_SYSTEM)
|
||||
{
|
||||
BL::ParticleSystem b_particle_system(
|
||||
b_point_density_node.particle_system());
|
||||
if(b_particle_system) {
|
||||
density_particle_system_texture_space(b_ob,
|
||||
b_particle_system,
|
||||
b_point_density_node.radius(),
|
||||
loc,
|
||||
size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
density_object_texture_space(b_ob,
|
||||
b_point_density_node.radius(),
|
||||
loc,
|
||||
size);
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
31
intern/cycles/blender/blender_texture.h
Normal file
31
intern/cycles/blender/blender_texture.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2011-2015 Blender Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __BLENDER_TEXTURE_H__
|
||||
#define __BLENDER_TEXTURE_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "blender_sync.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
void point_density_texture_space(BL::ShaderNodeTexPointDensity b_point_density_node,
|
||||
float3& loc,
|
||||
float3& size);
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __BLENDER_TEXTURE_H__ */
|
@@ -28,7 +28,7 @@
|
||||
* todo: clean this up ... */
|
||||
|
||||
extern "C" {
|
||||
void BLI_timestr(double _time, char *str, size_t maxlen);
|
||||
size_t BLI_timecode_string_from_time_simple(char *str, size_t maxlen, double time_seconds);
|
||||
void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
|
||||
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
|
||||
unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame);
|
||||
@@ -354,11 +354,20 @@ static inline void mesh_texture_space(BL::Mesh b_mesh, float3& loc, float3& size
|
||||
}
|
||||
|
||||
/* object used for motion blur */
|
||||
static inline bool object_use_motion(BL::Object b_ob)
|
||||
static inline bool object_use_motion(BL::Object b_parent, BL::Object b_ob)
|
||||
{
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
||||
bool use_motion = get_boolean(cobject, "use_motion_blur");
|
||||
|
||||
/* If motion blur is enabled for the object we also check
|
||||
* whether it's enabled for the parent object as well.
|
||||
*
|
||||
* This way we can control motion blur from the dupligroup
|
||||
* duplicator much easier.
|
||||
*/
|
||||
if(use_motion && b_parent.ptr.data != b_ob.ptr.data) {
|
||||
PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
|
||||
use_motion &= get_boolean(parent_cobject, "use_motion_blur");
|
||||
}
|
||||
return use_motion;
|
||||
}
|
||||
|
||||
@@ -375,11 +384,20 @@ static inline uint object_motion_steps(BL::Object b_ob)
|
||||
}
|
||||
|
||||
/* object uses deformation motion blur */
|
||||
static inline bool object_use_deform_motion(BL::Object b_ob)
|
||||
static inline bool object_use_deform_motion(BL::Object b_parent, BL::Object b_ob)
|
||||
{
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
||||
bool use_deform_motion = get_boolean(cobject, "use_deform_motion");
|
||||
|
||||
/* If motion blur is enabled for the object we also check
|
||||
* whether it's enabled for the parent object as well.
|
||||
*
|
||||
* This way we can control motion blur from the dupligroup
|
||||
* duplicator much easier.
|
||||
*/
|
||||
if(use_deform_motion && b_parent.ptr.data != b_ob.ptr.data) {
|
||||
PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
|
||||
use_deform_motion &= get_boolean(parent_cobject, "use_deform_motion");
|
||||
}
|
||||
return use_deform_motion;
|
||||
}
|
||||
|
||||
|
@@ -190,11 +190,12 @@ void BVH::build(Progress& progress)
|
||||
}
|
||||
|
||||
/* build nodes */
|
||||
vector<int> prim_type;
|
||||
vector<int> prim_index;
|
||||
vector<int> prim_object;
|
||||
|
||||
BVHBuild bvh_build(objects, prim_type, prim_index, prim_object, params, progress);
|
||||
BVHBuild bvh_build(objects,
|
||||
pack.prim_type,
|
||||
pack.prim_index,
|
||||
pack.prim_object,
|
||||
params,
|
||||
progress);
|
||||
BVHNode *root = bvh_build.run();
|
||||
|
||||
if(progress.get_cancel()) {
|
||||
@@ -202,14 +203,6 @@ void BVH::build(Progress& progress)
|
||||
return;
|
||||
}
|
||||
|
||||
/* todo: get rid of this copy */
|
||||
pack.prim_type = prim_type;
|
||||
pack.prim_index = prim_index;
|
||||
pack.prim_object = prim_object;
|
||||
prim_type.free_memory();
|
||||
prim_index.free_memory();
|
||||
prim_object.free_memory();
|
||||
|
||||
/* compute SAH */
|
||||
if(!params.top_level)
|
||||
pack.SAH = root->computeSubtreeSAHCost(params);
|
||||
|
@@ -65,15 +65,18 @@ public:
|
||||
/* Constructor / Destructor */
|
||||
|
||||
BVHBuild::BVHBuild(const vector<Object*>& objects_,
|
||||
vector<int>& prim_type_, vector<int>& prim_index_, vector<int>& prim_object_,
|
||||
const BVHParams& params_, Progress& progress_)
|
||||
: objects(objects_),
|
||||
prim_type(prim_type_),
|
||||
prim_index(prim_index_),
|
||||
prim_object(prim_object_),
|
||||
params(params_),
|
||||
progress(progress_),
|
||||
progress_start_time(0.0)
|
||||
array<int>& prim_type_,
|
||||
array<int>& prim_index_,
|
||||
array<int>& prim_object_,
|
||||
const BVHParams& params_,
|
||||
Progress& progress_)
|
||||
: objects(objects_),
|
||||
prim_type(prim_type_),
|
||||
prim_index(prim_index_),
|
||||
prim_object(prim_object_),
|
||||
params(params_),
|
||||
progress(progress_),
|
||||
progress_start_time(0.0)
|
||||
{
|
||||
spatial_min_overlap = 0.0f;
|
||||
}
|
||||
@@ -446,18 +449,10 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
|
||||
return new LeafNode(bounds, 0, 0, 0);
|
||||
}
|
||||
else if(num == 1) {
|
||||
if(start == prim_index.size()) {
|
||||
assert(params.use_spatial_split);
|
||||
|
||||
prim_type.push_back(ref->prim_type());
|
||||
prim_index.push_back(ref->prim_index());
|
||||
prim_object.push_back(ref->prim_object());
|
||||
}
|
||||
else {
|
||||
prim_type[start] = ref->prim_type();
|
||||
prim_index[start] = ref->prim_index();
|
||||
prim_object[start] = ref->prim_object();
|
||||
}
|
||||
assert(start < prim_type.size());
|
||||
prim_type[start] = ref->prim_type();
|
||||
prim_index[start] = ref->prim_index();
|
||||
prim_object[start] = ref->prim_object();
|
||||
|
||||
uint visibility = objects[ref->prim_object()]->visibility;
|
||||
return new LeafNode(ref->bounds(), visibility, start, start+1);
|
||||
@@ -484,17 +479,9 @@ BVHNode *BVHBuild::create_primitive_leaf_node(const int *p_type,
|
||||
int num)
|
||||
{
|
||||
for(int i = 0; i < num; ++i) {
|
||||
if(start + i == prim_index.size()) {
|
||||
assert(params.use_spatial_split);
|
||||
prim_type.push_back(p_type[i]);
|
||||
prim_index.push_back(p_index[i]);
|
||||
prim_object.push_back(p_object[i]);
|
||||
}
|
||||
else {
|
||||
prim_type[start + i] = p_type[i];
|
||||
prim_index[start + i] = p_index[i];
|
||||
prim_object[start + i] = p_object[i];
|
||||
}
|
||||
prim_type[start + i] = p_type[i];
|
||||
prim_index[start + i] = p_index[i];
|
||||
prim_object[start + i] = p_object[i];
|
||||
}
|
||||
return new LeafNode(bounds, visibility, start, start + num);
|
||||
}
|
||||
@@ -535,6 +522,19 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
|
||||
}
|
||||
}
|
||||
|
||||
/* Extend an array when needed. */
|
||||
if(prim_type.size() < range.end()) {
|
||||
assert(params.use_spatial_split);
|
||||
/* TODO(sergey): We might want to look into different policies of
|
||||
* re-allocation here, so on the one hand we would not do as much
|
||||
* re-allocations and on the other hand will have small memory
|
||||
* overhead.
|
||||
*/
|
||||
prim_type.resize(range.end());
|
||||
prim_index.resize(range.end());
|
||||
prim_object.resize(range.end());
|
||||
}
|
||||
|
||||
/* Create leaf nodes for every existing primitive. */
|
||||
BVHNode *leaves[PRIMITIVE_NUM_TOTAL + 1] = {NULL};
|
||||
int num_leaves = 0;
|
||||
|
@@ -42,13 +42,12 @@ class BVHBuild
|
||||
{
|
||||
public:
|
||||
/* Constructor/Destructor */
|
||||
BVHBuild(
|
||||
const vector<Object*>& objects,
|
||||
vector<int>& prim_type,
|
||||
vector<int>& prim_index,
|
||||
vector<int>& prim_object,
|
||||
const BVHParams& params,
|
||||
Progress& progress);
|
||||
BVHBuild(const vector<Object*>& objects,
|
||||
array<int>& prim_type,
|
||||
array<int>& prim_index,
|
||||
array<int>& prim_object,
|
||||
const BVHParams& params,
|
||||
Progress& progress);
|
||||
~BVHBuild();
|
||||
|
||||
BVHNode *run();
|
||||
@@ -99,9 +98,9 @@ protected:
|
||||
int num_original_references;
|
||||
|
||||
/* output primitive indexes and objects */
|
||||
vector<int>& prim_type;
|
||||
vector<int>& prim_index;
|
||||
vector<int>& prim_object;
|
||||
array<int>& prim_type;
|
||||
array<int>& prim_index;
|
||||
array<int>& prim_object;
|
||||
|
||||
/* build parameters */
|
||||
BVHParams params;
|
||||
|
@@ -31,6 +31,29 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Device Requested Features */
|
||||
|
||||
std::ostream& operator <<(std::ostream &os,
|
||||
const DeviceRequestedFeatures& requested_features)
|
||||
{
|
||||
os << "Experimental features: "
|
||||
<< (requested_features.experimental ? "On" : "Off") << std::endl;
|
||||
os << "Max closure count: " << requested_features.max_closure << std::endl;
|
||||
os << "Max nodes group: " << requested_features.max_nodes_group << std::endl;
|
||||
/* TODO(sergey): Decode bitflag into list of names. */
|
||||
os << "Nodes features: " << requested_features.nodes_features << std::endl;
|
||||
/* TODO(sergey): Make it utility function to convert bool to string. */
|
||||
os << "Use hair: "
|
||||
<< (requested_features.use_hair ? "True" : "False") << std::endl;
|
||||
os << "Use object motion: "
|
||||
<< (requested_features.use_object_motion ? "True" : "False") << std::endl;
|
||||
os << "Use camera motion: "
|
||||
<< (requested_features.use_camera_motion ? "True" : "False") << std::endl;
|
||||
os << "Use Baking: "
|
||||
<< (requested_features.use_baking ? "True" : "False") << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
/* Device */
|
||||
|
||||
Device::~Device()
|
||||
|
@@ -97,6 +97,9 @@ public:
|
||||
bool use_object_motion;
|
||||
bool use_camera_motion;
|
||||
|
||||
/* Denotes whether baking functionality is needed. */
|
||||
bool use_baking;
|
||||
|
||||
DeviceRequestedFeatures()
|
||||
{
|
||||
/* TODO(sergey): Find more meaningful defaults. */
|
||||
@@ -107,6 +110,7 @@ public:
|
||||
use_hair = false;
|
||||
use_object_motion = false;
|
||||
use_camera_motion = false;
|
||||
use_baking = false;
|
||||
}
|
||||
|
||||
bool modified(const DeviceRequestedFeatures& requested_features)
|
||||
@@ -114,10 +118,18 @@ public:
|
||||
return !(experimental == requested_features.experimental &&
|
||||
max_closure == requested_features.max_closure &&
|
||||
max_nodes_group == requested_features.max_nodes_group &&
|
||||
nodes_features == requested_features.nodes_features);
|
||||
nodes_features == requested_features.nodes_features &&
|
||||
use_hair == requested_features.use_hair &&
|
||||
use_object_motion == requested_features.use_object_motion &&
|
||||
use_camera_motion == requested_features.use_camera_motion &&
|
||||
use_baking == requested_features.use_baking);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
std::ostream& operator <<(std::ostream &os,
|
||||
const DeviceRequestedFeatures& requested_features);
|
||||
|
||||
/* Device */
|
||||
|
||||
struct DeviceDrawParams {
|
||||
@@ -161,10 +173,10 @@ public:
|
||||
virtual void tex_alloc(const char * /*name*/,
|
||||
device_memory& /*mem*/,
|
||||
InterpolationType interpolation = INTERPOLATION_NONE,
|
||||
bool periodic = false)
|
||||
ExtensionType extension = EXTENSION_REPEAT)
|
||||
{
|
||||
(void)interpolation; /* Ignored. */
|
||||
(void)periodic; /* Ignored. */
|
||||
(void)extension; /* Ignored. */
|
||||
};
|
||||
virtual void tex_free(device_memory& /*mem*/) {};
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user