Compare commits
779 Commits
temp-point
...
eevee-dof-
Author | SHA1 | Date | |
---|---|---|---|
7769b89bab | |||
cccf7387a8 | |||
c5873c7828 | |||
d02e644060 | |||
e49b702527 | |||
54d6e071ab | |||
7bc49f68a9 | |||
8a6e07e42c | |||
aeaa549948 | |||
c4c1b2addc | |||
d447a5eab3 | |||
376bffae03 | |||
f4f4495586 | |||
8e98983945 | |||
1a1aa5392d | |||
3200a135be | |||
2b18c41c4d | |||
85fe12071a | |||
3a446f2d9f | |||
487fe5abfc | |||
10e3b2dc8e | |||
e1f38b2169 | |||
e69217b283 | |||
c9d6737e3e | |||
4884153823 | |||
2ce1400297 | |||
0fc456f091 | |||
78ff852680 | |||
64a963486f | |||
![]() |
4a80c0e275 | ||
f2781e1c7c | |||
b3f9895ab0 | |||
1a5b988509 | |||
8c36f6becf | |||
9ad828dbad | |||
4ff5051ffc | |||
2262e18269 | |||
198ff4703f | |||
d0aa7d5562 | |||
f8359b5f52 | |||
326102f498 | |||
56bccd2395 | |||
b7865f77c3 | |||
a1c7cab06c | |||
ed00f7c65e | |||
9e0c876aad | |||
![]() |
1428544528 | ||
e3c8363ce0 | |||
f3a2434bb6 | |||
fed191fd89 | |||
![]() |
886486615b | ||
62419975b7 | |||
d19aaad0bc | |||
356c62fe32 | |||
1d77302fd9 | |||
bde797c172 | |||
d917d7cf94 | |||
1422c28ef1 | |||
3ae74bcd29 | |||
33b8063b1f | |||
038d72752d | |||
59054d906f | |||
84dddf641e | |||
d5d8655ca1 | |||
bc41aaaaaa | |||
5ec9e3a26e | |||
006e70dbd7 | |||
82e2d70024 | |||
a69983f30e | |||
c02f2d7371 | |||
9e9ebaba8d | |||
88d9eb14d1 | |||
d1ee8a0502 | |||
f04ddd398f | |||
03c1c5f3a4 | |||
5c72a4d452 | |||
fa2ffb1a2f | |||
5e117b1226 | |||
f4cb93b55d | |||
d857892553 | |||
e94c38e005 | |||
54ac63f06b | |||
1e55d28a4e | |||
9c244820d1 | |||
30ac21bf33 | |||
b10fac0432 | |||
d4aa5b2166 | |||
a9b53daf23 | |||
c828a505c2 | |||
419c67c851 | |||
a80c0ee167 | |||
194f6c7880 | |||
fecce5dc09 | |||
088fbc0286 | |||
e6a5e548d5 | |||
6b8f28a6b5 | |||
1939911c54 | |||
780857f8e8 | |||
cdf01f7750 | |||
2e84edea97 | |||
ae3fee3f47 | |||
7a64e93761 | |||
016bd284fb | |||
40061911d2 | |||
38bb263422 | |||
216ebe0b73 | |||
acc662ea5a | |||
3a954af862 | |||
036b65d778 | |||
c96b1e4cda | |||
f12338f3ce | |||
e6d0a5be0e | |||
d0f59d3842 | |||
171f2e4949 | |||
![]() |
5d215d5225 | ||
c7d75a6616 | |||
b3fc885544 | |||
876fd40643 | |||
0e37d3efc0 | |||
087777f2b9 | |||
7d6f58271b | |||
cacc1d723c | |||
bc94036a76 | |||
75e8e01124 | |||
b2e00e8f8e | |||
9f89166b52 | |||
b8feac9c81 | |||
![]() |
821df20797 | ||
02bb3595d0 | |||
1b32679284 | |||
bc794109db | |||
cf91fb347d | |||
954af8c182 | |||
b62e98d4e2 | |||
6f88053d85 | |||
45d952e045 | |||
3fb5e83867 | |||
27e2c5ab78 | |||
16fab8ebc4 | |||
ca4ac742f4 | |||
93706de594 | |||
cba5d38256 | |||
3e5091bb21 | |||
b2ce1b0758 | |||
82b06f3112 | |||
f560dc6892 | |||
b0ab4b815a | |||
213f8294b5 | |||
1e355b0992 | |||
92b0803f35 | |||
71cb6923f5 | |||
323b7ad9cd | |||
2f60e5d1b5 | |||
7a62574338 | |||
5db9a008b9 | |||
099788c3e8 | |||
fcb7b0adcc | |||
e58ef7db5b | |||
9c4dbb592b | |||
57fc9f6082 | |||
fc6b04d4e3 | |||
4b04818d79 | |||
c8b324fe90 | |||
133966423a | |||
a51ff5208b | |||
3c7d5ec829 | |||
a6b31af37e | |||
![]() |
3726aa68c3 | ||
![]() |
6f054f5ac7 | ||
c0d2b10c59 | |||
0bd2f18a85 | |||
07e66f58cc | |||
a64a8d2b79 | |||
dfcfc8ee95 | |||
8948f73784 | |||
bf721fb679 | |||
3b66f40d40 | |||
573bda1fae | |||
92567c072a | |||
8214a63493 | |||
![]() |
51c8d53a7d | ||
7000eb00f8 | |||
b379f626ce | |||
9fdb32bf51 | |||
61d1fd7e2f | |||
39cfc95c2c | |||
78f7377c88 | |||
fcda0c7eb9 | |||
9509e18564 | |||
c1c77b7b9a | |||
10e093b30d | |||
862aa2a66b | |||
e6a5e33c09 | |||
057859620d | |||
93412cb4e7 | |||
87d3f4aff3 | |||
198980693b | |||
df135b74fc | |||
e285765a6b | |||
3c84851142 | |||
1f14c0d20c | |||
24f09b8f55 | |||
e36f3da31c | |||
3bb970f75a | |||
c604fd56a7 | |||
37e60289c2 | |||
ff74136da9 | |||
81235000d4 | |||
4c4ccdfa36 | |||
c71a8e8376 | |||
0e39c526d8 | |||
61e5c665b7 | |||
e1f2db669c | |||
ded4940901 | |||
![]() |
0af512abdf | ||
a6ca6f5af7 | |||
a8e3293b81 | |||
97e646b54a | |||
a4d07bafc6 | |||
f83aa830cd | |||
cfa97fd7f7 | |||
f48adcca64 | |||
9b80291412 | |||
![]() |
4fbeb3e6be | ||
6f7e2bf170 | |||
9457a0faf5 | |||
8e52d76bcd | |||
cd24712c2c | |||
eedf6c6295 | |||
6e32018499 | |||
89d9f5983c | |||
06e080c712 | |||
c92b5622ad | |||
3f8816eb6a | |||
75c426a60a | |||
ea01c8c5f6 | |||
4b7b4efd5b | |||
fc669a4c3e | |||
6e03a66e78 | |||
abb2215061 | |||
fb10eaf6e8 | |||
b036baa60a | |||
2c948ea405 | |||
7d24aa8aa8 | |||
e41a8bfabe | |||
5496d8cd36 | |||
d096d9c4d6 | |||
656f6ae643 | |||
733bcbed46 | |||
1f81195fb9 | |||
c32c6a5f85 | |||
1c4b0c47dd | |||
de3f369b30 | |||
874665d5e6 | |||
cdb8209b35 | |||
d9a63d40e2 | |||
556381c84a | |||
3d7d0f1f2e | |||
a6016bf5af | |||
60d85a3e60 | |||
23e108c5b6 | |||
ef28da2623 | |||
64612d57e2 | |||
18ea15cf2d | |||
6157c45445 | |||
82523840cd | |||
abd6b1d7b2 | |||
9cd4618390 | |||
ae5c15bb43 | |||
6d40d72189 | |||
c967208460 | |||
41979fc03b | |||
981380cf6d | |||
20504e555e | |||
f22e85d721 | |||
c9c79aad9e | |||
ff7a557c67 | |||
6fff85b2e4 | |||
89484e9754 | |||
fea585ded4 | |||
66f8835f9c | |||
3d3b6d94e6 | |||
66151b5de3 | |||
c1d0b234fb | |||
8d51c06611 | |||
20d0bb43af | |||
31f568c336 | |||
dde3ecc1a8 | |||
c51a5b204c | |||
e7e4b3c6af | |||
26b5760d6d | |||
![]() |
76ab0381d1 | ||
![]() |
532d3a103a | ||
84671d796d | |||
b665781808 | |||
ed809866b1 | |||
e6aece32a0 | |||
74633c0456 | |||
![]() |
c399651637 | ||
c3a4c6c209 | |||
4935ed6ce6 | |||
dc8b31af57 | |||
f066cee92f | |||
548d8a397c | |||
2a8122fb65 | |||
0d9f79b163 | |||
f21de01b84 | |||
7909f70f64 | |||
e9e054b987 | |||
71a8e32dc0 | |||
d55d95b04d | |||
![]() |
7d2f746369 | ||
![]() |
6499a2ec5c | ||
d7a2e0b83c | |||
![]() |
be262cf561 | ||
![]() |
0734b235d2 | ||
5841c1d819 | |||
f91aeaedb1 | |||
d7365bfdd5 | |||
9135370633 | |||
53ab14ffed | |||
ae1e68f514 | |||
0b55a9f886 | |||
70e064f111 | |||
c4f3475612 | |||
6249995c5e | |||
eaa726542e | |||
77f73a9284 | |||
a35c0fe6ce | |||
14f61c619b | |||
4fc54ddae1 | |||
1559aa3da0 | |||
![]() |
c134d7437d | ||
55936c060b | |||
6c6431809d | |||
3f0213d929 | |||
93e3aed041 | |||
aa030d3459 | |||
bf3875d6ac | |||
e137695436 | |||
8d78831fbd | |||
51c433f1a5 | |||
8a77019474 | |||
04f91bce53 | |||
b64f0fab06 | |||
2e67191c86 | |||
3656fc3aee | |||
3203340168 | |||
2a81d948ad | |||
5c490bcbc8 | |||
a9e12e50ae | |||
e623e62d3e | |||
ef6d652428 | |||
f226687bb9 | |||
4792d988fb | |||
e9a47223cb | |||
4bc7996e2e | |||
72a207de35 | |||
![]() |
601b690a24 | ||
![]() |
da2955fdf6 | ||
928aee934f | |||
f38479f9b4 | |||
7a005fb7d1 | |||
440c348323 | |||
6650310844 | |||
6a655eb871 | |||
c8067f798f | |||
371312cf2c | |||
dd2b616320 | |||
06fdbe6664 | |||
fba35a02c6 | |||
![]() |
5f2c5e5bb8 | ||
ebaa3fcedd | |||
7cb65a1e67 | |||
be8b60aa20 | |||
02404ded80 | |||
a0b85800ec | |||
3df2bea88b | |||
4d94e2afc8 | |||
2188047d9d | |||
52022cba78 | |||
![]() |
5f55022276 | ||
292685ea39 | |||
0cb264a282 | |||
17ac860cef | |||
32fd000b4b | |||
1ac3c861fd | |||
![]() |
5a1cef2e76 | ||
bf329d37da | |||
7a0281914e | |||
7f9ed0178a | |||
b90ccaa067 | |||
![]() |
5501a5de32 | ||
![]() |
d6bbcc4f66 | ||
6d21703e89 | |||
e16c786022 | |||
93c10797dc | |||
744fa41e7e | |||
77b51d4e58 | |||
6623d572aa | |||
9708aa6341 | |||
c5e409b013 | |||
850115531d | |||
652dd4e27f | |||
d1c6704413 | |||
cf6d17a6aa | |||
2fec46c3e6 | |||
c8d6e2dfa0 | |||
e90a2a3f01 | |||
f04206cbc7 | |||
b37fac5ff4 | |||
ec909e5d0f | |||
e747c07156 | |||
b449da3a7d | |||
db15df0baa | |||
fee0c90127 | |||
42732568d5 | |||
b94f1a63f1 | |||
aa065a2951 | |||
d3506c86da | |||
9ad181a5d0 | |||
9c088b1b97 | |||
2b0d08961a | |||
de9977260c | |||
e9cd3d50a7 | |||
9f3c5a061d | |||
e77c65f73c | |||
bd4ed5ca9a | |||
ded9484925 | |||
aaa1d58054 | |||
90bcd5e724 | |||
a1f44e43a2 | |||
5d6e5a9076 | |||
e91b59b589 | |||
e845467d93 | |||
735093dee8 | |||
3469e06c1a | |||
bbe6d44928 | |||
131a758b6f | |||
8f112af609 | |||
0c732382ae | |||
be7106a974 | |||
7e32bb8492 | |||
226eb5e366 | |||
18e063b69d | |||
7a07ca1f8c | |||
644976548d | |||
9fbf3075ad | |||
2ba2d2bd9d | |||
7f96e6ed7e | |||
6ac0a3d83c | |||
ae4a430755 | |||
526373b897 | |||
cd8893d446 | |||
d179e1c6e4 | |||
0373d1b09f | |||
8eaea99d98 | |||
![]() |
927d099ec0 | ||
![]() |
cdf564277c | ||
3a9d43cf31 | |||
2469ddc1a9 | |||
c0bbb93b88 | |||
421c5127f4 | |||
295b21f56a | |||
ee5a4f41eb | |||
141f17eaf4 | |||
8d958fe685 | |||
1a30687c24 | |||
4f3fba2aa7 | |||
665eca85ba | |||
7b528b2a3a | |||
99e5d5ba21 | |||
e391ad7bbc | |||
b9e07c1e0b | |||
96fa78f5b0 | |||
ca475479eb | |||
41982af6a0 | |||
f24992d2ec | |||
b4b02eb4ff | |||
ceb500df03 | |||
425e706921 | |||
a92ebab5da | |||
b32e8e5ba7 | |||
cfd54ad7d7 | |||
9c4c3fbabc | |||
3fd92b5c22 | |||
f817a11dc6 | |||
643420186c | |||
1135790ad5 | |||
84702bd3d8 | |||
f4d07196bd | |||
aff7d59986 | |||
324d6d2192 | |||
649c87814d | |||
9237b2019c | |||
35f379ba26 | |||
793547e7d1 | |||
985bc08688 | |||
eb45e7be47 | |||
![]() |
cd4e27a4a1 | ||
011a79215d | |||
d7cfee0b68 | |||
b243fab16b | |||
eaf5ee8981 | |||
41a945d746 | |||
7b45850eac | |||
b303769d2e | |||
c60c30205d | |||
4f3fb67c43 | |||
c07c110467 | |||
b33d839162 | |||
a823e825c8 | |||
e267afebf4 | |||
e69f8483ed | |||
0d599ce95a | |||
e12eb89f22 | |||
736b0d6894 | |||
1f691050e5 | |||
10d2cbfa36 | |||
1451f7d093 | |||
9f658822f9 | |||
fc5f9a8ac9 | |||
4a09907eab | |||
4f6ce899d4 | |||
6a8f4bfc60 | |||
b01c865687 | |||
87db3423c9 | |||
![]() |
a73dfac519 | ||
![]() |
9425628c84 | ||
f2988543c2 | |||
8e5b6320a6 | |||
![]() |
685419d6be | ||
91bf24dd00 | |||
f0ab9034d9 | |||
aee7d8f411 | |||
e69034e6d9 | |||
c082b21625 | |||
160d8c1ea6 | |||
fad8a753a9 | |||
2c31a84bd1 | |||
1db904d954 | |||
74c6c504b2 | |||
908b383b7d | |||
9f337bef80 | |||
8bd5d58860 | |||
255c850e0b | |||
b2a6e2abdb | |||
69d30c1543 | |||
41d1729148 | |||
6f47549fe5 | |||
c7f6309437 | |||
b2037464e4 | |||
be970c03c2 | |||
d3fe320b83 | |||
0706a756f9 | |||
63e898a0ff | |||
6290091bac | |||
da6dea5701 | |||
694032c9d1 | |||
c2e6969c56 | |||
bc95c249a7 | |||
bcdba7c34d | |||
02a63115d2 | |||
c371d699ca | |||
7d114e5d87 | |||
36f0a1ead7 | |||
b39ee69789 | |||
d311a76931 | |||
c3207d88c2 | |||
40e089716b | |||
05179a0ba4 | |||
8b777ee6d6 | |||
9a32c7130b | |||
d60b128274 | |||
a9203e25a2 | |||
089cd25982 | |||
a86bb2594f | |||
df2ed1550d | |||
1cc54107a9 | |||
d26588268d | |||
418cd7c4ba | |||
e25f7e33ff | |||
94e9d3ca3e | |||
d31dd1da80 | |||
2fa7e81d9c | |||
d144337098 | |||
58e554a55c | |||
09c7c63890 | |||
4b4aec2884 | |||
bfa083f873 | |||
239229c390 | |||
40d6ee5304 | |||
b5c3f26cba | |||
f17b26bbed | |||
0ac8fec3be | |||
0ca0d3366d | |||
f508292277 | |||
5e0ef4ef85 | |||
0145c8d484 | |||
0d8948387e | |||
ce0f212498 | |||
4fde594fda | |||
023ebb890b | |||
1c2b203795 | |||
a1fb3dc7ae | |||
3584f1d224 | |||
b4530deec4 | |||
e061bbadec | |||
dfdf79fb03 | |||
14e6f2f4db | |||
95af2e39f6 | |||
9f2271d354 | |||
6251eb8bda | |||
![]() |
c85317e669 | ||
![]() |
f7a5695676 | ||
34de342257 | |||
f071e41d63 | |||
dacce1d07f | |||
4ef0654449 | |||
502eadb2f7 | |||
ced673c833 | |||
9fb755fe4c | |||
2ee2f87f29 | |||
06da6e2eaf | |||
5f9358a373 | |||
14bb9f09ab | |||
54c28e5bfb | |||
ca476a638c | |||
66a87fc9f4 | |||
1e8ed36a90 | |||
![]() |
6fb7d0f559 | ||
2b2e65855a | |||
ef2ed3d737 | |||
4e8c78245d | |||
24cdffde55 | |||
f5ec29023d | |||
e02d84eb3b | |||
0a44c4b594 | |||
1e193a0b56 | |||
79dd9fedb2 | |||
3cc1bcce4f | |||
7573631d69 | |||
d4ffccbeae | |||
3adb9530bb | |||
3856c58f5d | |||
6403c8c025 | |||
39b752316d | |||
66161ba3a1 | |||
f7829961c6 | |||
ecffd231a0 | |||
fef7b792e7 | |||
cdfa3feb91 | |||
c4bbe44e47 | |||
2f0d919f89 | |||
8fd3ffcb31 | |||
27c142aa29 | |||
a8436334bd | |||
957de39191 | |||
![]() |
f71a7d3914 | ||
fa817b8c96 | |||
de60dc84e2 | |||
3a62ab73a3 | |||
bf7fdd0f67 | |||
2aa7bc06e7 | |||
ce317c9faa | |||
f1a577b38a | |||
dc69ef6f3b | |||
5cf04fe2ba | |||
319056679b | |||
69a7015e12 | |||
3459f75f5b | |||
0b0e45252b | |||
237e27e161 | |||
69b667d14e | |||
20a54347ee | |||
3732508c64 | |||
c4286ddb09 | |||
![]() |
340529a845 | ||
df96a9c6ea | |||
c63442d2f2 | |||
cab6d5e94a | |||
6c840a2cb9 | |||
a51584dc70 | |||
04572f0899 | |||
dc59955481 | |||
f03752b92f | |||
10ce2a1016 | |||
32e4ded24b | |||
09709a7e64 | |||
b75552ebbb | |||
40d391fa60 | |||
![]() |
7a4bdc3a4f | ||
![]() |
0f2ae614a1 | ||
30dd31a7b3 | |||
33a558bf21 | |||
5c1b740f1e | |||
0815e2fdb1 | |||
406d747695 | |||
9131c697dd | |||
e5ee7e9a2d | |||
8795514384 | |||
8ed7ed0255 | |||
53bd58993e | |||
3cc7e2ad9d | |||
![]() |
74f6b81c12 | ||
4e90266fd8 | |||
6704372f04 | |||
10423d462a | |||
6f28c199b3 | |||
a0029a678f | |||
8cdd701b45 | |||
442b6e5e09 | |||
9e038a2c6b | |||
4b1112c8c9 | |||
5cf87b4a8e | |||
ab536824a6 | |||
4b0871af87 | |||
![]() |
3191b76eb5 | ||
024ac9c089 | |||
e7c36ce43c | |||
3e4dd7b000 | |||
a4226a050b | |||
646f1cc89a | |||
f64746177f | |||
0876829e7a | |||
5804bf25bd | |||
c13383da41 | |||
01b9dfeab4 | |||
73169628a1 | |||
b6aa8daf49 | |||
c4c2c4bdb8 | |||
cf9709fd1e | |||
21b9231d7f | |||
00b2c7c5cc | |||
9dab489d51 | |||
08ee5573a9 | |||
09fe0e8aa9 | |||
d08ec3120f | |||
84c08748d8 | |||
a60e270efb | |||
8ad305382e | |||
5d826866a3 | |||
cfc9b95abd | |||
1f4c1c5fc7 | |||
bae4d00e2a | |||
7d749720ad | |||
8df0268e2b | |||
80578a9d54 | |||
2771dfd563 | |||
ad4202a14f | |||
89f490932f | |||
![]() |
55c56f1ffb | ||
5f411f7f38 | |||
![]() |
78011d712d | ||
d985751324 | |||
ed1042ee06 | |||
76fd41e9db | |||
0f95f51361 | |||
2cd091e9c7 | |||
![]() |
dc170a6d67 | ||
8964c02348 | |||
8185d07ace | |||
38df935c09 | |||
aed5b88ec1 | |||
![]() |
27b78c9c94 | ||
614bd239f8 | |||
7b68d0679e | |||
7af8271c34 | |||
ba44919601 | |||
0b711e6758 | |||
3f7c294a95 | |||
97a6b3ceee | |||
37c5552742 | |||
![]() |
5d99199880 | ||
92826a921c | |||
bc58425862 | |||
b9e02eace6 | |||
6b5e4ad589 | |||
144d9b901e |
@@ -10,8 +10,9 @@
|
|||||||
# Changes that belong here:
|
# Changes that belong here:
|
||||||
# - Massive comment, doxy-sections, or spelling corrections.
|
# - Massive comment, doxy-sections, or spelling corrections.
|
||||||
# - Clang-format, PEP8 or other automated changes which are *strictly* "no functional change".
|
# - Clang-format, PEP8 or other automated changes which are *strictly* "no functional change".
|
||||||
# - Several smaller commits should be added to this list at once, because adding
|
# - Several commits should be added to this list at once, because adding
|
||||||
# one extra commit (to edit this file) after every small cleanup is noisy.
|
# one extra commit (to edit this file) after every cleanup is noisy.
|
||||||
|
# - No clang-tidy changes.
|
||||||
#
|
#
|
||||||
# Note:
|
# Note:
|
||||||
# - The comment above the SHA should be the first line of the commit.
|
# - The comment above the SHA should be the first line of the commit.
|
||||||
@@ -92,78 +93,12 @@ c42a6b77b52560d257279de2cb624b4ef2c0d24c
|
|||||||
# Cleanup: use doxy sections for imbuf
|
# Cleanup: use doxy sections for imbuf
|
||||||
c207f7c22e1439e0b285fba5d2c072bdae23f981
|
c207f7c22e1439e0b285fba5d2c072bdae23f981
|
||||||
|
|
||||||
# Cleanup: Clang-Tidy, modernize-use-bool-literals
|
|
||||||
af35ada2f3fa8da4d46b3a71de724d353d716820
|
|
||||||
|
|
||||||
# Cleanup: Use nullptr everywhere in fluid code
|
|
||||||
311031ecd03dbfbf43e1df672a395f24b2e7d4d3
|
|
||||||
|
|
||||||
# Cleanup: Clang-Tidy, modernize-redundant-void-arg
|
|
||||||
a331d5c99299c4514ca33c843b1c79b872f2728d
|
|
||||||
|
|
||||||
# Cleanup: Clang-Tidy modernize-use-nullptr
|
|
||||||
16732def37c5a66f3ea28dbe247b09cc6bca6677
|
|
||||||
|
|
||||||
# Cleanup: Clang-tidy, modernize-concat-nested-namespaces
|
|
||||||
4525049aa0cf818f6483dce589ac9791eb562338
|
|
||||||
|
|
||||||
# Cleanup: Clang-tidy else-after-return
|
|
||||||
ae342ed4511cf2e144dcd27ce2c635d3d536f9ad
|
|
||||||
|
|
||||||
# Cleanup: Clang-Tidy, readability-redundant-member-init
|
|
||||||
190170d4cc92ff34abe1744a10474ac4f1074086
|
|
||||||
|
|
||||||
# Cleanup: use 'filepath' instead of 'name' for ImBuf utilities
|
|
||||||
99f56b4c16323f96c0cbf54e392fb509fcac5bda
|
|
||||||
|
|
||||||
# Cleanup: clang-format
|
# Cleanup: clang-format
|
||||||
c4d8f6a4a8ddc29ed27311ed7578b3c8c31399d2
|
c4d8f6a4a8ddc29ed27311ed7578b3c8c31399d2
|
||||||
b5d310b569e07a937798a2d38539cfd290149f1c
|
b5d310b569e07a937798a2d38539cfd290149f1c
|
||||||
8c846cccd6bdfd3e90a695fabbf05f53e5466a57
|
8c846cccd6bdfd3e90a695fabbf05f53e5466a57
|
||||||
40d4a4cb1a6b4c3c2a486e8f2868f547530e0811
|
|
||||||
4eac03d821fa17546f562485f7d073813a5e5943
|
4eac03d821fa17546f562485f7d073813a5e5943
|
||||||
|
1166110a9d66af9c5a47cee2be591f50fdc445e8
|
||||||
|
|
||||||
# Cleanup: use preprocessor version check for PyTypeObject declaration
|
# Cleanup: clang-format.
|
||||||
cd9acfed4f7674b84be965d469a367aef96f8af3
|
40d4a4cb1a6b4c3c2a486e8f2868f547530e0811
|
||||||
|
|
||||||
# Cycles: fix compilation of OSL shaders following API change
|
|
||||||
b980cd163a9d5d77eeffc2e353333e739fa9e719
|
|
||||||
|
|
||||||
# Cleanup: clang-tidy suppress warnings for PyTypeObject.tp_print
|
|
||||||
efd71aad4f22ec0073d80b8dd296015d3f395aa8
|
|
||||||
|
|
||||||
# Cleanup: fix wrong merge, remove extra unique_ptr.
|
|
||||||
6507449e54a167c63a72229e4d0119dd2af68ae5
|
|
||||||
|
|
||||||
# Cleanup: fix some clang tidy issues
|
|
||||||
525a042c5c7513c41240b118acca002f6c60cc12
|
|
||||||
|
|
||||||
# Fix T82520: error building freestyle with Python3.8
|
|
||||||
e118426e4695a97d67e65d69677f3c4e2db50a56
|
|
||||||
|
|
||||||
# Cleanup: Clang-tidy, readability-else-after-return
|
|
||||||
7be47dadea5066ae095c644e0b4f1f10d75f5ab3
|
|
||||||
|
|
||||||
# Cleanup: Add `r_` to return parameter
|
|
||||||
45dca05b1cd2a5ead59144c93d790fdfe7c35ee6
|
|
||||||
|
|
||||||
# Cleanup: Typo in `print_default_info` function name.
|
|
||||||
41a73909dec716642f044e60b40a28335c9fdb10
|
|
||||||
|
|
||||||
# Cleanup: Reduce indentation
|
|
||||||
1cc3a0e2cf73a5ff4f9e0a7f5338eda77266b300
|
|
||||||
|
|
||||||
# Build-system: Force C linkage for all DNA type headers
|
|
||||||
ad4b7741dba45a2be210942c18af6b6e4438f129
|
|
||||||
|
|
||||||
# Cleanup: Move function to proper section
|
|
||||||
c126e27cdc8b28365a9d5f9fafc4d521d1eb83df
|
|
||||||
|
|
||||||
# Cleanup: remove break after return statements
|
|
||||||
bbdfeb751e16d939482d2e4b95c4d470f53f18a5
|
|
||||||
|
|
||||||
# Cleanup: clang-tidy
|
|
||||||
af013ff76feef7e8b8ba642279c62a5dc275d59f
|
|
||||||
|
|
||||||
# Cleanup: Make panel type flag names more clear
|
|
||||||
9d28353b525ecfbcca1501be72e4276dfb2bbc2a
|
|
||||||
|
@@ -205,6 +205,7 @@ option(WITH_OPENVDB_BLOSC "Enable blosc compression for OpenVDB, only enable if
|
|||||||
option(WITH_OPENVDB_3_ABI_COMPATIBLE "Assume OpenVDB library has been compiled with version 3 ABI compatibility" OFF)
|
option(WITH_OPENVDB_3_ABI_COMPATIBLE "Assume OpenVDB library has been compiled with version 3 ABI compatibility" OFF)
|
||||||
mark_as_advanced(WITH_OPENVDB_3_ABI_COMPATIBLE)
|
mark_as_advanced(WITH_OPENVDB_3_ABI_COMPATIBLE)
|
||||||
option(WITH_NANOVDB "Enable usage of NanoVDB data structure for rendering on the GPU" ON)
|
option(WITH_NANOVDB "Enable usage of NanoVDB data structure for rendering on the GPU" ON)
|
||||||
|
option(WITH_HARU "Enable features relying on Libharu (Grease pencil PDF export)" ON)
|
||||||
|
|
||||||
# GHOST Windowing Library Options
|
# GHOST Windowing Library Options
|
||||||
option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF)
|
option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF)
|
||||||
@@ -730,6 +731,9 @@ set_and_warn_dependency(WITH_OPENVDB WITH_NANOVDB OFF)
|
|||||||
# OpenVDB uses 'half' type from OpenEXR & fails to link without OpenEXR enabled.
|
# OpenVDB uses 'half' type from OpenEXR & fails to link without OpenEXR enabled.
|
||||||
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENVDB OFF)
|
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENVDB OFF)
|
||||||
|
|
||||||
|
# Haru needs `TIFFFaxBlackCodes` & `TIFFFaxWhiteCodes` symbols from TIFF.
|
||||||
|
set_and_warn_dependency(WITH_IMAGE_TIFF WITH_HARU OFF)
|
||||||
|
|
||||||
# auto enable openimageio for cycles
|
# auto enable openimageio for cycles
|
||||||
if(WITH_CYCLES)
|
if(WITH_CYCLES)
|
||||||
set(WITH_OPENIMAGEIO ON)
|
set(WITH_OPENIMAGEIO ON)
|
||||||
@@ -1763,8 +1767,20 @@ if(WITH_BLENDER)
|
|||||||
# internal and external library information first, for test linking
|
# internal and external library information first, for test linking
|
||||||
add_subdirectory(source)
|
add_subdirectory(source)
|
||||||
elseif(WITH_CYCLES_STANDALONE)
|
elseif(WITH_CYCLES_STANDALONE)
|
||||||
|
add_subdirectory(intern/glew-mx)
|
||||||
|
add_subdirectory(intern/guardedalloc)
|
||||||
|
add_subdirectory(intern/libc_compat)
|
||||||
|
add_subdirectory(intern/numaapi)
|
||||||
|
add_subdirectory(intern/sky)
|
||||||
|
|
||||||
add_subdirectory(intern/cycles)
|
add_subdirectory(intern/cycles)
|
||||||
add_subdirectory(extern/clew)
|
add_subdirectory(extern/clew)
|
||||||
|
if(WITH_CYCLES_LOGGING)
|
||||||
|
if(NOT WITH_SYSTEM_GFLAGS)
|
||||||
|
add_subdirectory(extern/gflags)
|
||||||
|
endif()
|
||||||
|
add_subdirectory(extern/glog)
|
||||||
|
endif()
|
||||||
if(WITH_CUDA_DYNLOAD)
|
if(WITH_CUDA_DYNLOAD)
|
||||||
add_subdirectory(extern/cuew)
|
add_subdirectory(extern/cuew)
|
||||||
endif()
|
endif()
|
||||||
@@ -1837,6 +1853,7 @@ if(FIRST_RUN)
|
|||||||
info_cfg_option(WITH_FFTW3)
|
info_cfg_option(WITH_FFTW3)
|
||||||
info_cfg_option(WITH_FREESTYLE)
|
info_cfg_option(WITH_FREESTYLE)
|
||||||
info_cfg_option(WITH_GMP)
|
info_cfg_option(WITH_GMP)
|
||||||
|
info_cfg_option(WITH_HARU)
|
||||||
info_cfg_option(WITH_IK_ITASC)
|
info_cfg_option(WITH_IK_ITASC)
|
||||||
info_cfg_option(WITH_IK_SOLVER)
|
info_cfg_option(WITH_IK_SOLVER)
|
||||||
info_cfg_option(WITH_INPUT_NDOF)
|
info_cfg_option(WITH_INPUT_NDOF)
|
||||||
@@ -1845,6 +1862,8 @@ if(FIRST_RUN)
|
|||||||
info_cfg_option(WITH_OPENCOLORIO)
|
info_cfg_option(WITH_OPENCOLORIO)
|
||||||
info_cfg_option(WITH_OPENIMAGEDENOISE)
|
info_cfg_option(WITH_OPENIMAGEDENOISE)
|
||||||
info_cfg_option(WITH_OPENVDB)
|
info_cfg_option(WITH_OPENVDB)
|
||||||
|
info_cfg_option(WITH_POTRACE)
|
||||||
|
info_cfg_option(WITH_PUGIXML)
|
||||||
info_cfg_option(WITH_QUADRIFLOW)
|
info_cfg_option(WITH_QUADRIFLOW)
|
||||||
info_cfg_option(WITH_TBB)
|
info_cfg_option(WITH_TBB)
|
||||||
info_cfg_option(WITH_USD)
|
info_cfg_option(WITH_USD)
|
||||||
|
13
GNUmakefile
13
GNUmakefile
@@ -183,8 +183,13 @@ endif
|
|||||||
ifndef DEPS_INSTALL_DIR
|
ifndef DEPS_INSTALL_DIR
|
||||||
DEPS_INSTALL_DIR:=$(shell dirname "$(BLENDER_DIR)")/lib/$(OS_NCASE)
|
DEPS_INSTALL_DIR:=$(shell dirname "$(BLENDER_DIR)")/lib/$(OS_NCASE)
|
||||||
|
|
||||||
ifneq ($(OS_NCASE),darwin)
|
# Add processor type to directory name, except for darwin x86_64
|
||||||
# Add processor type to directory name
|
# which by convention does not have it.
|
||||||
|
ifeq ($(OS_NCASE),darwin)
|
||||||
|
ifneq ($(CPU),x86_64)
|
||||||
|
DEPS_INSTALL_DIR:=$(DEPS_INSTALL_DIR)_$(CPU)
|
||||||
|
endif
|
||||||
|
else
|
||||||
DEPS_INSTALL_DIR:=$(DEPS_INSTALL_DIR)_$(CPU)
|
DEPS_INSTALL_DIR:=$(DEPS_INSTALL_DIR)_$(CPU)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@@ -198,7 +203,7 @@ endif
|
|||||||
# in libraries, or python 2 for running make update to get it.
|
# in libraries, or python 2 for running make update to get it.
|
||||||
ifeq ($(OS_NCASE),darwin)
|
ifeq ($(OS_NCASE),darwin)
|
||||||
ifeq (, $(shell command -v $(PYTHON)))
|
ifeq (, $(shell command -v $(PYTHON)))
|
||||||
PYTHON:=../lib/darwin/python/bin/python3.7m
|
PYTHON:=$(DEPS_INSTALL_DIR)/python/bin/python3.7m
|
||||||
ifeq (, $(shell command -v $(PYTHON)))
|
ifeq (, $(shell command -v $(PYTHON)))
|
||||||
PYTHON:=python
|
PYTHON:=python
|
||||||
endif
|
endif
|
||||||
@@ -520,7 +525,7 @@ format: .FORCE
|
|||||||
|
|
||||||
# Simple version of ./doc/python_api/sphinx_doc_gen.sh with no PDF generation.
|
# Simple version of ./doc/python_api/sphinx_doc_gen.sh with no PDF generation.
|
||||||
doc_py: .FORCE
|
doc_py: .FORCE
|
||||||
ASAN_OPTIONS=halt_on_error=0 \
|
ASAN_OPTIONS=halt_on_error=0:${ASAN_OPTIONS} \
|
||||||
$(BLENDER_BIN) --background -noaudio --factory-startup \
|
$(BLENDER_BIN) --background -noaudio --factory-startup \
|
||||||
--python doc/python_api/sphinx_doc_gen.py
|
--python doc/python_api/sphinx_doc_gen.py
|
||||||
sphinx-build -b html -j $(NPROCS) doc/python_api/sphinx-in doc/python_api/sphinx-out
|
sphinx-build -b html -j $(NPROCS) doc/python_api/sphinx-in doc/python_api/sphinx-out
|
||||||
|
@@ -92,6 +92,7 @@ include(cmake/package_python.cmake)
|
|||||||
include(cmake/numpy.cmake)
|
include(cmake/numpy.cmake)
|
||||||
include(cmake/usd.cmake)
|
include(cmake/usd.cmake)
|
||||||
include(cmake/potrace.cmake)
|
include(cmake/potrace.cmake)
|
||||||
|
include(cmake/haru.cmake)
|
||||||
# Boost needs to be included after python.cmake due to the PYTHON_BINARY variable being needed.
|
# Boost needs to be included after python.cmake due to the PYTHON_BINARY variable being needed.
|
||||||
include(cmake/boost.cmake)
|
include(cmake/boost.cmake)
|
||||||
include(cmake/pugixml.cmake)
|
include(cmake/pugixml.cmake)
|
||||||
|
46
build_files/build_environment/cmake/haru.cmake
Normal file
46
build_files/build_environment/cmake/haru.cmake
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# ***** 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.
|
||||||
|
#
|
||||||
|
# ***** END GPL LICENSE BLOCK *****
|
||||||
|
|
||||||
|
set(HARU_EXTRA_ARGS
|
||||||
|
-DLIBHPDF_SHARED=OFF
|
||||||
|
-DLIBHPDF_STATIC=ON
|
||||||
|
-DLIBHPDF_EXAMPLES=OFF
|
||||||
|
-DLIBHPDF_ENABLE_EXCEPTIONS=ON
|
||||||
|
)
|
||||||
|
|
||||||
|
ExternalProject_Add(external_haru
|
||||||
|
URL ${HARU_URI}
|
||||||
|
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||||
|
URL_HASH MD5=${HARU_HASH}
|
||||||
|
PREFIX ${BUILD_DIR}/haru
|
||||||
|
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/haru/src/external_haru < ${PATCH_DIR}/haru.diff
|
||||||
|
CMAKE_ARGS
|
||||||
|
-DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_PREFIX=${LIBDIR}/haru
|
||||||
|
${DEFAULT_CMAKE_FLAGS} ${HARU_EXTRA_ARGS}
|
||||||
|
INSTALL_DIR ${LIBDIR}/haru
|
||||||
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
if(BUILD_MODE STREQUAL Release)
|
||||||
|
ExternalProject_Add_Step(external_haru after_install
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/haru/include ${HARVEST_TARGET}/haru/include
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/haru/lib/libhpdfs.lib ${HARVEST_TARGET}/haru/lib/libhpdfs.lib
|
||||||
|
DEPENDEES install
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
@@ -187,6 +187,8 @@ harvest(usd/lib/usd usd/lib/usd "*")
|
|||||||
harvest(usd/plugin usd/plugin "*")
|
harvest(usd/plugin usd/plugin "*")
|
||||||
harvest(potrace/include potrace/include "*.h")
|
harvest(potrace/include potrace/include "*.h")
|
||||||
harvest(potrace/lib potrace/lib "*.a")
|
harvest(potrace/lib potrace/lib "*.a")
|
||||||
|
harvest(haru/include haru/include "*.h")
|
||||||
|
harvest(haru/lib haru/lib "*.a")
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
harvest(libglu/lib mesa/lib "*.so*")
|
harvest(libglu/lib mesa/lib "*.so*")
|
||||||
|
@@ -42,7 +42,7 @@ if(UNIX)
|
|||||||
-DSQLITE_MAX_VARIABLE_NUMBER=250000 \
|
-DSQLITE_MAX_VARIABLE_NUMBER=250000 \
|
||||||
-fPIC")
|
-fPIC")
|
||||||
set(SQLITE_CONFIGURE_ENV ${SQLITE_CONFIGURE_ENV} && export LDFLAGS=${SQLITE_LDFLAGS} && export CFLAGS=${SQLITE_CFLAGS})
|
set(SQLITE_CONFIGURE_ENV ${SQLITE_CONFIGURE_ENV} && export LDFLAGS=${SQLITE_LDFLAGS} && export CFLAGS=${SQLITE_CFLAGS})
|
||||||
set(SQLITE_CONFIGURATION_ARGS ${SQLITE_CONFIGURATION_ARGS} --enable-threadsafe --enable-load-extension --enable-json1 --enable-fts4 --enable-fts5
|
set(SQLITE_CONFIGURATION_ARGS ${SQLITE_CONFIGURATION_ARGS} --enable-threadsafe --enable-load-extension --enable-json1 --enable-fts4 --enable-fts5 --disable-tcl
|
||||||
--enable-shared=no)
|
--enable-shared=no)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@@ -331,3 +331,7 @@ set(GMP_HASH a325e3f09e6d91e62101e59f9bda3ec1)
|
|||||||
set(POTRACE_VERSION 1.16)
|
set(POTRACE_VERSION 1.16)
|
||||||
set(POTRACE_URI http://potrace.sourceforge.net/download/${POTRACE_VERSION}/potrace-${POTRACE_VERSION}.tar.gz)
|
set(POTRACE_URI http://potrace.sourceforge.net/download/${POTRACE_VERSION}/potrace-${POTRACE_VERSION}.tar.gz)
|
||||||
set(POTRACE_HASH 5f0bd87ddd9a620b0c4e65652ef93d69)
|
set(POTRACE_HASH 5f0bd87ddd9a620b0c4e65652ef93d69)
|
||||||
|
|
||||||
|
set(HARU_VERSION 2_3_0)
|
||||||
|
set(HARU_URI https://github.com/libharu/libharu/archive/RELEASE_${HARU_VERSION}.tar.gz)
|
||||||
|
set(HARU_HASH 4f916aa49c3069b3a10850013c507460)
|
||||||
|
@@ -385,25 +385,25 @@ USE_CXX11=true
|
|||||||
CLANG_FORMAT_VERSION_MIN="6.0"
|
CLANG_FORMAT_VERSION_MIN="6.0"
|
||||||
CLANG_FORMAT_VERSION_MAX="10.0"
|
CLANG_FORMAT_VERSION_MAX="10.0"
|
||||||
|
|
||||||
PYTHON_VERSION="3.7.7"
|
PYTHON_VERSION="3.9.1"
|
||||||
PYTHON_VERSION_SHORT="3.7"
|
PYTHON_VERSION_SHORT="3.9"
|
||||||
PYTHON_VERSION_MIN="3.7"
|
PYTHON_VERSION_MIN="3.7"
|
||||||
PYTHON_VERSION_MAX="3.9"
|
PYTHON_VERSION_MAX="3.10"
|
||||||
PYTHON_VERSION_INSTALLED=$PYTHON_VERSION_MIN
|
PYTHON_VERSION_INSTALLED=$PYTHON_VERSION_MIN
|
||||||
PYTHON_FORCE_BUILD=false
|
PYTHON_FORCE_BUILD=false
|
||||||
PYTHON_FORCE_REBUILD=false
|
PYTHON_FORCE_REBUILD=false
|
||||||
PYTHON_SKIP=false
|
PYTHON_SKIP=false
|
||||||
|
|
||||||
NUMPY_VERSION="1.17.5"
|
NUMPY_VERSION="1.19.5"
|
||||||
NUMPY_VERSION_SHORT="1.17"
|
NUMPY_VERSION_SHORT="1.19"
|
||||||
NUMPY_VERSION_MIN="1.8"
|
NUMPY_VERSION_MIN="1.8"
|
||||||
NUMPY_VERSION_MAX="2.0"
|
NUMPY_VERSION_MAX="2.0"
|
||||||
NUMPY_FORCE_BUILD=false
|
NUMPY_FORCE_BUILD=false
|
||||||
NUMPY_FORCE_REBUILD=false
|
NUMPY_FORCE_REBUILD=false
|
||||||
NUMPY_SKIP=false
|
NUMPY_SKIP=false
|
||||||
|
|
||||||
BOOST_VERSION="1.70.0"
|
BOOST_VERSION="1.73.0"
|
||||||
BOOST_VERSION_SHORT="1.70"
|
BOOST_VERSION_SHORT="1.73"
|
||||||
BOOST_VERSION_MIN="1.49"
|
BOOST_VERSION_MIN="1.49"
|
||||||
BOOST_VERSION_MAX="2.0"
|
BOOST_VERSION_MAX="2.0"
|
||||||
BOOST_FORCE_BUILD=false
|
BOOST_FORCE_BUILD=false
|
||||||
@@ -439,7 +439,7 @@ _with_built_openexr=false
|
|||||||
OIIO_VERSION="2.1.15.0"
|
OIIO_VERSION="2.1.15.0"
|
||||||
OIIO_VERSION_SHORT="2.1"
|
OIIO_VERSION_SHORT="2.1"
|
||||||
OIIO_VERSION_MIN="2.1.12"
|
OIIO_VERSION_MIN="2.1.12"
|
||||||
OIIO_VERSION_MAX="3.0"
|
OIIO_VERSION_MAX="2.2.10"
|
||||||
OIIO_FORCE_BUILD=false
|
OIIO_FORCE_BUILD=false
|
||||||
OIIO_FORCE_REBUILD=false
|
OIIO_FORCE_REBUILD=false
|
||||||
OIIO_SKIP=false
|
OIIO_SKIP=false
|
||||||
@@ -483,7 +483,7 @@ OPENVDB_FORCE_REBUILD=false
|
|||||||
OPENVDB_SKIP=false
|
OPENVDB_SKIP=false
|
||||||
|
|
||||||
# Alembic needs to be compiled for now
|
# Alembic needs to be compiled for now
|
||||||
ALEMBIC_VERSION="1.7.12"
|
ALEMBIC_VERSION="1.7.16"
|
||||||
ALEMBIC_VERSION_SHORT="1.7"
|
ALEMBIC_VERSION_SHORT="1.7"
|
||||||
ALEMBIC_VERSION_MIN="1.7"
|
ALEMBIC_VERSION_MIN="1.7"
|
||||||
ALEMBIC_VERSION_MAX="2.0"
|
ALEMBIC_VERSION_MAX="2.0"
|
||||||
@@ -2064,7 +2064,6 @@ compile_OIIO() {
|
|||||||
cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst"
|
cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst"
|
||||||
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
|
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
|
||||||
cmake_d="$cmake_d -D STOP_ON_WARNING=OFF"
|
cmake_d="$cmake_d -D STOP_ON_WARNING=OFF"
|
||||||
cmake_d="$cmake_d -D BUILDSTATIC=OFF"
|
|
||||||
cmake_d="$cmake_d -D LINKSTATIC=OFF"
|
cmake_d="$cmake_d -D LINKSTATIC=OFF"
|
||||||
cmake_d="$cmake_d -D USE_SIMD=sse2"
|
cmake_d="$cmake_d -D USE_SIMD=sse2"
|
||||||
|
|
||||||
@@ -2099,9 +2098,6 @@ compile_OIIO() {
|
|||||||
# if [ -d $INST/ocio ]; then
|
# if [ -d $INST/ocio ]; then
|
||||||
# cmake_d="$cmake_d -D OCIO_PATH=$INST/ocio"
|
# cmake_d="$cmake_d -D OCIO_PATH=$INST/ocio"
|
||||||
# fi
|
# fi
|
||||||
cmake_d="$cmake_d -D USE_OCIO=OFF"
|
|
||||||
|
|
||||||
cmake_d="$cmake_d -D OIIO_BUILD_CPP11=ON"
|
|
||||||
|
|
||||||
if file /bin/cp | grep -q '32-bit'; then
|
if file /bin/cp | grep -q '32-bit'; then
|
||||||
cflags="-fPIC -m32 -march=i686"
|
cflags="-fPIC -m32 -march=i686"
|
||||||
|
12
build_files/build_environment/patches/haru.diff
Normal file
12
build_files/build_environment/patches/haru.diff
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
diff --git a/src/hpdf_image_ccitt.c b/src/hpdf_image_ccitt.c
|
||||||
|
index 8672763..9be531a 100644
|
||||||
|
--- a/src/hpdf_image_ccitt.c
|
||||||
|
+++ b/src/hpdf_image_ccitt.c
|
||||||
|
@@ -21,7 +21,6 @@
|
||||||
|
#include <memory.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
-#define G3CODES
|
||||||
|
#include "t4.h"
|
||||||
|
|
||||||
|
typedef unsigned int uint32;
|
@@ -88,7 +88,6 @@ class VersionInfo:
|
|||||||
self.short_version = "%d.%02d" % (version_numbers[0], version_numbers[1])
|
self.short_version = "%d.%02d" % (version_numbers[0], version_numbers[1])
|
||||||
self.version = "%d.%02d.%d" % version_numbers
|
self.version = "%d.%02d.%d" % version_numbers
|
||||||
self.version_cycle = self._parse_header_file(blender_h, 'BLENDER_VERSION_CYCLE')
|
self.version_cycle = self._parse_header_file(blender_h, 'BLENDER_VERSION_CYCLE')
|
||||||
self.version_cycle_number = self._parse_header_file(blender_h, 'BLENDER_VERSION_CYCLE_NUMBER')
|
|
||||||
self.hash = self._parse_header_file(buildinfo_h, 'BUILD_HASH')[1:-1]
|
self.hash = self._parse_header_file(buildinfo_h, 'BUILD_HASH')[1:-1]
|
||||||
|
|
||||||
if self.version_cycle == "release":
|
if self.version_cycle == "release":
|
||||||
@@ -97,8 +96,7 @@ class VersionInfo:
|
|||||||
self.is_development_build = False
|
self.is_development_build = False
|
||||||
elif self.version_cycle == "rc":
|
elif self.version_cycle == "rc":
|
||||||
# Release candidate
|
# Release candidate
|
||||||
version_cycle = self.version_cycle + self.version_cycle_number
|
self.full_version = self.version + self.version_cycle
|
||||||
self.full_version = self.version + version_cycle
|
|
||||||
self.is_development_build = False
|
self.is_development_build = False
|
||||||
else:
|
else:
|
||||||
# Development build
|
# Development build
|
||||||
|
@@ -34,6 +34,8 @@ set(_clang_tidy_SEARCH_DIRS
|
|||||||
# TODO(sergey): Find more reliable way of finding the latest clang-tidy.
|
# TODO(sergey): Find more reliable way of finding the latest clang-tidy.
|
||||||
find_program(CLANG_TIDY_EXECUTABLE
|
find_program(CLANG_TIDY_EXECUTABLE
|
||||||
NAMES
|
NAMES
|
||||||
|
clang-tidy-12
|
||||||
|
clang-tidy-11
|
||||||
clang-tidy-10
|
clang-tidy-10
|
||||||
clang-tidy-9
|
clang-tidy-9
|
||||||
clang-tidy-8
|
clang-tidy-8
|
||||||
|
64
build_files/cmake/Modules/FindHaru.cmake
Normal file
64
build_files/cmake/Modules/FindHaru.cmake
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# - Find HARU library
|
||||||
|
# Find the native Haru includes and library
|
||||||
|
# This module defines
|
||||||
|
# HARU_INCLUDE_DIRS, where to find hpdf.h, set when
|
||||||
|
# HARU_INCLUDE_DIR is found.
|
||||||
|
# HARU_LIBRARIES, libraries to link against to use Haru.
|
||||||
|
# HARU_ROOT_DIR, The base directory to search for Haru.
|
||||||
|
# This can also be an environment variable.
|
||||||
|
# HARU_FOUND, If false, do not try to use Haru.
|
||||||
|
#
|
||||||
|
# also defined, but not for general use are
|
||||||
|
# HARU_LIBRARY, where to find the Haru library.
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2021 Blender Foundation.
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD 3-Clause License,
|
||||||
|
# see accompanying file BSD-3-Clause-license.txt for details.
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
|
# If HARU_ROOT_DIR was defined in the environment, use it.
|
||||||
|
if(NOT HARU_ROOT_DIR AND NOT $ENV{HARU_ROOT_DIR} STREQUAL "")
|
||||||
|
set(HARU_ROOT_DIR $ENV{HARU_ROOT_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_haru_SEARCH_DIRS
|
||||||
|
${HARU_ROOT_DIR}
|
||||||
|
/opt/lib/haru
|
||||||
|
)
|
||||||
|
|
||||||
|
find_path(HARU_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
hpdf.h
|
||||||
|
HINTS
|
||||||
|
${_haru_SEARCH_DIRS}
|
||||||
|
PATH_SUFFIXES
|
||||||
|
include/haru
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(HARU_LIBRARY
|
||||||
|
NAMES
|
||||||
|
hpdfs
|
||||||
|
HINTS
|
||||||
|
${_haru_SEARCH_DIRS}
|
||||||
|
PATH_SUFFIXES
|
||||||
|
lib64 lib
|
||||||
|
)
|
||||||
|
|
||||||
|
# Handle the QUIETLY and REQUIRED arguments and set HARU_FOUND to TRUE if
|
||||||
|
# all listed variables are TRUE.
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(Haru DEFAULT_MSG HARU_LIBRARY HARU_INCLUDE_DIR)
|
||||||
|
|
||||||
|
if(HARU_FOUND)
|
||||||
|
set(HARU_LIBRARIES ${HARU_LIBRARY})
|
||||||
|
set(HARU_INCLUDE_DIRS ${HARU_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
mark_as_advanced(
|
||||||
|
HARU_INCLUDE_DIR
|
||||||
|
HARU_LIBRARY
|
||||||
|
)
|
||||||
|
|
||||||
|
unset(_haru_SEARCH_DIRS)
|
@@ -99,7 +99,9 @@ macro(BLENDER_SRC_GTEST_EX)
|
|||||||
|
|
||||||
# Don't fail tests on leaks since these often happen in external libraries
|
# Don't fail tests on leaks since these often happen in external libraries
|
||||||
# that we can't fix.
|
# that we can't fix.
|
||||||
set_tests_properties(${TARGET_NAME} PROPERTIES ENVIRONMENT LSAN_OPTIONS=exitcode=0)
|
set_tests_properties(${TARGET_NAME} PROPERTIES
|
||||||
|
ENVIRONMENT LSAN_OPTIONS=exitcode=0:$ENV{LSAN_OPTIONS}
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set_target_properties(${TARGET_NAME} PROPERTIES VS_GLOBAL_VcpkgEnabled "false")
|
set_target_properties(${TARGET_NAME} PROPERTIES VS_GLOBAL_VcpkgEnabled "false")
|
||||||
|
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# Note: this code should be cleaned up / refactored.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
if sys.version_info.major < 3:
|
if sys.version_info.major < 3:
|
||||||
print("\nPython3.x needed, found %s.\nAborting!\n" %
|
print("\nPython3.x needed, found %s.\nAborting!\n" %
|
||||||
@@ -37,12 +39,23 @@ from cmake_consistency_check_config import (
|
|||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from os.path import join, dirname, normpath, splitext
|
from os.path import (
|
||||||
|
dirname,
|
||||||
|
join,
|
||||||
|
normpath,
|
||||||
|
splitext,
|
||||||
|
)
|
||||||
|
|
||||||
global_h = set()
|
global_h = set()
|
||||||
global_c = set()
|
global_c = set()
|
||||||
global_refs = {}
|
global_refs = {}
|
||||||
|
|
||||||
|
# Flatten `IGNORE_SOURCE_MISSING` to avoid nested looping.
|
||||||
|
IGNORE_SOURCE_MISSING = [
|
||||||
|
(k, ignore_path) for k, ig_list in IGNORE_SOURCE_MISSING
|
||||||
|
for ignore_path in ig_list
|
||||||
|
]
|
||||||
|
|
||||||
# Ignore cmake file, path pairs.
|
# Ignore cmake file, path pairs.
|
||||||
global_ignore_source_missing = {}
|
global_ignore_source_missing = {}
|
||||||
for k, v in IGNORE_SOURCE_MISSING:
|
for k, v in IGNORE_SOURCE_MISSING:
|
||||||
@@ -178,6 +191,8 @@ def cmake_get_src(f):
|
|||||||
|
|
||||||
if not l:
|
if not l:
|
||||||
pass
|
pass
|
||||||
|
elif l in local_ignore_source_missing:
|
||||||
|
local_ignore_source_missing.remove(l)
|
||||||
elif l.startswith("$"):
|
elif l.startswith("$"):
|
||||||
if context_name == "SRC":
|
if context_name == "SRC":
|
||||||
# assume if it ends with context_name we know about it
|
# assume if it ends with context_name we know about it
|
||||||
@@ -227,10 +242,7 @@ def cmake_get_src(f):
|
|||||||
# replace_line(f, i - 1, new_path_rel)
|
# replace_line(f, i - 1, new_path_rel)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if l in local_ignore_source_missing:
|
raise Exception("non existent include %s:%d -> %s" % (f, i, new_file))
|
||||||
local_ignore_source_missing.remove(l)
|
|
||||||
else:
|
|
||||||
raise Exception("non existent include %s:%d -> %s" % (f, i, new_file))
|
|
||||||
|
|
||||||
# print(new_file)
|
# print(new_file)
|
||||||
|
|
||||||
@@ -258,16 +270,16 @@ def cmake_get_src(f):
|
|||||||
|
|
||||||
|
|
||||||
def is_ignore_source(f, ignore_used):
|
def is_ignore_source(f, ignore_used):
|
||||||
for index, ig in enumerate(IGNORE_SOURCE):
|
for index, ignore_path in enumerate(IGNORE_SOURCE):
|
||||||
if ig in f:
|
if ignore_path in f:
|
||||||
ignore_used[index] = True
|
ignore_used[index] = True
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def is_ignore_cmake(f, ignore_used):
|
def is_ignore_cmake(f, ignore_used):
|
||||||
for index, ig in enumerate(IGNORE_CMAKE):
|
for index, ignore_path in enumerate(IGNORE_CMAKE):
|
||||||
if ig in f:
|
if ignore_path in f:
|
||||||
ignore_used[index] = True
|
ignore_used[index] = True
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@@ -298,7 +310,7 @@ def main():
|
|||||||
for cf, i in refs:
|
for cf, i in refs:
|
||||||
errs.append((cf, i))
|
errs.append((cf, i))
|
||||||
else:
|
else:
|
||||||
raise Exception("CMake referenecs missing, internal error, aborting!")
|
raise Exception("CMake references missing, internal error, aborting!")
|
||||||
is_err = True
|
is_err = True
|
||||||
|
|
||||||
errs.sort()
|
errs.sort()
|
||||||
@@ -309,7 +321,7 @@ def main():
|
|||||||
# print("sed '%dd' '%s' > '%s.tmp' ; mv '%s.tmp' '%s'" % (i, cf, cf, cf, cf))
|
# print("sed '%dd' '%s' > '%s.tmp' ; mv '%s.tmp' '%s'" % (i, cf, cf, cf, cf))
|
||||||
|
|
||||||
if is_err:
|
if is_err:
|
||||||
raise Exception("CMake referenecs missing files, aborting!")
|
raise Exception("CMake references missing files, aborting!")
|
||||||
del is_err
|
del is_err
|
||||||
del errs
|
del errs
|
||||||
|
|
||||||
@@ -320,7 +332,7 @@ def main():
|
|||||||
if cf not in global_c:
|
if cf not in global_c:
|
||||||
print("missing_c: ", cf)
|
print("missing_c: ", cf)
|
||||||
|
|
||||||
# check if automake builds a corrasponding .o file.
|
# Check if automake builds a corresponding .o file.
|
||||||
'''
|
'''
|
||||||
if cf in global_c:
|
if cf in global_c:
|
||||||
out1 = os.path.splitext(cf)[0] + ".o"
|
out1 = os.path.splitext(cf)[0] + ".o"
|
||||||
@@ -356,21 +368,21 @@ def main():
|
|||||||
|
|
||||||
# Check ignores aren't stale
|
# Check ignores aren't stale
|
||||||
print("\nCheck for unused 'IGNORE_SOURCE' paths...")
|
print("\nCheck for unused 'IGNORE_SOURCE' paths...")
|
||||||
for index, ig in enumerate(IGNORE_SOURCE):
|
for index, ignore_path in enumerate(IGNORE_SOURCE):
|
||||||
if not ignore_used_source[index]:
|
if not ignore_used_source[index]:
|
||||||
print("unused ignore: %r" % ig)
|
print("unused ignore: %r" % ignore_path)
|
||||||
|
|
||||||
# Check ignores aren't stale
|
# Check ignores aren't stale
|
||||||
print("\nCheck for unused 'IGNORE_SOURCE_MISSING' paths...")
|
print("\nCheck for unused 'IGNORE_SOURCE_MISSING' paths...")
|
||||||
for k, v in sorted(global_ignore_source_missing.items()):
|
for k, v in sorted(global_ignore_source_missing.items()):
|
||||||
for ig in v:
|
for ignore_path in v:
|
||||||
print("unused ignore: %r -> %r" % (ig, k))
|
print("unused ignore: %r -> %r" % (ignore_path, k))
|
||||||
|
|
||||||
# Check ignores aren't stale
|
# Check ignores aren't stale
|
||||||
print("\nCheck for unused 'IGNORE_CMAKE' paths...")
|
print("\nCheck for unused 'IGNORE_CMAKE' paths...")
|
||||||
for index, ig in enumerate(IGNORE_CMAKE):
|
for index, ignore_path in enumerate(IGNORE_CMAKE):
|
||||||
if not ignore_used_cmake[index]:
|
if not ignore_used_cmake[index]:
|
||||||
print("unused ignore: %r" % ig)
|
print("unused ignore: %r" % ignore_path)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@@ -34,8 +34,18 @@ IGNORE_SOURCE = (
|
|||||||
|
|
||||||
# Ignore cmake file, path pairs.
|
# Ignore cmake file, path pairs.
|
||||||
IGNORE_SOURCE_MISSING = (
|
IGNORE_SOURCE_MISSING = (
|
||||||
# Use for cycles stand-alone.
|
( # Use for cycles stand-alone.
|
||||||
("intern/cycles/util/CMakeLists.txt", "../../third_party/numaapi/include"),
|
"intern/cycles/util/CMakeLists.txt", (
|
||||||
|
"../../third_party/numaapi/include",
|
||||||
|
)),
|
||||||
|
( # Use for `WITH_NANOVDB`.
|
||||||
|
"intern/cycles/kernel/CMakeLists.txt", (
|
||||||
|
"nanovdb/util/CSampleFromVoxels.h",
|
||||||
|
"nanovdb/util/SampleFromVoxels.h",
|
||||||
|
"nanovdb/NanoVDB.h",
|
||||||
|
"nanovdb/CNanoVDB.h",
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
IGNORE_CMAKE = (
|
IGNORE_CMAKE = (
|
||||||
|
@@ -19,6 +19,7 @@ set(WITH_DRACO ON CACHE BOOL "" FORCE)
|
|||||||
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
|
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_GMP ON CACHE BOOL "" FORCE)
|
set(WITH_GMP ON CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_HARU ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
|
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
|
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
|
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
|
||||||
@@ -44,6 +45,8 @@ set(WITH_OPENMP ON CACHE BOOL "" FORCE)
|
|||||||
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
|
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
|
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
|
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_PUGIXML ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_NANOVDB ON CACHE BOOL "" FORCE)
|
set(WITH_NANOVDB ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
|
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
|
||||||
|
@@ -24,6 +24,7 @@ set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
|||||||
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
|
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
|
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_GMP OFF CACHE BOOL "" FORCE)
|
set(WITH_GMP OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_HARU OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
|
set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE)
|
set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE)
|
set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE)
|
||||||
@@ -51,6 +52,8 @@ set(WITH_OPENIMAGEIO OFF CACHE BOOL "" FORCE)
|
|||||||
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
|
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
|
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_POTRACE OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_PUGIXML OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_NANOVDB OFF CACHE BOOL "" FORCE)
|
set(WITH_NANOVDB OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_QUADRIFLOW OFF CACHE BOOL "" FORCE)
|
set(WITH_QUADRIFLOW OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_SDL OFF CACHE BOOL "" FORCE)
|
set(WITH_SDL OFF CACHE BOOL "" FORCE)
|
||||||
|
@@ -20,6 +20,7 @@ set(WITH_DRACO ON CACHE BOOL "" FORCE)
|
|||||||
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
|
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_GMP ON CACHE BOOL "" FORCE)
|
set(WITH_GMP ON CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_HARU ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
|
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
|
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
|
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
|
||||||
@@ -45,6 +46,8 @@ set(WITH_OPENMP ON CACHE BOOL "" FORCE)
|
|||||||
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
|
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
|
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
|
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_PUGIXML ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_NANOVDB ON CACHE BOOL "" FORCE)
|
set(WITH_NANOVDB ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
|
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
|
||||||
|
@@ -1231,7 +1231,7 @@ function(find_python_package
|
|||||||
set(WITH_PYTHON_INSTALL_${_upper_package} OFF PARENT_SCOPE)
|
set(WITH_PYTHON_INSTALL_${_upper_package} OFF PARENT_SCOPE)
|
||||||
else()
|
else()
|
||||||
message(STATUS "${package} found at '${PYTHON_${_upper_package}_PATH}'")
|
message(STATUS "${package} found at '${PYTHON_${_upper_package}_PATH}'")
|
||||||
|
|
||||||
if(NOT "${relative_include_dir}" STREQUAL "")
|
if(NOT "${relative_include_dir}" STREQUAL "")
|
||||||
set(_relative_include_dir "${package}/${relative_include_dir}")
|
set(_relative_include_dir "${package}/${relative_include_dir}")
|
||||||
unset(PYTHON_${_upper_package}_INCLUDE_DIRS CACHE)
|
unset(PYTHON_${_upper_package}_INCLUDE_DIRS CACHE)
|
||||||
|
@@ -72,7 +72,11 @@ if(WITH_JACK)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT DEFINED LIBDIR)
|
if(NOT DEFINED LIBDIR)
|
||||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin)
|
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64")
|
||||||
|
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin)
|
||||||
|
else()
|
||||||
|
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin_${CMAKE_OSX_ARCHITECTURES})
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
||||||
endif()
|
endif()
|
||||||
@@ -428,6 +432,14 @@ if(WITH_GMP)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_HARU)
|
||||||
|
find_package(Haru)
|
||||||
|
if(NOT HARU_FOUND)
|
||||||
|
message(WARNING "Haru not found, disabling WITH_HARU")
|
||||||
|
set(WITH_HARU OFF)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(EXISTS ${LIBDIR})
|
if(EXISTS ${LIBDIR})
|
||||||
without_system_libs_end()
|
without_system_libs_end()
|
||||||
endif()
|
endif()
|
||||||
|
@@ -352,6 +352,11 @@ endif()
|
|||||||
|
|
||||||
if(WITH_PUGIXML)
|
if(WITH_PUGIXML)
|
||||||
find_package_wrapper(PugiXML)
|
find_package_wrapper(PugiXML)
|
||||||
|
|
||||||
|
if (NOT PUGIXML_FOUND)
|
||||||
|
set(WITH_PUGIXML OFF)
|
||||||
|
message(STATUS "PugiXML not found, disabling WITH_PUGIXML")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_OPENIMAGEIO)
|
if(WITH_OPENIMAGEIO)
|
||||||
@@ -610,7 +615,13 @@ endif()
|
|||||||
|
|
||||||
# GNU Compiler
|
# GNU Compiler
|
||||||
if(CMAKE_COMPILER_IS_GNUCC)
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
|
# ffp-contract=off:
|
||||||
|
# Automatically turned on when building with "-march=native". This is
|
||||||
|
# explicitly turned off here as it will make floating point math give a bit
|
||||||
|
# different results. This will lead to automated test failures. So disable
|
||||||
|
# this until we support it. Seems to default to off in clang and the intel
|
||||||
|
# compiler.
|
||||||
|
set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -ffp-contract=off")
|
||||||
|
|
||||||
# `maybe-uninitialized` is unreliable in release builds, but fine in debug builds.
|
# `maybe-uninitialized` is unreliable in release builds, but fine in debug builds.
|
||||||
set(GCC_EXTRA_FLAGS_RELEASE "-Wno-maybe-uninitialized")
|
set(GCC_EXTRA_FLAGS_RELEASE "-Wno-maybe-uninitialized")
|
||||||
|
@@ -800,3 +800,15 @@ if(WITH_POTRACE)
|
|||||||
set(POTRACE_LIBRARIES ${LIBDIR}/potrace/lib/potrace.lib)
|
set(POTRACE_LIBRARIES ${LIBDIR}/potrace/lib/potrace.lib)
|
||||||
set(POTRACE_FOUND On)
|
set(POTRACE_FOUND On)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_HARU)
|
||||||
|
if(EXISTS ${LIBDIR}/haru)
|
||||||
|
set(HARU_FOUND On)
|
||||||
|
set(HARU_ROOT_DIR ${LIBDIR}/haru)
|
||||||
|
set(HARU_INCLUDE_DIRS ${HARU_ROOT_DIR}/include)
|
||||||
|
set(HARU_LIBRARIES ${HARU_ROOT_DIR}/lib/libhpdfs.lib)
|
||||||
|
else()
|
||||||
|
message(WARNING "Haru was not found, disabling WITH_HARU")
|
||||||
|
set(WITH_HARU OFF)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@@ -49,7 +50,12 @@ def svn_update(args, release_version):
|
|||||||
|
|
||||||
# Checkout precompiled libraries
|
# Checkout precompiled libraries
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
lib_platform = "darwin"
|
if platform.machine() == 'x86_64':
|
||||||
|
lib_platform = "darwin"
|
||||||
|
elif platform.machine() == 'arm64':
|
||||||
|
lib_platform = "darwin_arm64"
|
||||||
|
else:
|
||||||
|
lib_platform = None
|
||||||
elif sys.platform == 'win32':
|
elif sys.platform == 'win32':
|
||||||
# Windows checkout is usually handled by bat scripts since python3 to run
|
# Windows checkout is usually handled by bat scripts since python3 to run
|
||||||
# this script is bundled as part of the precompiled libraries. However it
|
# this script is bundled as part of the precompiled libraries. However it
|
||||||
|
@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "V2.92"
|
PROJECT_NUMBER = "V2.93"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
@@ -52,10 +52,11 @@ outfilename = sys.argv[2]
|
|||||||
|
|
||||||
cmd = [blender_bin, "--help"]
|
cmd = [blender_bin, "--help"]
|
||||||
print(" executing:", " ".join(cmd))
|
print(" executing:", " ".join(cmd))
|
||||||
|
ASAN_OPTIONS = "exitcode=0:" + os.environ.get("ASAN_OPTIONS", "")
|
||||||
blender_help = subprocess.run(
|
blender_help = subprocess.run(
|
||||||
cmd, env={"ASAN_OPTIONS": "exitcode=0"}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8")
|
cmd, env={"ASAN_OPTIONS": ASAN_OPTIONS}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8")
|
||||||
blender_version = subprocess.run(
|
blender_version = subprocess.run(
|
||||||
[blender_bin, "--version"], env={"ASAN_OPTIONS": "exitcode=0"}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8").strip()
|
[blender_bin, "--version"], env={"ASAN_OPTIONS": ASAN_OPTIONS}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8").strip()
|
||||||
blender_version, blender_date = (blender_version.split("build") + [None, None])[0:2]
|
blender_version, blender_date = (blender_version.split("build") + [None, None])[0:2]
|
||||||
blender_version = blender_version.rstrip().partition(" ")[2] # remove 'Blender' prefix.
|
blender_version = blender_version.rstrip().partition(" ")[2] # remove 'Blender' prefix.
|
||||||
if blender_date is None:
|
if blender_date is None:
|
||||||
|
@@ -55,7 +55,7 @@ if $DO_EXE_BLENDER ; then
|
|||||||
# Don't delete existing docs, now partial updates are used for quick builds.
|
# Don't delete existing docs, now partial updates are used for quick builds.
|
||||||
#
|
#
|
||||||
# Disable ASAN error halt since it results in nonzero exit code on any minor issue.
|
# Disable ASAN error halt since it results in nonzero exit code on any minor issue.
|
||||||
ASAN_OPTIONS=halt_on_error=0 \
|
ASAN_OPTIONS=halt_on_error=0:${ASAN_OPTIONS} \
|
||||||
$BLENDER_BIN \
|
$BLENDER_BIN \
|
||||||
--background \
|
--background \
|
||||||
-noaudio \
|
-noaudio \
|
||||||
|
16
extern/mantaflow/preprocessed/conjugategrad.h
vendored
16
extern/mantaflow/preprocessed/conjugategrad.h
vendored
@@ -170,7 +170,7 @@ struct ApplyMatrix : public KernelBase {
|
|||||||
unusedParameter(vecRhs); // Not needed in this matrix application
|
unusedParameter(vecRhs); // Not needed in this matrix application
|
||||||
|
|
||||||
if (matrixA.size() != 4)
|
if (matrixA.size() != 4)
|
||||||
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
|
errMsg("ConjugateGrad: Invalid A matrix in apply matrix step");
|
||||||
Grid<Real> &A0 = *matrixA[0];
|
Grid<Real> &A0 = *matrixA[0];
|
||||||
Grid<Real> &Ai = *matrixA[1];
|
Grid<Real> &Ai = *matrixA[1];
|
||||||
Grid<Real> &Aj = *matrixA[2];
|
Grid<Real> &Aj = *matrixA[2];
|
||||||
@@ -256,7 +256,7 @@ struct ApplyMatrix2D : public KernelBase {
|
|||||||
unusedParameter(vecRhs); // Not needed in this matrix application
|
unusedParameter(vecRhs); // Not needed in this matrix application
|
||||||
|
|
||||||
if (matrixA.size() != 3)
|
if (matrixA.size() != 3)
|
||||||
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
|
errMsg("ConjugateGrad: Invalid A matrix in apply matrix step");
|
||||||
Grid<Real> &A0 = *matrixA[0];
|
Grid<Real> &A0 = *matrixA[0];
|
||||||
Grid<Real> &Ai = *matrixA[1];
|
Grid<Real> &Ai = *matrixA[1];
|
||||||
Grid<Real> &Aj = *matrixA[2];
|
Grid<Real> &Aj = *matrixA[2];
|
||||||
@@ -338,7 +338,7 @@ struct ApplyMatrixViscosityU : public KernelBase {
|
|||||||
const std::vector<Grid<Real> *> vecRhs) const
|
const std::vector<Grid<Real> *> vecRhs) const
|
||||||
{
|
{
|
||||||
if (matrixA.size() != 15)
|
if (matrixA.size() != 15)
|
||||||
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
|
errMsg("ConjugateGrad: Invalid A matrix in apply matrix step");
|
||||||
Grid<Real> &A0 = *matrixA[0];
|
Grid<Real> &A0 = *matrixA[0];
|
||||||
Grid<Real> &Aplusi = *matrixA[1];
|
Grid<Real> &Aplusi = *matrixA[1];
|
||||||
Grid<Real> &Aplusj = *matrixA[2];
|
Grid<Real> &Aplusj = *matrixA[2];
|
||||||
@@ -348,7 +348,7 @@ struct ApplyMatrixViscosityU : public KernelBase {
|
|||||||
Grid<Real> &Aminusk = *matrixA[6];
|
Grid<Real> &Aminusk = *matrixA[6];
|
||||||
|
|
||||||
if (vecRhs.size() != 2)
|
if (vecRhs.size() != 2)
|
||||||
errMsg("ConjugatedGrad: Invalid rhs vector in apply matrix step");
|
errMsg("ConjugateGrad: Invalid rhs vector in apply matrix step");
|
||||||
Grid<Real> &srcV = *vecRhs[0];
|
Grid<Real> &srcV = *vecRhs[0];
|
||||||
Grid<Real> &srcW = *vecRhs[1];
|
Grid<Real> &srcW = *vecRhs[1];
|
||||||
|
|
||||||
@@ -450,7 +450,7 @@ struct ApplyMatrixViscosityV : public KernelBase {
|
|||||||
const std::vector<Grid<Real> *> vecRhs) const
|
const std::vector<Grid<Real> *> vecRhs) const
|
||||||
{
|
{
|
||||||
if (matrixA.size() != 15)
|
if (matrixA.size() != 15)
|
||||||
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
|
errMsg("ConjugateGrad: Invalid A matrix in apply matrix step");
|
||||||
Grid<Real> &A0 = *matrixA[0];
|
Grid<Real> &A0 = *matrixA[0];
|
||||||
Grid<Real> &Aplusi = *matrixA[1];
|
Grid<Real> &Aplusi = *matrixA[1];
|
||||||
Grid<Real> &Aplusj = *matrixA[2];
|
Grid<Real> &Aplusj = *matrixA[2];
|
||||||
@@ -460,7 +460,7 @@ struct ApplyMatrixViscosityV : public KernelBase {
|
|||||||
Grid<Real> &Aminusk = *matrixA[6];
|
Grid<Real> &Aminusk = *matrixA[6];
|
||||||
|
|
||||||
if (vecRhs.size() != 2)
|
if (vecRhs.size() != 2)
|
||||||
errMsg("ConjugatedGrad: Invalid rhs vector in apply matrix step");
|
errMsg("ConjugateGrad: Invalid rhs vector in apply matrix step");
|
||||||
Grid<Real> &srcU = *vecRhs[0];
|
Grid<Real> &srcU = *vecRhs[0];
|
||||||
Grid<Real> &srcW = *vecRhs[1];
|
Grid<Real> &srcW = *vecRhs[1];
|
||||||
|
|
||||||
@@ -562,7 +562,7 @@ struct ApplyMatrixViscosityW : public KernelBase {
|
|||||||
const std::vector<Grid<Real> *> vecRhs) const
|
const std::vector<Grid<Real> *> vecRhs) const
|
||||||
{
|
{
|
||||||
if (matrixA.size() != 15)
|
if (matrixA.size() != 15)
|
||||||
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
|
errMsg("ConjugateGrad: Invalid A matrix in apply matrix step");
|
||||||
Grid<Real> &A0 = *matrixA[0];
|
Grid<Real> &A0 = *matrixA[0];
|
||||||
Grid<Real> &Aplusi = *matrixA[1];
|
Grid<Real> &Aplusi = *matrixA[1];
|
||||||
Grid<Real> &Aplusj = *matrixA[2];
|
Grid<Real> &Aplusj = *matrixA[2];
|
||||||
@@ -572,7 +572,7 @@ struct ApplyMatrixViscosityW : public KernelBase {
|
|||||||
Grid<Real> &Aminusk = *matrixA[6];
|
Grid<Real> &Aminusk = *matrixA[6];
|
||||||
|
|
||||||
if (vecRhs.size() != 2)
|
if (vecRhs.size() != 2)
|
||||||
errMsg("ConjugatedGrad: Invalid rhs vector in apply matrix step");
|
errMsg("ConjugateGrad: Invalid rhs vector in apply matrix step");
|
||||||
Grid<Real> &srcU = *vecRhs[0];
|
Grid<Real> &srcU = *vecRhs[0];
|
||||||
Grid<Real> &srcV = *vecRhs[1];
|
Grid<Real> &srcV = *vecRhs[1];
|
||||||
|
|
||||||
|
23
extern/mantaflow/preprocessed/fileio/iogrids.cpp
vendored
23
extern/mantaflow/preprocessed/fileio/iogrids.cpp
vendored
@@ -628,13 +628,24 @@ template<class T> int readGridUni(const string &name, Grid<T> *grid)
|
|||||||
// current file format
|
// current file format
|
||||||
UniHeader head;
|
UniHeader head;
|
||||||
assertMsg(gzread(gzf, &head, sizeof(UniHeader)) == sizeof(UniHeader),
|
assertMsg(gzread(gzf, &head, sizeof(UniHeader)) == sizeof(UniHeader),
|
||||||
"can't read file, no header present");
|
"readGridUni: Can't read file, no header present");
|
||||||
assertMsg(head.dimX == grid->getSizeX() && head.dimY == grid->getSizeY() &&
|
|
||||||
head.dimZ == grid->getSizeZ(),
|
|
||||||
"grid dim doesn't match, " << Vec3(head.dimX, head.dimY, head.dimZ) << " vs "
|
|
||||||
<< grid->getSize());
|
|
||||||
assertMsg(unifyGridType(head.gridType) == unifyGridType(grid->getType()),
|
assertMsg(unifyGridType(head.gridType) == unifyGridType(grid->getType()),
|
||||||
"grid type doesn't match " << head.gridType << " vs " << grid->getType());
|
"readGridUni: Grid type doesn't match " << head.gridType << " vs "
|
||||||
|
<< grid->getType());
|
||||||
|
|
||||||
|
const Vec3i curGridSize = grid->getParent()->getGridSize();
|
||||||
|
const Vec3i headGridSize(head.dimX, head.dimY, head.dimZ);
|
||||||
|
# if BLENDER
|
||||||
|
// Correct grid size is only a soft requirement in Blender
|
||||||
|
if (headGridSize != curGridSize) {
|
||||||
|
debMsg("readGridUni: Grid dim doesn't match, " << headGridSize << " vs " << curGridSize, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
assertMsg(headGridSize == curGridSize,
|
||||||
|
"readGridUni: Grid dim doesn't match, " << headGridSize << " vs " << curGridSize);
|
||||||
|
# endif
|
||||||
|
|
||||||
# if FLOATINGPOINT_PRECISION != 1
|
# if FLOATINGPOINT_PRECISION != 1
|
||||||
// convert float to double
|
// convert float to double
|
||||||
Grid<T> temp(grid->getParent());
|
Grid<T> temp(grid->getParent());
|
||||||
|
@@ -230,6 +230,19 @@ int readParticlesUni(const std::string &name, BasicParticleSystem *parts)
|
|||||||
assertMsg(((head.bytesPerElement == PartSysSize) && (head.elementType == 0)),
|
assertMsg(((head.bytesPerElement == PartSysSize) && (head.elementType == 0)),
|
||||||
"particle type doesn't match");
|
"particle type doesn't match");
|
||||||
|
|
||||||
|
const Vec3i curGridSize = parts->getParent()->getGridSize();
|
||||||
|
const Vec3i headGridSize(head.dimX, head.dimY, head.dimZ);
|
||||||
|
# if BLENDER
|
||||||
|
// Correct grid size is only a soft requirement in Blender
|
||||||
|
if (headGridSize != curGridSize) {
|
||||||
|
debMsg("readPdataUni: Grid dim doesn't match, " << headGridSize << " vs " << curGridSize, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
assertMsg(headGridSize == curGridSize,
|
||||||
|
"readPdataUni: Grid dim doesn't match, " << headGridSize << " vs " << curGridSize);
|
||||||
|
# endif
|
||||||
|
|
||||||
// re-allocate all data
|
// re-allocate all data
|
||||||
parts->resizeAll(head.dim);
|
parts->resizeAll(head.dim);
|
||||||
|
|
||||||
@@ -325,6 +338,19 @@ template<class T> int readPdataUni(const std::string &name, ParticleDataImpl<T>
|
|||||||
pdata->getParticleSys()->resize(head.dim); // ensure that parent particle system has same size
|
pdata->getParticleSys()->resize(head.dim); // ensure that parent particle system has same size
|
||||||
pdata->resize(head.dim);
|
pdata->resize(head.dim);
|
||||||
|
|
||||||
|
const Vec3i curGridSize = pdata->getParent()->getGridSize();
|
||||||
|
const Vec3i headGridSize(head.dimX, head.dimY, head.dimZ);
|
||||||
|
# if BLENDER
|
||||||
|
// Correct grid size is only a soft requirement in Blender
|
||||||
|
if (headGridSize != curGridSize) {
|
||||||
|
debMsg("readPdataUni: Grid dim doesn't match, " << headGridSize << " vs " << curGridSize, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
assertMsg(headGridSize == curGridSize,
|
||||||
|
"readPdataUni: Grid dim doesn't match, " << headGridSize << " vs " << curGridSize);
|
||||||
|
# endif
|
||||||
|
|
||||||
assertMsg(head.dim == pdata->size(), "pdata size doesn't match");
|
assertMsg(head.dim == pdata->size(), "pdata size doesn't match");
|
||||||
# if FLOATINGPOINT_PRECISION != 1
|
# if FLOATINGPOINT_PRECISION != 1
|
||||||
ParticleDataImpl<T> temp(pdata->getParent());
|
ParticleDataImpl<T> temp(pdata->getParent());
|
||||||
|
@@ -90,6 +90,13 @@ template<> void convertFrom(openvdb::Vec3s &in, Vec3 *out)
|
|||||||
(*out).z = in.z();
|
(*out).z = in.z();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> void convertFrom(openvdb::Vec3i &in, Vec3i *out)
|
||||||
|
{
|
||||||
|
(*out).x = in.x();
|
||||||
|
(*out).y = in.y();
|
||||||
|
(*out).z = in.z();
|
||||||
|
}
|
||||||
|
|
||||||
// Convert to OpenVDB value from Manta value.
|
// Convert to OpenVDB value from Manta value.
|
||||||
template<class S, class T> void convertTo(S *out, T &in)
|
template<class S, class T> void convertTo(S *out, T &in)
|
||||||
{
|
{
|
||||||
|
153
extern/mantaflow/preprocessed/fileio/iovdb.cpp
vendored
153
extern/mantaflow/preprocessed/fileio/iovdb.cpp
vendored
@@ -38,6 +38,11 @@
|
|||||||
#define POSITION_NAME "P"
|
#define POSITION_NAME "P"
|
||||||
#define FLAG_NAME "U"
|
#define FLAG_NAME "U"
|
||||||
|
|
||||||
|
#define META_BASE_RES "file_base_resolution"
|
||||||
|
#define META_VOXEL_SIZE "file_voxel_size"
|
||||||
|
#define META_BBOX_MAX "file_bbox_max"
|
||||||
|
#define META_BBOX_MIN "file_bbox_min"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace Manta {
|
namespace Manta {
|
||||||
@@ -388,7 +393,8 @@ int writeObjectsVDB(const string &filename,
|
|||||||
int compression,
|
int compression,
|
||||||
int precision,
|
int precision,
|
||||||
float clip,
|
float clip,
|
||||||
const Grid<Real> *clipGrid)
|
const Grid<Real> *clipGrid,
|
||||||
|
const bool meta)
|
||||||
{
|
{
|
||||||
openvdb::initialize();
|
openvdb::initialize();
|
||||||
openvdb::io::File file(filename);
|
openvdb::io::File file(filename);
|
||||||
@@ -489,6 +495,16 @@ int writeObjectsVDB(const string &filename,
|
|||||||
// Set additional grid attributes, e.g. name, grid class, compression level, etc.
|
// Set additional grid attributes, e.g. name, grid class, compression level, etc.
|
||||||
if (vdbGrid) {
|
if (vdbGrid) {
|
||||||
setGridOptions<openvdb::GridBase>(vdbGrid, objectName, gClass, voxelSize, precision);
|
setGridOptions<openvdb::GridBase>(vdbGrid, objectName, gClass, voxelSize, precision);
|
||||||
|
|
||||||
|
// Optional metadata: Save additional simulation information per vdb object
|
||||||
|
if (meta) {
|
||||||
|
const Vec3i size = object->getParent()->getGridSize();
|
||||||
|
// The (dense) resolution of this grid
|
||||||
|
vdbGrid->insertMeta(META_BASE_RES,
|
||||||
|
openvdb::Vec3IMetadata(openvdb::Vec3i(size.x, size.y, size.z)));
|
||||||
|
// Length of one voxel side
|
||||||
|
vdbGrid->insertMeta(META_VOXEL_SIZE, openvdb::FloatMetadata(voxelSize));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,6 +549,44 @@ int writeObjectsVDB(const string &filename,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clearAll(std::vector<PbClass *> *objects, std::vector<ParticleDataBase *> pdbBuffer)
|
||||||
|
{
|
||||||
|
// Clear all data loaded into manta objects (e.g. during IO error)
|
||||||
|
for (std::vector<PbClass *>::iterator iter = objects->begin(); iter != objects->end(); ++iter) {
|
||||||
|
if (GridBase *mantaGrid = dynamic_cast<GridBase *>(*iter)) {
|
||||||
|
if (mantaGrid->getType() & GridBase::TypeInt) {
|
||||||
|
Grid<int> *mantaIntGrid = (Grid<int> *)mantaGrid;
|
||||||
|
mantaIntGrid->clear();
|
||||||
|
}
|
||||||
|
else if (mantaGrid->getType() & GridBase::TypeReal) {
|
||||||
|
Grid<Real> *mantaRealGrid = (Grid<Real> *)mantaGrid;
|
||||||
|
mantaRealGrid->clear();
|
||||||
|
}
|
||||||
|
else if (mantaGrid->getType() & GridBase::TypeVec3) {
|
||||||
|
Grid<Vec3> *mantaVec3Grid = (Grid<Vec3> *)mantaGrid;
|
||||||
|
mantaVec3Grid->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (BasicParticleSystem *mantaPP = dynamic_cast<BasicParticleSystem *>(*iter)) {
|
||||||
|
mantaPP->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (ParticleDataBase *pdb : pdbBuffer) {
|
||||||
|
if (pdb->getType() == ParticleDataBase::TypeInt) {
|
||||||
|
ParticleDataImpl<int> *mantaPDataInt = (ParticleDataImpl<int> *)pdb;
|
||||||
|
mantaPDataInt->clear();
|
||||||
|
}
|
||||||
|
else if (pdb->getType() == ParticleDataBase::TypeReal) {
|
||||||
|
ParticleDataImpl<Real> *mantaPDataReal = (ParticleDataImpl<Real> *)pdb;
|
||||||
|
mantaPDataReal->clear();
|
||||||
|
}
|
||||||
|
else if (pdb->getType() == ParticleDataBase::TypeVec3) {
|
||||||
|
ParticleDataImpl<Vec3> *mantaPDataVec3 = (ParticleDataImpl<Vec3> *)pdb;
|
||||||
|
mantaPDataVec3->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, float worldSize)
|
int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, float worldSize)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -561,6 +615,9 @@ int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, floa
|
|||||||
// A buffer to store a handle to pData objects. These will be read alongside a particle system.
|
// A buffer to store a handle to pData objects. These will be read alongside a particle system.
|
||||||
std::vector<ParticleDataBase *> pdbBuffer;
|
std::vector<ParticleDataBase *> pdbBuffer;
|
||||||
|
|
||||||
|
// Count how many objects could not be read correctly
|
||||||
|
int readFailure = 0;
|
||||||
|
|
||||||
for (std::vector<PbClass *>::iterator iter = objects->begin(); iter != objects->end(); ++iter) {
|
for (std::vector<PbClass *>::iterator iter = objects->begin(); iter != objects->end(); ++iter) {
|
||||||
|
|
||||||
if (gridsVDB.empty()) {
|
if (gridsVDB.empty()) {
|
||||||
@@ -568,11 +625,12 @@ int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, floa
|
|||||||
}
|
}
|
||||||
// If there is just one grid in this file, load it regardless of name match (to vdb caches per
|
// If there is just one grid in this file, load it regardless of name match (to vdb caches per
|
||||||
// grid).
|
// grid).
|
||||||
bool onlyGrid = (gridsVDB.size() == 1);
|
const bool onlyGrid = (gridsVDB.size() == 1);
|
||||||
|
|
||||||
PbClass *object = dynamic_cast<PbClass *>(*iter);
|
PbClass *object = dynamic_cast<PbClass *>(*iter);
|
||||||
const Real dx = object->getParent()->getDx();
|
const Real dx = object->getParent()->getDx();
|
||||||
const Real voxelSize = worldSize * dx;
|
const Vec3i origRes = object->getParent()->getGridSize();
|
||||||
|
Real voxelSize = worldSize * dx;
|
||||||
|
|
||||||
// Particle data objects are treated separately - buffered and inserted when reading the
|
// Particle data objects are treated separately - buffered and inserted when reading the
|
||||||
// particle system
|
// particle system
|
||||||
@@ -596,6 +654,81 @@ int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, floa
|
|||||||
if (!nameMatch && !onlyGrid) {
|
if (!nameMatch && !onlyGrid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Metadata: If present in the file, meta data will be parsed into these fields
|
||||||
|
Real metaVoxelSize(0);
|
||||||
|
Vec3i metaRes(0), metaBBoxMax(0), metaBBoxMin(0);
|
||||||
|
|
||||||
|
// Loop to load all meta data that we care about
|
||||||
|
for (openvdb::MetaMap::MetaIterator iter = vdbGrid->beginMeta(); iter != vdbGrid->endMeta();
|
||||||
|
++iter) {
|
||||||
|
const std::string &name = iter->first;
|
||||||
|
const openvdb::Metadata::Ptr value = iter->second;
|
||||||
|
if (name.compare(META_BASE_RES) == 0) {
|
||||||
|
openvdb::Vec3i tmp = static_cast<openvdb::Vec3IMetadata &>(*value).value();
|
||||||
|
convertFrom(tmp, &metaRes);
|
||||||
|
}
|
||||||
|
else if (name.compare(META_VOXEL_SIZE) == 0) {
|
||||||
|
float tmp = static_cast<openvdb::FloatMetadata &>(*value).value();
|
||||||
|
convertFrom(tmp, &metaVoxelSize);
|
||||||
|
|
||||||
|
voxelSize = metaVoxelSize; // Make sure to update voxel size variable (used in
|
||||||
|
// pointgrid's importVDB())
|
||||||
|
if (worldSize != 1.0)
|
||||||
|
debMsg(
|
||||||
|
"readObjectsVDB: Found voxel size in meta data. worldSize parameter will be "
|
||||||
|
"ignored!",
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
else if (name.compare(META_BBOX_MAX) == 0) {
|
||||||
|
openvdb::Vec3i tmp = static_cast<openvdb::Vec3IMetadata &>(*value).value();
|
||||||
|
convertFrom(tmp, &metaBBoxMax);
|
||||||
|
}
|
||||||
|
else if (name.compare(META_BBOX_MIN) == 0) {
|
||||||
|
openvdb::Vec3i tmp = static_cast<openvdb::Vec3IMetadata &>(*value).value();
|
||||||
|
convertFrom(tmp, &metaBBoxMin);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debMsg("readObjectsVDB: Skipping unknown meta information '" << name << "'", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare metadata with allocated grid setup. This prevents invalid index access.
|
||||||
|
if (notZero(metaRes) && metaRes != origRes) {
|
||||||
|
debMsg("readObjectsVDB Warning: Grid '" << vdbGrid->getName()
|
||||||
|
<< "' has not been read. Meta grid res " << metaRes
|
||||||
|
<< " vs " << origRes << " current grid size",
|
||||||
|
1);
|
||||||
|
readFailure++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (notZero(metaVoxelSize) && metaVoxelSize != voxelSize) {
|
||||||
|
debMsg("readObjectsVDB Warning: Grid '"
|
||||||
|
<< vdbGrid->getName() << "' has not been read. Meta voxel size "
|
||||||
|
<< metaVoxelSize << " vs " << voxelSize << " current voxel size",
|
||||||
|
1);
|
||||||
|
readFailure++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (metaBBoxMax.x > origRes.x || metaBBoxMax.y > origRes.y || metaBBoxMax.z > origRes.z) {
|
||||||
|
debMsg("readObjectsVDB Warning: Grid '"
|
||||||
|
<< vdbGrid->getName() << "' has not been read. Vdb bbox max " << metaBBoxMax
|
||||||
|
<< " vs " << origRes << " current grid size",
|
||||||
|
1);
|
||||||
|
readFailure++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const Vec3i origOrigin(0);
|
||||||
|
if (metaBBoxMin.x < origOrigin.x || metaBBoxMin.y < origOrigin.y ||
|
||||||
|
metaBBoxMin.z < origOrigin.z) {
|
||||||
|
debMsg("readObjectsVDB Warning: Grid '"
|
||||||
|
<< vdbGrid->getName() << "' has not been read. Vdb bbox min " << metaBBoxMin
|
||||||
|
<< " vs " << origOrigin << " current grid origin",
|
||||||
|
1);
|
||||||
|
readFailure++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (GridBase *mantaGrid = dynamic_cast<GridBase *>(*iter)) {
|
if (GridBase *mantaGrid = dynamic_cast<GridBase *>(*iter)) {
|
||||||
|
|
||||||
if (mantaGrid->getType() & GridBase::TypeInt) {
|
if (mantaGrid->getType() & GridBase::TypeInt) {
|
||||||
@@ -655,6 +788,17 @@ int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, floa
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Do not continue loading objects in this loop if there was a read error
|
||||||
|
if (readFailure > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readFailure > 0) {
|
||||||
|
// Clear all data that has already been loaded into simulation objects
|
||||||
|
clearAll(objects, pdbBuffer);
|
||||||
|
pdbBuffer.clear();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give out a warning if pData items were present but could not be read due to missing particle
|
// Give out a warning if pData items were present but could not be read due to missing particle
|
||||||
@@ -729,7 +873,8 @@ int writeObjectsVDB(const string &filename,
|
|||||||
int compression,
|
int compression,
|
||||||
int precision,
|
int precision,
|
||||||
float clip,
|
float clip,
|
||||||
const Grid<Real> *clipGrid)
|
const Grid<Real> *clipGrid,
|
||||||
|
const bool meta)
|
||||||
{
|
{
|
||||||
errMsg("Cannot save to .vdb file. Mantaflow has not been built with OpenVDB support.");
|
errMsg("Cannot save to .vdb file. Mantaflow has not been built with OpenVDB support.");
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -85,7 +85,8 @@ int save(const string &name,
|
|||||||
bool precisionHalf = true,
|
bool precisionHalf = true,
|
||||||
int precision = PRECISION_HALF,
|
int precision = PRECISION_HALF,
|
||||||
float clip = 1e-4,
|
float clip = 1e-4,
|
||||||
const Grid<Real> *clipGrid = nullptr)
|
const Grid<Real> *clipGrid = nullptr,
|
||||||
|
const bool meta = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!precisionHalf) {
|
if (!precisionHalf) {
|
||||||
@@ -105,7 +106,7 @@ int save(const string &name,
|
|||||||
return writeGridsVol(name, &objects);
|
return writeGridsVol(name, &objects);
|
||||||
if (ext == ".vdb")
|
if (ext == ".vdb")
|
||||||
return writeObjectsVDB(
|
return writeObjectsVDB(
|
||||||
name, &objects, worldSize, skipDeletedParts, compression, precision, clip, clipGrid);
|
name, &objects, worldSize, skipDeletedParts, compression, precision, clip, clipGrid, meta);
|
||||||
else if (ext == ".npz")
|
else if (ext == ".npz")
|
||||||
return writeGridsNumpy(name, &objects);
|
return writeGridsNumpy(name, &objects);
|
||||||
else if (ext == ".txt")
|
else if (ext == ".txt")
|
||||||
@@ -134,6 +135,7 @@ static PyObject *_W_1(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|||||||
int precision = _args.getOpt<int>("precision", 6, PRECISION_HALF, &_lock);
|
int precision = _args.getOpt<int>("precision", 6, PRECISION_HALF, &_lock);
|
||||||
float clip = _args.getOpt<float>("clip", 7, 1e-4, &_lock);
|
float clip = _args.getOpt<float>("clip", 7, 1e-4, &_lock);
|
||||||
const Grid<Real> *clipGrid = _args.getPtrOpt<Grid<Real>>("clipGrid", 8, nullptr, &_lock);
|
const Grid<Real> *clipGrid = _args.getPtrOpt<Grid<Real>>("clipGrid", 8, nullptr, &_lock);
|
||||||
|
const bool meta = _args.getOpt<bool>("meta", 9, false, &_lock);
|
||||||
_retval = toPy(save(name,
|
_retval = toPy(save(name,
|
||||||
objects,
|
objects,
|
||||||
worldSize,
|
worldSize,
|
||||||
@@ -142,7 +144,8 @@ static PyObject *_W_1(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|||||||
precisionHalf,
|
precisionHalf,
|
||||||
precision,
|
precision,
|
||||||
clip,
|
clip,
|
||||||
clipGrid));
|
clipGrid,
|
||||||
|
meta));
|
||||||
_args.check();
|
_args.check();
|
||||||
}
|
}
|
||||||
pbFinalizePlugin(parent, "save", !noTiming);
|
pbFinalizePlugin(parent, "save", !noTiming);
|
||||||
|
@@ -77,7 +77,8 @@ int writeObjectsVDB(const std::string &filename,
|
|||||||
int compression = COMPRESSION_ZIP,
|
int compression = COMPRESSION_ZIP,
|
||||||
int precision = PRECISION_HALF,
|
int precision = PRECISION_HALF,
|
||||||
float clip = 1e-4,
|
float clip = 1e-4,
|
||||||
const Grid<Real> *clipGrid = nullptr);
|
const Grid<Real> *clipGrid = nullptr,
|
||||||
|
const bool meta = false);
|
||||||
int readObjectsVDB(const std::string &filename,
|
int readObjectsVDB(const std::string &filename,
|
||||||
std::vector<PbClass *> *objects,
|
std::vector<PbClass *> *objects,
|
||||||
float scale = 1.0);
|
float scale = 1.0);
|
||||||
|
2
extern/mantaflow/preprocessed/gitinfo.h
vendored
2
extern/mantaflow/preprocessed/gitinfo.h
vendored
@@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
#define MANTA_GIT_VERSION "commit e2285cb9bc492987f728123be6cfc1fe11fe73d6"
|
#define MANTA_GIT_VERSION "commit 1c86d86496e7f7473c36248d12ef07bf4d9d2840"
|
||||||
|
6
extern/mantaflow/preprocessed/grid.cpp
vendored
6
extern/mantaflow/preprocessed/grid.cpp
vendored
@@ -508,8 +508,7 @@ struct CompMaxVec : public KernelBase {
|
|||||||
|
|
||||||
template<class T> Grid<T> &Grid<T>::copyFrom(const Grid<T> &a, bool copyType)
|
template<class T> Grid<T> &Grid<T>::copyFrom(const Grid<T> &a, bool copyType)
|
||||||
{
|
{
|
||||||
assertMsg(a.mSize.x == mSize.x && a.mSize.y == mSize.y && a.mSize.z == mSize.z,
|
assertMsg(a.mSize == mSize, "different grid resolutions " << a.mSize << " vs " << this->mSize);
|
||||||
"different grid resolutions " << a.mSize << " vs " << this->mSize);
|
|
||||||
memcpy(mData, a.mData, sizeof(T) * mSize.x * mSize.y * mSize.z);
|
memcpy(mData, a.mData, sizeof(T) * mSize.x * mSize.y * mSize.z);
|
||||||
if (copyType)
|
if (copyType)
|
||||||
mType = a.mType; // copy type marker
|
mType = a.mType; // copy type marker
|
||||||
@@ -3402,8 +3401,7 @@ void PbRegister_markIsolatedFluidCell()
|
|||||||
void copyMACData(
|
void copyMACData(
|
||||||
const MACGrid &source, MACGrid &target, const FlagGrid &flags, const int flag, const int bnd)
|
const MACGrid &source, MACGrid &target, const FlagGrid &flags, const int flag, const int bnd)
|
||||||
{
|
{
|
||||||
assertMsg(source.getSize().x == target.getSize().x && source.getSize().y == target.getSize().y &&
|
assertMsg(source.getSize() == target.getSize(),
|
||||||
source.getSize().z == target.getSize().z,
|
|
||||||
"different grid resolutions " << source.getSize() << " vs " << target.getSize());
|
"different grid resolutions " << source.getSize() << " vs " << target.getSize());
|
||||||
|
|
||||||
// Grid<Real> divGrid(target.getParent());
|
// Grid<Real> divGrid(target.getParent());
|
||||||
|
1
extern/mantaflow/preprocessed/grid.h
vendored
1
extern/mantaflow/preprocessed/grid.h
vendored
@@ -596,6 +596,7 @@ template<class T> class Grid : public GridBase {
|
|||||||
//! set data
|
//! set data
|
||||||
inline void set(int i, int j, int k, T &val)
|
inline void set(int i, int j, int k, T &val)
|
||||||
{
|
{
|
||||||
|
DEBUG_ONLY(checkIndex(i, j, k));
|
||||||
mData[index(i, j, k)] = val;
|
mData[index(i, j, k)] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
extern/mantaflow/preprocessed/grid4d.cpp
vendored
4
extern/mantaflow/preprocessed/grid4d.cpp
vendored
@@ -491,9 +491,7 @@ template<class T> Grid4d<T> &Grid4d<T>::safeDivide(const Grid4d<T> &a)
|
|||||||
}
|
}
|
||||||
template<class T> Grid4d<T> &Grid4d<T>::copyFrom(const Grid4d<T> &a, bool copyType)
|
template<class T> Grid4d<T> &Grid4d<T>::copyFrom(const Grid4d<T> &a, bool copyType)
|
||||||
{
|
{
|
||||||
assertMsg(a.mSize.x == mSize.x && a.mSize.y == mSize.y && a.mSize.z == mSize.z &&
|
assertMsg(a.mSize == mSize, "different Grid4d resolutions " << a.mSize << " vs " << this->mSize);
|
||||||
a.mSize.t == mSize.t,
|
|
||||||
"different Grid4d resolutions " << a.mSize << " vs " << this->mSize);
|
|
||||||
memcpy(mData, a.mData, sizeof(T) * mSize.x * mSize.y * mSize.z * mSize.t);
|
memcpy(mData, a.mData, sizeof(T) * mSize.x * mSize.y * mSize.z * mSize.t);
|
||||||
if (copyType)
|
if (copyType)
|
||||||
mType = a.mType; // copy type marker
|
mType = a.mType; // copy type marker
|
||||||
|
@@ -139,7 +139,7 @@ struct KnEstimateVolumeFraction : public KernelBase {
|
|||||||
{
|
{
|
||||||
const Vec3 centre = startCentre + Vec3(i, j, k) * 0.5;
|
const Vec3 centre = startCentre + Vec3(i, j, k) * 0.5;
|
||||||
const Real offset = 0.5 * dx;
|
const Real offset = 0.5 * dx;
|
||||||
const int order = 2;
|
const int order = 1; // is sufficient
|
||||||
|
|
||||||
Real phi000 = phi.getInterpolatedHi(centre + Vec3(-offset, -offset, -offset), order);
|
Real phi000 = phi.getInterpolatedHi(centre + Vec3(-offset, -offset, -offset), order);
|
||||||
Real phi001 = phi.getInterpolatedHi(centre + Vec3(-offset, -offset, +offset), order);
|
Real phi001 = phi.getInterpolatedHi(centre + Vec3(-offset, -offset, +offset), order);
|
||||||
@@ -1067,10 +1067,8 @@ void solveViscosity(const FlagGrid &flags,
|
|||||||
|
|
||||||
Real viscTop = 0.25 * (viscosity(i, j, k) + viscosity(i, j, k - 1) + viscosity(i, j + 1, k) +
|
Real viscTop = 0.25 * (viscosity(i, j, k) + viscosity(i, j, k - 1) + viscosity(i, j + 1, k) +
|
||||||
viscosity(i, j + 1, k - 1));
|
viscosity(i, j + 1, k - 1));
|
||||||
;
|
|
||||||
Real viscBottom = 0.25 * (viscosity(i, j, k) + viscosity(i, j, k - 1) +
|
Real viscBottom = 0.25 * (viscosity(i, j, k) + viscosity(i, j, k - 1) +
|
||||||
viscosity(i, j - 1, k) + viscosity(i, j - 1, k - 1));
|
viscosity(i, j - 1, k) + viscosity(i, j - 1, k - 1));
|
||||||
;
|
|
||||||
Real volTop = exVolLiquid(i, j + 1, k);
|
Real volTop = exVolLiquid(i, j + 1, k);
|
||||||
Real volBottom = exVolLiquid(i, j, k);
|
Real volBottom = exVolLiquid(i, j, k);
|
||||||
|
|
||||||
@@ -1224,7 +1222,7 @@ void solveViscosity(const FlagGrid &flags,
|
|||||||
uSolution, uRhs, uResidual, uSearch, flags, uTmp, uMatA, uVecRhs);
|
uSolution, uRhs, uResidual, uSearch, flags, uTmp, uMatA, uVecRhs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errMsg("2D Matrix application not yet supported in viscosity solver");
|
errMsg("Viscosity: 2D Matrix application not yet supported in viscosity solver");
|
||||||
}
|
}
|
||||||
|
|
||||||
// CG solver for V
|
// CG solver for V
|
||||||
@@ -1249,7 +1247,7 @@ void solveViscosity(const FlagGrid &flags,
|
|||||||
vSolution, vRhs, vResidual, vSearch, flags, vTmp, vMatA, vVecRhs);
|
vSolution, vRhs, vResidual, vSearch, flags, vTmp, vMatA, vVecRhs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errMsg("2D Matrix application not yet supported in viscosity solver");
|
errMsg("Viscosity: 2D Matrix application not yet supported in viscosity solver");
|
||||||
}
|
}
|
||||||
|
|
||||||
// CG solver for W
|
// CG solver for W
|
||||||
@@ -1274,7 +1272,7 @@ void solveViscosity(const FlagGrid &flags,
|
|||||||
wSolution, wRhs, wResidual, wSearch, flags, wTmp, wMatA, wVecRhs);
|
wSolution, wRhs, wResidual, wSearch, flags, wTmp, wMatA, wVecRhs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errMsg("2D Matrix application not yet supported in viscosity solver");
|
errMsg("Viscosity: 2D Matrix application not yet supported in viscosity solver");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same accuracy for all dimensions
|
// Same accuracy for all dimensions
|
||||||
@@ -1308,7 +1306,7 @@ void solveViscosity(const FlagGrid &flags,
|
|||||||
wRhs.copyFrom(wSearch);
|
wRhs.copyFrom(wSearch);
|
||||||
}
|
}
|
||||||
debMsg(
|
debMsg(
|
||||||
"Viscosity::solveViscosity done. "
|
"Viscosity: solveViscosity() done. "
|
||||||
"Iterations (u,v,w): ("
|
"Iterations (u,v,w): ("
|
||||||
<< uGcg->getIterations() << "," << vGcg->getIterations() << "," << wGcg->getIterations()
|
<< uGcg->getIterations() << "," << vGcg->getIterations() << "," << wGcg->getIterations()
|
||||||
<< "), "
|
<< "), "
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
# Standalone or with Blender
|
# Standalone or with Blender
|
||||||
if(NOT WITH_BLENDER AND WITH_CYCLES_STANDALONE)
|
if(NOT WITH_BLENDER AND WITH_CYCLES_STANDALONE)
|
||||||
set(CYCLES_INSTALL_PATH "")
|
set(CYCLES_INSTALL_PATH ${CMAKE_INSTALL_PREFIX})
|
||||||
else()
|
else()
|
||||||
set(WITH_CYCLES_BLENDER ON)
|
set(WITH_CYCLES_BLENDER ON)
|
||||||
# WINDOWS_PYTHON_DEBUG needs to write into the user addons folder since it will
|
# WINDOWS_PYTHON_DEBUG needs to write into the user addons folder since it will
|
||||||
@@ -379,6 +379,9 @@ endif()
|
|||||||
# Subdirectories
|
# Subdirectories
|
||||||
|
|
||||||
if(WITH_CYCLES_BLENDER)
|
if(WITH_CYCLES_BLENDER)
|
||||||
|
# Not needed to make cycles automated tests pass with -march=native.
|
||||||
|
# However Blender itself needs this flag.
|
||||||
|
remove_cc_flag("-ffp-contract=off")
|
||||||
add_definitions(-DWITH_BLENDER_GUARDEDALLOC)
|
add_definitions(-DWITH_BLENDER_GUARDEDALLOC)
|
||||||
add_subdirectory(blender)
|
add_subdirectory(blender)
|
||||||
endif()
|
endif()
|
||||||
|
@@ -133,12 +133,12 @@ static void scene_init()
|
|||||||
|
|
||||||
/* Camera width/height override? */
|
/* Camera width/height override? */
|
||||||
if (!(options.width == 0 || options.height == 0)) {
|
if (!(options.width == 0 || options.height == 0)) {
|
||||||
options.scene->camera->width = options.width;
|
options.scene->camera->set_full_width(options.width);
|
||||||
options.scene->camera->height = options.height;
|
options.scene->camera->set_full_height(options.height);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
options.width = options.scene->camera->width;
|
options.width = options.scene->camera->get_full_width();
|
||||||
options.height = options.scene->camera->height;
|
options.height = options.scene->camera->get_full_height();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate Viewplane */
|
/* Calculate Viewplane */
|
||||||
@@ -233,7 +233,7 @@ static void display()
|
|||||||
static void motion(int x, int y, int button)
|
static void motion(int x, int y, int button)
|
||||||
{
|
{
|
||||||
if (options.interactive) {
|
if (options.interactive) {
|
||||||
Transform matrix = options.session->scene->camera->matrix;
|
Transform matrix = options.session->scene->camera->get_matrix();
|
||||||
|
|
||||||
/* Translate */
|
/* Translate */
|
||||||
if (button == 0) {
|
if (button == 0) {
|
||||||
@@ -251,8 +251,8 @@ static void motion(int x, int y, int button)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Update and Reset */
|
/* Update and Reset */
|
||||||
options.session->scene->camera->matrix = matrix;
|
options.session->scene->camera->set_matrix(matrix);
|
||||||
options.session->scene->camera->need_update = true;
|
options.session->scene->camera->need_flags_update = true;
|
||||||
options.session->scene->camera->need_device_update = true;
|
options.session->scene->camera->need_device_update = true;
|
||||||
|
|
||||||
options.session->reset(session_buffer_params(), options.session_params.samples);
|
options.session->reset(session_buffer_params(), options.session_params.samples);
|
||||||
@@ -266,10 +266,10 @@ static void resize(int width, int height)
|
|||||||
|
|
||||||
if (options.session) {
|
if (options.session) {
|
||||||
/* Update camera */
|
/* Update camera */
|
||||||
options.session->scene->camera->width = width;
|
options.session->scene->camera->set_full_width(options.width);
|
||||||
options.session->scene->camera->height = height;
|
options.session->scene->camera->set_full_height(options.height);
|
||||||
options.session->scene->camera->compute_auto_viewplane();
|
options.session->scene->camera->compute_auto_viewplane();
|
||||||
options.session->scene->camera->need_update = true;
|
options.session->scene->camera->need_flags_update = true;
|
||||||
options.session->scene->camera->need_device_update = true;
|
options.session->scene->camera->need_device_update = true;
|
||||||
|
|
||||||
options.session->reset(session_buffer_params(), options.session_params.samples);
|
options.session->reset(session_buffer_params(), options.session_params.samples);
|
||||||
@@ -302,7 +302,7 @@ static void keyboard(unsigned char key)
|
|||||||
|
|
||||||
/* Navigation */
|
/* Navigation */
|
||||||
else if (options.interactive && (key == 'w' || key == 'a' || key == 's' || key == 'd')) {
|
else if (options.interactive && (key == 'w' || key == 'a' || key == 's' || key == 'd')) {
|
||||||
Transform matrix = options.session->scene->camera->matrix;
|
Transform matrix = options.session->scene->camera->get_matrix();
|
||||||
float3 translate;
|
float3 translate;
|
||||||
|
|
||||||
if (key == 'w')
|
if (key == 'w')
|
||||||
@@ -317,8 +317,8 @@ static void keyboard(unsigned char key)
|
|||||||
matrix = matrix * transform_translate(translate);
|
matrix = matrix * transform_translate(translate);
|
||||||
|
|
||||||
/* Update and Reset */
|
/* Update and Reset */
|
||||||
options.session->scene->camera->matrix = matrix;
|
options.session->scene->camera->set_matrix(matrix);
|
||||||
options.session->scene->camera->need_update = true;
|
options.session->scene->camera->need_flags_update = true;
|
||||||
options.session->scene->camera->need_device_update = true;
|
options.session->scene->camera->need_device_update = true;
|
||||||
|
|
||||||
options.session->reset(session_buffer_params(), options.session_params.samples);
|
options.session->reset(session_buffer_params(), options.session_params.samples);
|
||||||
@@ -345,10 +345,7 @@ static void keyboard(unsigned char key)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
options.session->scene->integrator->max_bounce = bounce;
|
options.session->scene->integrator->set_max_bounce(bounce);
|
||||||
|
|
||||||
/* Update and Reset */
|
|
||||||
options.session->scene->integrator->need_update = true;
|
|
||||||
|
|
||||||
options.session->reset(session_buffer_params(), options.session_params.samples);
|
options.session->reset(session_buffer_params(), options.session_params.samples);
|
||||||
}
|
}
|
||||||
|
@@ -190,17 +190,18 @@ static void xml_read_camera(XMLReadState &state, xml_node node)
|
|||||||
{
|
{
|
||||||
Camera *cam = state.scene->camera;
|
Camera *cam = state.scene->camera;
|
||||||
|
|
||||||
xml_read_int(&cam->width, node, "width");
|
int width = -1, height = -1;
|
||||||
xml_read_int(&cam->height, node, "height");
|
xml_read_int(&width, node, "width");
|
||||||
|
xml_read_int(&height, node, "height");
|
||||||
|
|
||||||
cam->full_width = cam->width;
|
cam->set_full_width(width);
|
||||||
cam->full_height = cam->height;
|
cam->set_full_height(height);
|
||||||
|
|
||||||
xml_read_node(state, cam, node);
|
xml_read_node(state, cam, node);
|
||||||
|
|
||||||
cam->matrix = state.tfm;
|
cam->set_matrix(state.tfm);
|
||||||
|
|
||||||
cam->need_update = true;
|
cam->need_flags_update = true;
|
||||||
cam->update(state.scene);
|
cam->update(state.scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,11 +339,13 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node
|
|||||||
|
|
||||||
if (node_name == "image_texture") {
|
if (node_name == "image_texture") {
|
||||||
ImageTextureNode *img = (ImageTextureNode *)snode;
|
ImageTextureNode *img = (ImageTextureNode *)snode;
|
||||||
img->filename = path_join(state.base, img->filename.string());
|
ustring filename(path_join(state.base, img->get_filename().string()));
|
||||||
|
img->set_filename(filename);
|
||||||
}
|
}
|
||||||
else if (node_name == "environment_texture") {
|
else if (node_name == "environment_texture") {
|
||||||
EnvironmentTextureNode *env = (EnvironmentTextureNode *)snode;
|
EnvironmentTextureNode *env = (EnvironmentTextureNode *)snode;
|
||||||
env->filename = path_join(state.base, env->filename.string());
|
ustring filename(path_join(state.base, env->get_filename().string()));
|
||||||
|
env->set_filename(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snode) {
|
if (snode) {
|
||||||
@@ -384,8 +387,8 @@ static Mesh *xml_add_mesh(Scene *scene, const Transform &tfm)
|
|||||||
|
|
||||||
/* create object*/
|
/* create object*/
|
||||||
Object *object = new Object();
|
Object *object = new Object();
|
||||||
object->geometry = mesh;
|
object->set_geometry(mesh);
|
||||||
object->tfm = tfm;
|
object->set_tfm(tfm);
|
||||||
scene->objects.push_back(object);
|
scene->objects.push_back(object);
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
@@ -395,7 +398,9 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
|
|||||||
{
|
{
|
||||||
/* add mesh */
|
/* add mesh */
|
||||||
Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
|
Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
|
||||||
mesh->used_shaders.push_back(state.shader);
|
array<Node *> used_shaders = mesh->get_used_shaders();
|
||||||
|
used_shaders.push_back_slow(state.shader);
|
||||||
|
mesh->set_used_shaders(used_shaders);
|
||||||
|
|
||||||
/* read state */
|
/* read state */
|
||||||
int shader = 0;
|
int shader = 0;
|
||||||
@@ -411,20 +416,24 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
|
|||||||
xml_read_int_array(nverts, node, "nverts");
|
xml_read_int_array(nverts, node, "nverts");
|
||||||
|
|
||||||
if (xml_equal_string(node, "subdivision", "catmull-clark")) {
|
if (xml_equal_string(node, "subdivision", "catmull-clark")) {
|
||||||
mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK;
|
mesh->set_subdivision_type(Mesh::SUBDIVISION_CATMULL_CLARK);
|
||||||
}
|
}
|
||||||
else if (xml_equal_string(node, "subdivision", "linear")) {
|
else if (xml_equal_string(node, "subdivision", "linear")) {
|
||||||
mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR;
|
mesh->set_subdivision_type(Mesh::SUBDIVISION_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
|
array<float3> P_array;
|
||||||
|
P_array = P;
|
||||||
|
|
||||||
|
if (mesh->get_subdivision_type() == Mesh::SUBDIVISION_NONE) {
|
||||||
/* create vertices */
|
/* create vertices */
|
||||||
mesh->verts = P;
|
|
||||||
|
mesh->set_verts(P_array);
|
||||||
|
|
||||||
size_t num_triangles = 0;
|
size_t num_triangles = 0;
|
||||||
for (size_t i = 0; i < nverts.size(); i++)
|
for (size_t i = 0; i < nverts.size(); i++)
|
||||||
num_triangles += nverts[i] - 2;
|
num_triangles += nverts[i] - 2;
|
||||||
mesh->reserve_mesh(mesh->verts.size(), num_triangles);
|
mesh->reserve_mesh(mesh->get_verts().size(), num_triangles);
|
||||||
|
|
||||||
/* create triangles */
|
/* create triangles */
|
||||||
int index_offset = 0;
|
int index_offset = 0;
|
||||||
@@ -474,7 +483,7 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* create vertices */
|
/* create vertices */
|
||||||
mesh->verts = P;
|
mesh->set_verts(P_array);
|
||||||
|
|
||||||
size_t num_ngons = 0;
|
size_t num_ngons = 0;
|
||||||
size_t num_corners = 0;
|
size_t num_corners = 0;
|
||||||
@@ -513,23 +522,20 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* setup subd params */
|
/* setup subd params */
|
||||||
if (!mesh->subd_params) {
|
float dicing_rate = state.dicing_rate;
|
||||||
mesh->subd_params = new SubdParams(mesh);
|
xml_read_float(&dicing_rate, node, "dicing_rate");
|
||||||
}
|
dicing_rate = std::max(0.1f, dicing_rate);
|
||||||
SubdParams &sdparams = *mesh->subd_params;
|
|
||||||
|
|
||||||
sdparams.dicing_rate = state.dicing_rate;
|
mesh->set_subd_dicing_rate(dicing_rate);
|
||||||
xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
|
mesh->set_subd_objecttoworld(state.tfm);
|
||||||
sdparams.dicing_rate = std::max(0.1f, sdparams.dicing_rate);
|
|
||||||
|
|
||||||
sdparams.objecttoworld = state.tfm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we don't yet support arbitrary attributes, for now add vertex
|
/* we don't yet support arbitrary attributes, for now add vertex
|
||||||
* coordinates as generated coordinates if requested */
|
* coordinates as generated coordinates if requested */
|
||||||
if (mesh->need_attribute(state.scene, ATTR_STD_GENERATED)) {
|
if (mesh->need_attribute(state.scene, ATTR_STD_GENERATED)) {
|
||||||
Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
|
Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
|
||||||
memcpy(attr->data_float3(), mesh->verts.data(), sizeof(float3) * mesh->verts.size());
|
memcpy(
|
||||||
|
attr->data_float3(), mesh->get_verts().data(), sizeof(float3) * mesh->get_verts().size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,7 +545,7 @@ static void xml_read_light(XMLReadState &state, xml_node node)
|
|||||||
{
|
{
|
||||||
Light *light = new Light();
|
Light *light = new Light();
|
||||||
|
|
||||||
light->shader = state.shader;
|
light->set_shader(state.shader);
|
||||||
xml_read_node(state, light, node);
|
xml_read_node(state, light, node);
|
||||||
|
|
||||||
state.scene->lights.push_back(light);
|
state.scene->lights.push_back(light);
|
||||||
|
@@ -59,6 +59,7 @@ class CyclesRender(bpy.types.RenderEngine):
|
|||||||
bl_use_exclude_layers = True
|
bl_use_exclude_layers = True
|
||||||
bl_use_save_buffers = True
|
bl_use_save_buffers = True
|
||||||
bl_use_spherical_stereo = True
|
bl_use_spherical_stereo = True
|
||||||
|
bl_use_custom_freestyle = True
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.session = None
|
self.session = None
|
||||||
|
@@ -1148,7 +1148,7 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
|
|||||||
split = layout.split(factor=0.65)
|
split = layout.split(factor=0.65)
|
||||||
|
|
||||||
if ob:
|
if ob:
|
||||||
split.template_ID(ob, "active_material", new="material.new", duplicate="material.duplicate")
|
split.template_ID(ob, "active_material", new="material.new")
|
||||||
row = split.row()
|
row = split.row()
|
||||||
|
|
||||||
if slot:
|
if slot:
|
||||||
|
@@ -67,11 +67,10 @@ static bool ObtainCacheParticleData(
|
|||||||
Transform tfm = get_transform(b_ob->matrix_world());
|
Transform tfm = get_transform(b_ob->matrix_world());
|
||||||
Transform itfm = transform_quick_inverse(tfm);
|
Transform itfm = transform_quick_inverse(tfm);
|
||||||
|
|
||||||
BL::Object::modifiers_iterator b_mod;
|
for (BL::Modifier &b_mod : b_ob->modifiers) {
|
||||||
for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
|
if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
|
||||||
if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
|
(background ? b_mod.show_render() : b_mod.show_viewport())) {
|
||||||
(background ? b_mod->show_render() : b_mod->show_viewport())) {
|
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
|
||||||
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
|
|
||||||
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
||||||
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
||||||
|
|
||||||
@@ -163,11 +162,10 @@ static bool ObtainCacheParticleUV(Hair *hair,
|
|||||||
|
|
||||||
CData->curve_uv.clear();
|
CData->curve_uv.clear();
|
||||||
|
|
||||||
BL::Object::modifiers_iterator b_mod;
|
for (BL::Modifier &b_mod : b_ob->modifiers) {
|
||||||
for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
|
if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
|
||||||
if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
|
(background ? b_mod.show_render() : b_mod.show_viewport())) {
|
||||||
(background ? b_mod->show_render() : b_mod->show_viewport())) {
|
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
|
||||||
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
|
|
||||||
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
||||||
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
||||||
|
|
||||||
@@ -226,11 +224,10 @@ static bool ObtainCacheParticleVcol(Hair *hair,
|
|||||||
|
|
||||||
CData->curve_vcol.clear();
|
CData->curve_vcol.clear();
|
||||||
|
|
||||||
BL::Object::modifiers_iterator b_mod;
|
for (BL::Modifier &b_mod : b_ob->modifiers) {
|
||||||
for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
|
if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
|
||||||
if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
|
(background ? b_mod.show_render() : b_mod.show_viewport())) {
|
||||||
(background ? b_mod->show_render() : b_mod->show_viewport())) {
|
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
|
||||||
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
|
|
||||||
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
||||||
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
||||||
|
|
||||||
@@ -510,11 +507,10 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int
|
|||||||
bool BlenderSync::object_has_particle_hair(BL::Object b_ob)
|
bool BlenderSync::object_has_particle_hair(BL::Object b_ob)
|
||||||
{
|
{
|
||||||
/* Test if the object has a particle modifier with hair. */
|
/* Test if the object has a particle modifier with hair. */
|
||||||
BL::Object::modifiers_iterator b_mod;
|
for (BL::Modifier &b_mod : b_ob.modifiers) {
|
||||||
for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
|
if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
|
||||||
if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
|
(preview ? b_mod.show_viewport() : b_mod.show_render())) {
|
||||||
(preview ? b_mod->show_viewport() : b_mod->show_render())) {
|
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
|
||||||
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
|
|
||||||
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
||||||
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
||||||
|
|
||||||
@@ -678,9 +674,7 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
|
|||||||
/* Export curves and points. */
|
/* Export curves and points. */
|
||||||
vector<float> points_length;
|
vector<float> points_length;
|
||||||
|
|
||||||
BL::Hair::curves_iterator b_curve_iter;
|
for (BL::HairCurve &b_curve : b_hair.curves) {
|
||||||
for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
|
|
||||||
BL::HairCurve b_curve = *b_curve_iter;
|
|
||||||
const int first_point_index = b_curve.first_point_index();
|
const int first_point_index = b_curve.first_point_index();
|
||||||
const int num_points = b_curve.num_points();
|
const int num_points = b_curve.num_points();
|
||||||
|
|
||||||
@@ -748,9 +742,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
|
|||||||
int num_motion_keys = 0;
|
int num_motion_keys = 0;
|
||||||
int curve_index = 0;
|
int curve_index = 0;
|
||||||
|
|
||||||
BL::Hair::curves_iterator b_curve_iter;
|
for (BL::HairCurve &b_curve : b_hair.curves) {
|
||||||
for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
|
|
||||||
BL::HairCurve b_curve = *b_curve_iter;
|
|
||||||
const int first_point_index = b_curve.first_point_index();
|
const int first_point_index = b_curve.first_point_index();
|
||||||
const int num_points = b_curve.num_points();
|
const int num_points = b_curve.num_points();
|
||||||
|
|
||||||
@@ -855,10 +847,7 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *ha
|
|||||||
hair->set_value(socket, new_hair, socket);
|
hair->set_value(socket, new_hair, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
hair->attributes.clear();
|
hair->attributes.update(std::move(new_hair.attributes));
|
||||||
foreach (Attribute &attr, new_hair.attributes.attributes) {
|
|
||||||
hair->attributes.attributes.push_back(std::move(attr));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tag update */
|
/* tag update */
|
||||||
|
|
||||||
|
@@ -47,11 +47,9 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
|
|||||||
|
|
||||||
/* Find cycles preferences. */
|
/* Find cycles preferences. */
|
||||||
PointerRNA cpreferences;
|
PointerRNA cpreferences;
|
||||||
BL::Preferences::addons_iterator b_addon_iter;
|
for (BL::Addon &b_addon : b_preferences.addons) {
|
||||||
for (b_preferences.addons.begin(b_addon_iter); b_addon_iter != b_preferences.addons.end();
|
if (b_addon.module() == "cycles") {
|
||||||
++b_addon_iter) {
|
cpreferences = b_addon.preferences().ptr;
|
||||||
if (b_addon_iter->module() == "cycles") {
|
|
||||||
cpreferences = b_addon_iter->preferences().ptr;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,32 +42,20 @@ static Geometry::Type determine_geom_type(BL::Object &b_ob, bool use_particle_ha
|
|||||||
return Geometry::MESH;
|
return Geometry::MESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
|
array<Node *> BlenderSync::find_used_shaders(BL::Object &b_ob)
|
||||||
BL::Object &b_ob,
|
|
||||||
BL::Object &b_ob_instance,
|
|
||||||
bool object_updated,
|
|
||||||
bool use_particle_hair,
|
|
||||||
TaskPool *task_pool)
|
|
||||||
{
|
{
|
||||||
/* Test if we can instance or if the object is modified. */
|
|
||||||
BL::ID b_ob_data = b_ob.data();
|
|
||||||
BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
|
|
||||||
BL::Material material_override = view_layer.material_override;
|
BL::Material material_override = view_layer.material_override;
|
||||||
Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume :
|
Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume :
|
||||||
scene->default_surface;
|
scene->default_surface;
|
||||||
Geometry::Type geom_type = determine_geom_type(b_ob, use_particle_hair);
|
|
||||||
GeometryKey key(b_key_id.ptr.data, geom_type);
|
|
||||||
|
|
||||||
/* Find shader indices. */
|
|
||||||
array<Node *> used_shaders;
|
array<Node *> used_shaders;
|
||||||
|
|
||||||
BL::Object::material_slots_iterator slot;
|
for (BL::MaterialSlot &b_slot : b_ob.material_slots) {
|
||||||
for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
|
|
||||||
if (material_override) {
|
if (material_override) {
|
||||||
find_shader(material_override, used_shaders, default_shader);
|
find_shader(material_override, used_shaders, default_shader);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BL::ID b_material(slot->material());
|
BL::ID b_material(b_slot.material());
|
||||||
find_shader(b_material, used_shaders, default_shader);
|
find_shader(b_material, used_shaders, default_shader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,6 +67,25 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
|
|||||||
used_shaders.push_back_slow(default_shader);
|
used_shaders.push_back_slow(default_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return used_shaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
|
||||||
|
BL::Object &b_ob,
|
||||||
|
BL::Object &b_ob_instance,
|
||||||
|
bool object_updated,
|
||||||
|
bool use_particle_hair,
|
||||||
|
TaskPool *task_pool)
|
||||||
|
{
|
||||||
|
/* Test if we can instance or if the object is modified. */
|
||||||
|
BL::ID b_ob_data = b_ob.data();
|
||||||
|
BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
|
||||||
|
Geometry::Type geom_type = determine_geom_type(b_ob, use_particle_hair);
|
||||||
|
GeometryKey key(b_key_id.ptr.data, geom_type);
|
||||||
|
|
||||||
|
/* Find shader indices. */
|
||||||
|
array<Node *> used_shaders = find_used_shaders(b_ob);
|
||||||
|
|
||||||
/* Ensure we only sync instanced geometry once. */
|
/* Ensure we only sync instanced geometry once. */
|
||||||
Geometry *geom = geometry_map.find(key);
|
Geometry *geom = geometry_map.find(key);
|
||||||
if (geom) {
|
if (geom) {
|
||||||
@@ -124,7 +131,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
|
|||||||
|
|
||||||
foreach (Node *node, geom->get_used_shaders()) {
|
foreach (Node *node, geom->get_used_shaders()) {
|
||||||
Shader *shader = static_cast<Shader *>(node);
|
Shader *shader = static_cast<Shader *>(node);
|
||||||
if (shader->need_update_geometry) {
|
if (shader->need_update_geometry()) {
|
||||||
attribute_recalc = true;
|
attribute_recalc = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -285,12 +285,10 @@ static void attr_create_sculpt_vertex_color(Scene *scene,
|
|||||||
BL::Mesh &b_mesh,
|
BL::Mesh &b_mesh,
|
||||||
bool subdivision)
|
bool subdivision)
|
||||||
{
|
{
|
||||||
BL::Mesh::sculpt_vertex_colors_iterator l;
|
for (BL::MeshVertColorLayer &l : b_mesh.sculpt_vertex_colors) {
|
||||||
|
const bool active_render = l.active_render();
|
||||||
for (b_mesh.sculpt_vertex_colors.begin(l); l != b_mesh.sculpt_vertex_colors.end(); ++l) {
|
|
||||||
const bool active_render = l->active_render();
|
|
||||||
AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
|
AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
|
||||||
ustring vcol_name = ustring(l->name().c_str());
|
ustring vcol_name = ustring(l.name().c_str());
|
||||||
|
|
||||||
const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
|
const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
|
||||||
mesh->need_attribute(scene, vcol_std);
|
mesh->need_attribute(scene, vcol_std);
|
||||||
@@ -307,7 +305,7 @@ static void attr_create_sculpt_vertex_color(Scene *scene,
|
|||||||
int numverts = b_mesh.vertices.length();
|
int numverts = b_mesh.vertices.length();
|
||||||
|
|
||||||
for (int i = 0; i < numverts; i++) {
|
for (int i = 0; i < numverts; i++) {
|
||||||
*(cdata++) = get_float4(l->data[i].color());
|
*(cdata++) = get_float4(l.data[i].color());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,12 +313,10 @@ static void attr_create_sculpt_vertex_color(Scene *scene,
|
|||||||
/* Create vertex color attributes. */
|
/* Create vertex color attributes. */
|
||||||
static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
|
static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
|
||||||
{
|
{
|
||||||
BL::Mesh::vertex_colors_iterator l;
|
for (BL::MeshLoopColorLayer &l : b_mesh.vertex_colors) {
|
||||||
|
const bool active_render = l.active_render();
|
||||||
for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
|
|
||||||
const bool active_render = l->active_render();
|
|
||||||
AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
|
AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
|
||||||
ustring vcol_name = ustring(l->name().c_str());
|
ustring vcol_name = ustring(l.name().c_str());
|
||||||
|
|
||||||
const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
|
const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
|
||||||
mesh->need_attribute(scene, vcol_std);
|
mesh->need_attribute(scene, vcol_std);
|
||||||
@@ -339,13 +335,12 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
|
|||||||
vcol_attr = mesh->subd_attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
|
vcol_attr = mesh->subd_attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
BL::Mesh::polygons_iterator p;
|
|
||||||
uchar4 *cdata = vcol_attr->data_uchar4();
|
uchar4 *cdata = vcol_attr->data_uchar4();
|
||||||
|
|
||||||
for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
|
for (BL::MeshPolygon &p : b_mesh.polygons) {
|
||||||
int n = p->loop_total();
|
int n = p.loop_total();
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
float4 color = get_float4(l->data[p->loop_start() + i].color());
|
float4 color = get_float4(l.data[p.loop_start() + i].color());
|
||||||
/* Compress/encode vertex color using the sRGB curve. */
|
/* Compress/encode vertex color using the sRGB curve. */
|
||||||
*(cdata++) = color_float4_to_uchar4(color);
|
*(cdata++) = color_float4_to_uchar4(color);
|
||||||
}
|
}
|
||||||
@@ -359,14 +354,13 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
|
|||||||
vcol_attr = mesh->attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
|
vcol_attr = mesh->attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
BL::Mesh::loop_triangles_iterator t;
|
|
||||||
uchar4 *cdata = vcol_attr->data_uchar4();
|
uchar4 *cdata = vcol_attr->data_uchar4();
|
||||||
|
|
||||||
for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
|
for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
|
||||||
int3 li = get_int3(t->loops());
|
int3 li = get_int3(t.loops());
|
||||||
float4 c1 = get_float4(l->data[li[0]].color());
|
float4 c1 = get_float4(l.data[li[0]].color());
|
||||||
float4 c2 = get_float4(l->data[li[1]].color());
|
float4 c2 = get_float4(l.data[li[1]].color());
|
||||||
float4 c3 = get_float4(l->data[li[2]].color());
|
float4 c3 = get_float4(l.data[li[2]].color());
|
||||||
|
|
||||||
/* Compress/encode vertex color using the sRGB curve. */
|
/* Compress/encode vertex color using the sRGB curve. */
|
||||||
cdata[0] = color_float4_to_uchar4(c1);
|
cdata[0] = color_float4_to_uchar4(c1);
|
||||||
@@ -383,14 +377,12 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
|
|||||||
static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
|
static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
|
||||||
{
|
{
|
||||||
if (b_mesh.uv_layers.length() != 0) {
|
if (b_mesh.uv_layers.length() != 0) {
|
||||||
BL::Mesh::uv_layers_iterator l;
|
for (BL::MeshUVLoopLayer &l : b_mesh.uv_layers) {
|
||||||
|
const bool active_render = l.active_render();
|
||||||
for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) {
|
|
||||||
const bool active_render = l->active_render();
|
|
||||||
AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
|
AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
|
||||||
ustring uv_name = ustring(l->name().c_str());
|
ustring uv_name = ustring(l.name().c_str());
|
||||||
AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
|
AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
|
||||||
ustring tangent_name = ustring((string(l->name().c_str()) + ".tangent").c_str());
|
ustring tangent_name = ustring((string(l.name().c_str()) + ".tangent").c_str());
|
||||||
|
|
||||||
/* Denotes whether UV map was requested directly. */
|
/* Denotes whether UV map was requested directly. */
|
||||||
const bool need_uv = mesh->need_attribute(scene, uv_name) ||
|
const bool need_uv = mesh->need_attribute(scene, uv_name) ||
|
||||||
@@ -412,14 +404,13 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
|
|||||||
uv_attr = mesh->attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
|
uv_attr = mesh->attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
|
||||||
}
|
}
|
||||||
|
|
||||||
BL::Mesh::loop_triangles_iterator t;
|
|
||||||
float2 *fdata = uv_attr->data_float2();
|
float2 *fdata = uv_attr->data_float2();
|
||||||
|
|
||||||
for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
|
for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
|
||||||
int3 li = get_int3(t->loops());
|
int3 li = get_int3(t.loops());
|
||||||
fdata[0] = get_float2(l->data[li[0]].uv());
|
fdata[0] = get_float2(l.data[li[0]].uv());
|
||||||
fdata[1] = get_float2(l->data[li[1]].uv());
|
fdata[1] = get_float2(l.data[li[1]].uv());
|
||||||
fdata[2] = get_float2(l->data[li[2]].uv());
|
fdata[2] = get_float2(l.data[li[2]].uv());
|
||||||
fdata += 3;
|
fdata += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -427,10 +418,10 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
|
|||||||
/* UV tangent */
|
/* UV tangent */
|
||||||
if (need_tangent) {
|
if (need_tangent) {
|
||||||
AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
|
AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
|
||||||
ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
|
ustring sign_name = ustring((string(l.name().c_str()) + ".tangent_sign").c_str());
|
||||||
bool need_sign = (mesh->need_attribute(scene, sign_name) ||
|
bool need_sign = (mesh->need_attribute(scene, sign_name) ||
|
||||||
mesh->need_attribute(scene, sign_std));
|
mesh->need_attribute(scene, sign_std));
|
||||||
mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render);
|
mikk_compute_tangents(b_mesh, l.name().c_str(), mesh, need_sign, active_render);
|
||||||
}
|
}
|
||||||
/* Remove temporarily created UV attribute. */
|
/* Remove temporarily created UV attribute. */
|
||||||
if (!need_uv && uv_attr != NULL) {
|
if (!need_uv && uv_attr != NULL) {
|
||||||
@@ -480,13 +471,12 @@ static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
|
|||||||
uv_attr->flags |= ATTR_SUBDIVIDED;
|
uv_attr->flags |= ATTR_SUBDIVIDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
BL::Mesh::polygons_iterator p;
|
|
||||||
float2 *fdata = uv_attr->data_float2();
|
float2 *fdata = uv_attr->data_float2();
|
||||||
|
|
||||||
for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
|
for (BL::MeshPolygon &p : b_mesh.polygons) {
|
||||||
int n = p->loop_total();
|
int n = p.loop_total();
|
||||||
for (int j = 0; j < n; j++) {
|
for (int j = 0; j < n; j++) {
|
||||||
*(fdata++) = get_float2(l->data[p->loop_start() + j].uv());
|
*(fdata++) = get_float2(l->data[p.loop_start() + j].uv());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -706,9 +696,8 @@ static void attr_create_random_per_island(Scene *scene,
|
|||||||
|
|
||||||
DisjointSet vertices_sets(number_of_vertices);
|
DisjointSet vertices_sets(number_of_vertices);
|
||||||
|
|
||||||
BL::Mesh::edges_iterator e;
|
for (BL::MeshEdge &e : b_mesh.edges) {
|
||||||
for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
|
vertices_sets.join(e.vertices()[0], e.vertices()[1]);
|
||||||
vertices_sets.join(e->vertices()[0], e->vertices()[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
|
AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
|
||||||
@@ -716,15 +705,13 @@ static void attr_create_random_per_island(Scene *scene,
|
|||||||
float *data = attribute->data_float();
|
float *data = attribute->data_float();
|
||||||
|
|
||||||
if (!subdivision) {
|
if (!subdivision) {
|
||||||
BL::Mesh::loop_triangles_iterator t;
|
for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
|
||||||
for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
|
data[t.index()] = hash_uint_to_float(vertices_sets.find(t.vertices()[0]));
|
||||||
data[t->index()] = hash_uint_to_float(vertices_sets.find(t->vertices()[0]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BL::Mesh::polygons_iterator p;
|
for (BL::MeshPolygon &p : b_mesh.polygons) {
|
||||||
for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
|
data[p.index()] = hash_uint_to_float(vertices_sets.find(p.vertices()[0]));
|
||||||
data[p->index()] = hash_uint_to_float(vertices_sets.find(p->vertices()[0]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -756,10 +743,9 @@ static void create_mesh(Scene *scene,
|
|||||||
numtris = numfaces;
|
numtris = numfaces;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BL::Mesh::polygons_iterator p;
|
for (BL::MeshPolygon &p : b_mesh.polygons) {
|
||||||
for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
|
numngons += (p.loop_total() == 4) ? 0 : 1;
|
||||||
numngons += (p->loop_total() == 4) ? 0 : 1;
|
numcorners += p.loop_total();
|
||||||
numcorners += p->loop_total();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,17 +789,15 @@ static void create_mesh(Scene *scene,
|
|||||||
|
|
||||||
/* create faces */
|
/* create faces */
|
||||||
if (!subdivision) {
|
if (!subdivision) {
|
||||||
BL::Mesh::loop_triangles_iterator t;
|
for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
|
||||||
|
BL::MeshPolygon p = b_mesh.polygons[t.polygon_index()];
|
||||||
for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
|
int3 vi = get_int3(t.vertices());
|
||||||
BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()];
|
|
||||||
int3 vi = get_int3(t->vertices());
|
|
||||||
|
|
||||||
int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
|
int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
|
||||||
bool smooth = p.use_smooth() || use_loop_normals;
|
bool smooth = p.use_smooth() || use_loop_normals;
|
||||||
|
|
||||||
if (use_loop_normals) {
|
if (use_loop_normals) {
|
||||||
BL::Array<float, 9> loop_normals = t->split_normals();
|
BL::Array<float, 9> loop_normals = t.split_normals();
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
N[vi[i]] = make_float3(
|
N[vi[i]] = make_float3(
|
||||||
loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
|
loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
|
||||||
@@ -828,18 +812,17 @@ static void create_mesh(Scene *scene,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BL::Mesh::polygons_iterator p;
|
|
||||||
vector<int> vi;
|
vector<int> vi;
|
||||||
|
|
||||||
for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
|
for (BL::MeshPolygon &p : b_mesh.polygons) {
|
||||||
int n = p->loop_total();
|
int n = p.loop_total();
|
||||||
int shader = clamp(p->material_index(), 0, used_shaders.size() - 1);
|
int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
|
||||||
bool smooth = p->use_smooth() || use_loop_normals;
|
bool smooth = p.use_smooth() || use_loop_normals;
|
||||||
|
|
||||||
vi.resize(n);
|
vi.resize(n);
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
/* NOTE: Autosmooth is already taken care about. */
|
/* NOTE: Autosmooth is already taken care about. */
|
||||||
vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
|
vi[i] = b_mesh.loops[p.loop_start() + i].vertex_index();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create subd faces */
|
/* create subd faces */
|
||||||
@@ -891,19 +874,18 @@ static void create_subd_mesh(Scene *scene,
|
|||||||
|
|
||||||
/* export creases */
|
/* export creases */
|
||||||
size_t num_creases = 0;
|
size_t num_creases = 0;
|
||||||
BL::Mesh::edges_iterator e;
|
|
||||||
|
|
||||||
for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
|
for (BL::MeshEdge &e : b_mesh.edges) {
|
||||||
if (e->crease() != 0.0f) {
|
if (e.crease() != 0.0f) {
|
||||||
num_creases++;
|
num_creases++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh->reserve_subd_creases(num_creases);
|
mesh->reserve_subd_creases(num_creases);
|
||||||
|
|
||||||
for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
|
for (BL::MeshEdge &e : b_mesh.edges) {
|
||||||
if (e->crease() != 0.0f) {
|
if (e.crease() != 0.0f) {
|
||||||
mesh->add_crease(e->vertices()[0], e->vertices()[1], e->crease());
|
mesh->add_crease(e.vertices()[0], e.vertices()[1], e.crease());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1075,15 +1057,8 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me
|
|||||||
mesh->set_value(socket, new_mesh, socket);
|
mesh->set_value(socket, new_mesh, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh->attributes.clear();
|
mesh->attributes.update(std::move(new_mesh.attributes));
|
||||||
foreach (Attribute &attr, new_mesh.attributes.attributes) {
|
mesh->subd_attributes.update(std::move(new_mesh.subd_attributes));
|
||||||
mesh->attributes.attributes.push_back(std::move(attr));
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh->subd_attributes.clear();
|
|
||||||
foreach (Attribute &attr, new_mesh.subd_attributes.attributes) {
|
|
||||||
mesh->subd_attributes.attributes.push_back(std::move(attr));
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh->set_num_subd_faces(new_mesh.get_num_subd_faces());
|
mesh->set_num_subd_faces(new_mesh.get_num_subd_faces());
|
||||||
|
|
||||||
|
@@ -51,10 +51,11 @@ bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* object level material links */
|
/* object level material links */
|
||||||
BL::Object::material_slots_iterator slot;
|
for (BL::MaterialSlot &b_slot : b_ob.material_slots) {
|
||||||
for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
|
if (b_slot.link() == BL::MaterialSlot::link_OBJECT) {
|
||||||
if (slot->link() == BL::MaterialSlot::link_OBJECT)
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -243,9 +244,6 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
|
|||||||
|
|
||||||
/* holdout */
|
/* holdout */
|
||||||
object->set_use_holdout(use_holdout);
|
object->set_use_holdout(use_holdout);
|
||||||
if (object->use_holdout_is_modified()) {
|
|
||||||
scene->object_manager->tag_update(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
object->set_visibility(visibility);
|
object->set_visibility(visibility);
|
||||||
|
|
||||||
|
@@ -57,7 +57,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
|
|||||||
|
|
||||||
/* no update needed? */
|
/* no update needed? */
|
||||||
if (!need_update && !object->get_geometry()->is_modified() &&
|
if (!need_update && !object->get_geometry()->is_modified() &&
|
||||||
!scene->object_manager->need_update)
|
!scene->object_manager->need_update())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* first time used in this sync loop? clear and tag update */
|
/* first time used in this sync loop? clear and tag update */
|
||||||
@@ -85,7 +85,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
|
|||||||
object->set_particle_index(psys->particles.size() - 1);
|
object->set_particle_index(psys->particles.size() - 1);
|
||||||
|
|
||||||
if (object->particle_index_is_modified())
|
if (object->particle_index_is_modified())
|
||||||
scene->object_manager->tag_update(scene);
|
scene->object_manager->tag_update(scene, ObjectManager::PARTICLE_MODIFIED);
|
||||||
|
|
||||||
/* return that this object has particle data */
|
/* return that this object has particle data */
|
||||||
return true;
|
return true;
|
||||||
|
@@ -597,22 +597,19 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
|
|||||||
bool removed;
|
bool removed;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
BL::Node::inputs_iterator b_input;
|
|
||||||
BL::Node::outputs_iterator b_output;
|
|
||||||
|
|
||||||
removed = false;
|
removed = false;
|
||||||
|
|
||||||
for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
|
for (BL::NodeSocket &b_input : b_node.inputs) {
|
||||||
if (used_sockets.find(b_input->ptr.data) == used_sockets.end()) {
|
if (used_sockets.find(b_input.ptr.data) == used_sockets.end()) {
|
||||||
b_node.inputs.remove(b_data, *b_input);
|
b_node.inputs.remove(b_data, b_input);
|
||||||
removed = true;
|
removed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
|
for (BL::NodeSocket &b_output : b_node.outputs) {
|
||||||
if (used_sockets.find(b_output->ptr.data) == used_sockets.end()) {
|
if (used_sockets.find(b_output.ptr.data) == used_sockets.end()) {
|
||||||
b_node.outputs.remove(b_data, *b_output);
|
b_node.outputs.remove(b_data, b_output);
|
||||||
removed = true;
|
removed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -358,11 +358,7 @@ void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
|
|||||||
|
|
||||||
if (do_read_only) {
|
if (do_read_only) {
|
||||||
/* copy each pass */
|
/* copy each pass */
|
||||||
BL::RenderLayer::passes_iterator b_iter;
|
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
||||||
|
|
||||||
for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
|
|
||||||
BL::RenderPass b_pass(*b_iter);
|
|
||||||
|
|
||||||
/* find matching pass type */
|
/* find matching pass type */
|
||||||
PassType pass_type = BlenderSync::get_pass_type(b_pass);
|
PassType pass_type = BlenderSync::get_pass_type(b_pass);
|
||||||
int components = b_pass.channels();
|
int components = b_pass.channels();
|
||||||
@@ -552,7 +548,6 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
|
|||||||
int seed = scene->integrator->get_seed();
|
int seed = scene->integrator->get_seed();
|
||||||
seed += hash_uint2(seed, hash_uint2(view_index * 0xdeadbeef, 0));
|
seed += hash_uint2(seed, hash_uint2(view_index * 0xdeadbeef, 0));
|
||||||
scene->integrator->set_seed(seed);
|
scene->integrator->set_seed(seed);
|
||||||
scene->integrator->tag_update(scene);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update number of samples per layer. */
|
/* Update number of samples per layer. */
|
||||||
@@ -736,10 +731,7 @@ void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay,
|
|||||||
|
|
||||||
if (!do_update_only) {
|
if (!do_update_only) {
|
||||||
/* copy each pass */
|
/* copy each pass */
|
||||||
BL::RenderLayer::passes_iterator b_iter;
|
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
||||||
|
|
||||||
for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
|
|
||||||
BL::RenderPass b_pass(*b_iter);
|
|
||||||
int components = b_pass.channels();
|
int components = b_pass.channels();
|
||||||
|
|
||||||
/* Copy pixels from regular render passes. */
|
/* Copy pixels from regular render passes. */
|
||||||
@@ -1116,10 +1108,6 @@ void BlenderSession::update_resumable_tile_manager(int num_samples)
|
|||||||
|
|
||||||
scene->integrator->set_start_sample(rounded_range_start_sample);
|
scene->integrator->set_start_sample(rounded_range_start_sample);
|
||||||
|
|
||||||
if (scene->integrator->is_modified()) {
|
|
||||||
scene->integrator->tag_update(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
session->tile_manager.range_start_sample = rounded_range_start_sample;
|
session->tile_manager.range_start_sample = rounded_range_start_sample;
|
||||||
session->tile_manager.range_num_samples = rounded_range_num_samples;
|
session->tile_manager.range_num_samples = rounded_range_num_samples;
|
||||||
}
|
}
|
||||||
|
@@ -148,15 +148,13 @@ BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_r
|
|||||||
|
|
||||||
static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name)
|
static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name)
|
||||||
{
|
{
|
||||||
BL::Node::outputs_iterator b_out;
|
for (BL::NodeSocket &b_out : b_node.outputs) {
|
||||||
|
if (b_out.name() == name) {
|
||||||
for (b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
|
return b_out;
|
||||||
if (b_out->name() == name)
|
}
|
||||||
return *b_out;
|
}
|
||||||
|
|
||||||
assert(0);
|
assert(0);
|
||||||
|
return *b_node.outputs.begin();
|
||||||
return *b_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static float3 get_node_output_rgba(BL::Node &b_node, const string &name)
|
static float3 get_node_output_rgba(BL::Node &b_node, const string &name)
|
||||||
@@ -723,9 +721,8 @@ static ShaderNode *add_node(Scene *scene,
|
|||||||
image->set_alpha_type(get_image_alpha_type(b_image));
|
image->set_alpha_type(get_image_alpha_type(b_image));
|
||||||
|
|
||||||
array<int> tiles;
|
array<int> tiles;
|
||||||
BL::Image::tiles_iterator b_iter;
|
for (BL::UDIMTile &b_tile : b_image.tiles) {
|
||||||
for (b_image.tiles.begin(b_iter); b_iter != b_image.tiles.end(); ++b_iter) {
|
tiles.push_back_slow(b_tile.number());
|
||||||
tiles.push_back_slow(b_iter->number());
|
|
||||||
}
|
}
|
||||||
image->set_tiles(tiles);
|
image->set_tiles(tiles);
|
||||||
|
|
||||||
@@ -885,7 +882,7 @@ static ShaderNode *add_node(Scene *scene,
|
|||||||
sky->set_sun_intensity(b_sky_node.sun_intensity());
|
sky->set_sun_intensity(b_sky_node.sun_intensity());
|
||||||
sky->set_sun_elevation(b_sky_node.sun_elevation());
|
sky->set_sun_elevation(b_sky_node.sun_elevation());
|
||||||
sky->set_sun_rotation(b_sky_node.sun_rotation());
|
sky->set_sun_rotation(b_sky_node.sun_rotation());
|
||||||
sky->set_altitude(1000.0f * b_sky_node.altitude());
|
sky->set_altitude(b_sky_node.altitude());
|
||||||
sky->set_air_density(b_sky_node.air_density());
|
sky->set_air_density(b_sky_node.air_density());
|
||||||
sky->set_dust_density(b_sky_node.dust_density());
|
sky->set_dust_density(b_sky_node.dust_density());
|
||||||
sky->set_ozone_density(b_sky_node.ozone_density());
|
sky->set_ozone_density(b_sky_node.ozone_density());
|
||||||
@@ -1012,18 +1009,18 @@ static ShaderInput *node_find_input_by_name(ShaderNode *node,
|
|||||||
string name = b_socket.name();
|
string name = b_socket.name();
|
||||||
|
|
||||||
if (node_use_modified_socket_name(node)) {
|
if (node_use_modified_socket_name(node)) {
|
||||||
BL::Node::inputs_iterator b_input;
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
int counter = 0, total = 0;
|
int counter = 0, total = 0;
|
||||||
|
|
||||||
for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
|
for (BL::NodeSocket &b_input : b_node.inputs) {
|
||||||
if (b_input->name() == name) {
|
if (b_input.name() == name) {
|
||||||
if (!found)
|
if (!found) {
|
||||||
counter++;
|
counter++;
|
||||||
|
}
|
||||||
total++;
|
total++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b_input->ptr.data == b_socket.ptr.data)
|
if (b_input.ptr.data == b_socket.ptr.data)
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1045,19 +1042,20 @@ static ShaderOutput *node_find_output_by_name(ShaderNode *node,
|
|||||||
string name = b_socket.name();
|
string name = b_socket.name();
|
||||||
|
|
||||||
if (node_use_modified_socket_name(node)) {
|
if (node_use_modified_socket_name(node)) {
|
||||||
BL::Node::outputs_iterator b_output;
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
int counter = 0, total = 0;
|
int counter = 0, total = 0;
|
||||||
|
|
||||||
for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
|
for (BL::NodeSocket &b_output : b_node.outputs) {
|
||||||
if (b_output->name() == name) {
|
if (b_output.name() == name) {
|
||||||
if (!found)
|
if (!found) {
|
||||||
counter++;
|
counter++;
|
||||||
|
}
|
||||||
total++;
|
total++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b_output->ptr.data == b_socket.ptr.data)
|
if (b_output.ptr.data == b_socket.ptr.data) {
|
||||||
found = true;
|
found = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rename if needed */
|
/* rename if needed */
|
||||||
@@ -1082,25 +1080,19 @@ static void add_nodes(Scene *scene,
|
|||||||
const ProxyMap &proxy_output_map)
|
const ProxyMap &proxy_output_map)
|
||||||
{
|
{
|
||||||
/* add nodes */
|
/* add nodes */
|
||||||
BL::ShaderNodeTree::nodes_iterator b_node;
|
|
||||||
PtrInputMap input_map;
|
PtrInputMap input_map;
|
||||||
PtrOutputMap output_map;
|
PtrOutputMap output_map;
|
||||||
|
|
||||||
BL::Node::inputs_iterator b_input;
|
|
||||||
BL::Node::outputs_iterator b_output;
|
|
||||||
|
|
||||||
/* find the node to use for output if there are multiple */
|
/* find the node to use for output if there are multiple */
|
||||||
BL::ShaderNode output_node = b_ntree.get_output_node(
|
BL::ShaderNode output_node = b_ntree.get_output_node(
|
||||||
BL::ShaderNodeOutputMaterial::target_CYCLES);
|
BL::ShaderNodeOutputMaterial::target_CYCLES);
|
||||||
|
|
||||||
/* add nodes */
|
/* add nodes */
|
||||||
for (b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
|
for (BL::Node &b_node : b_ntree.nodes) {
|
||||||
if (b_node->mute() || b_node->is_a(&RNA_NodeReroute)) {
|
if (b_node.mute() || b_node.is_a(&RNA_NodeReroute)) {
|
||||||
/* replace muted node with internal links */
|
/* replace muted node with internal links */
|
||||||
BL::Node::internal_links_iterator b_link;
|
for (BL::NodeLink &b_link : b_node.internal_links) {
|
||||||
for (b_node->internal_links.begin(b_link); b_link != b_node->internal_links.end();
|
BL::NodeSocket to_socket(b_link.to_socket());
|
||||||
++b_link) {
|
|
||||||
BL::NodeSocket to_socket(b_link->to_socket());
|
|
||||||
SocketType::Type to_socket_type = convert_socket_type(to_socket);
|
SocketType::Type to_socket_type = convert_socket_type(to_socket);
|
||||||
if (to_socket_type == SocketType::UNDEFINED) {
|
if (to_socket_type == SocketType::UNDEFINED) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1108,22 +1100,22 @@ static void add_nodes(Scene *scene,
|
|||||||
|
|
||||||
ConvertNode *proxy = graph->create_node<ConvertNode>(to_socket_type, to_socket_type, true);
|
ConvertNode *proxy = graph->create_node<ConvertNode>(to_socket_type, to_socket_type, true);
|
||||||
|
|
||||||
input_map[b_link->from_socket().ptr.data] = proxy->inputs[0];
|
input_map[b_link.from_socket().ptr.data] = proxy->inputs[0];
|
||||||
output_map[b_link->to_socket().ptr.data] = proxy->outputs[0];
|
output_map[b_link.to_socket().ptr.data] = proxy->outputs[0];
|
||||||
|
|
||||||
graph->add(proxy);
|
graph->add(proxy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (b_node->is_a(&RNA_ShaderNodeGroup) || b_node->is_a(&RNA_NodeCustomGroup) ||
|
else if (b_node.is_a(&RNA_ShaderNodeGroup) || b_node.is_a(&RNA_NodeCustomGroup) ||
|
||||||
b_node->is_a(&RNA_ShaderNodeCustomGroup)) {
|
b_node.is_a(&RNA_ShaderNodeCustomGroup)) {
|
||||||
|
|
||||||
BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
|
BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
|
||||||
if (b_node->is_a(&RNA_ShaderNodeGroup))
|
if (b_node.is_a(&RNA_ShaderNodeGroup))
|
||||||
b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(*b_node)).node_tree());
|
b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(b_node)).node_tree());
|
||||||
else if (b_node->is_a(&RNA_NodeCustomGroup))
|
else if (b_node.is_a(&RNA_NodeCustomGroup))
|
||||||
b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(*b_node)).node_tree());
|
b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(b_node)).node_tree());
|
||||||
else
|
else
|
||||||
b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(*b_node)).node_tree());
|
b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(b_node)).node_tree());
|
||||||
|
|
||||||
ProxyMap group_proxy_input_map, group_proxy_output_map;
|
ProxyMap group_proxy_input_map, group_proxy_output_map;
|
||||||
|
|
||||||
@@ -1131,8 +1123,8 @@ static void add_nodes(Scene *scene,
|
|||||||
* Do this even if the node group has no internal tree,
|
* Do this even if the node group has no internal tree,
|
||||||
* so that links have something to connect to and assert won't fail.
|
* so that links have something to connect to and assert won't fail.
|
||||||
*/
|
*/
|
||||||
for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
|
for (BL::NodeSocket &b_input : b_node.inputs) {
|
||||||
SocketType::Type input_type = convert_socket_type(*b_input);
|
SocketType::Type input_type = convert_socket_type(b_input);
|
||||||
if (input_type == SocketType::UNDEFINED) {
|
if (input_type == SocketType::UNDEFINED) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1141,14 +1133,14 @@ static void add_nodes(Scene *scene,
|
|||||||
graph->add(proxy);
|
graph->add(proxy);
|
||||||
|
|
||||||
/* register the proxy node for internal binding */
|
/* register the proxy node for internal binding */
|
||||||
group_proxy_input_map[b_input->identifier()] = proxy;
|
group_proxy_input_map[b_input.identifier()] = proxy;
|
||||||
|
|
||||||
input_map[b_input->ptr.data] = proxy->inputs[0];
|
input_map[b_input.ptr.data] = proxy->inputs[0];
|
||||||
|
|
||||||
set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
|
set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
|
||||||
}
|
}
|
||||||
for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
|
for (BL::NodeSocket &b_output : b_node.outputs) {
|
||||||
SocketType::Type output_type = convert_socket_type(*b_output);
|
SocketType::Type output_type = convert_socket_type(b_output);
|
||||||
if (output_type == SocketType::UNDEFINED) {
|
if (output_type == SocketType::UNDEFINED) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1157,9 +1149,9 @@ static void add_nodes(Scene *scene,
|
|||||||
graph->add(proxy);
|
graph->add(proxy);
|
||||||
|
|
||||||
/* register the proxy node for internal binding */
|
/* register the proxy node for internal binding */
|
||||||
group_proxy_output_map[b_output->identifier()] = proxy;
|
group_proxy_output_map[b_output.identifier()] = proxy;
|
||||||
|
|
||||||
output_map[b_output->ptr.data] = proxy->outputs[0];
|
output_map[b_output.ptr.data] = proxy->outputs[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b_group_ntree) {
|
if (b_group_ntree) {
|
||||||
@@ -1174,30 +1166,30 @@ static void add_nodes(Scene *scene,
|
|||||||
group_proxy_output_map);
|
group_proxy_output_map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (b_node->is_a(&RNA_NodeGroupInput)) {
|
else if (b_node.is_a(&RNA_NodeGroupInput)) {
|
||||||
/* map each socket to a proxy node */
|
/* map each socket to a proxy node */
|
||||||
for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
|
for (BL::NodeSocket &b_output : b_node.outputs) {
|
||||||
ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output->identifier());
|
ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output.identifier());
|
||||||
if (proxy_it != proxy_input_map.end()) {
|
if (proxy_it != proxy_input_map.end()) {
|
||||||
ConvertNode *proxy = proxy_it->second;
|
ConvertNode *proxy = proxy_it->second;
|
||||||
|
|
||||||
output_map[b_output->ptr.data] = proxy->outputs[0];
|
output_map[b_output.ptr.data] = proxy->outputs[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (b_node->is_a(&RNA_NodeGroupOutput)) {
|
else if (b_node.is_a(&RNA_NodeGroupOutput)) {
|
||||||
BL::NodeGroupOutput b_output_node(*b_node);
|
BL::NodeGroupOutput b_output_node(b_node);
|
||||||
/* only the active group output is used */
|
/* only the active group output is used */
|
||||||
if (b_output_node.is_active_output()) {
|
if (b_output_node.is_active_output()) {
|
||||||
/* map each socket to a proxy node */
|
/* map each socket to a proxy node */
|
||||||
for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
|
for (BL::NodeSocket &b_input : b_node.inputs) {
|
||||||
ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input->identifier());
|
ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input.identifier());
|
||||||
if (proxy_it != proxy_output_map.end()) {
|
if (proxy_it != proxy_output_map.end()) {
|
||||||
ConvertNode *proxy = proxy_it->second;
|
ConvertNode *proxy = proxy_it->second;
|
||||||
|
|
||||||
input_map[b_input->ptr.data] = proxy->inputs[0];
|
input_map[b_input.ptr.data] = proxy->inputs[0];
|
||||||
|
|
||||||
set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
|
set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1205,52 +1197,49 @@ static void add_nodes(Scene *scene,
|
|||||||
else {
|
else {
|
||||||
ShaderNode *node = NULL;
|
ShaderNode *node = NULL;
|
||||||
|
|
||||||
if (b_node->ptr.data == output_node.ptr.data) {
|
if (b_node.ptr.data == output_node.ptr.data) {
|
||||||
node = graph->output();
|
node = graph->output();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BL::ShaderNode b_shader_node(*b_node);
|
BL::ShaderNode b_shader_node(b_node);
|
||||||
node = add_node(
|
node = add_node(
|
||||||
scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree, b_shader_node);
|
scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree, b_shader_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
/* map node sockets for linking */
|
/* map node sockets for linking */
|
||||||
for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
|
for (BL::NodeSocket &b_input : b_node.inputs) {
|
||||||
ShaderInput *input = node_find_input_by_name(node, *b_node, *b_input);
|
ShaderInput *input = node_find_input_by_name(node, b_node, b_input);
|
||||||
if (!input) {
|
if (!input) {
|
||||||
/* XXX should not happen, report error? */
|
/* XXX should not happen, report error? */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
input_map[b_input->ptr.data] = input;
|
input_map[b_input.ptr.data] = input;
|
||||||
|
|
||||||
set_default_value(input, *b_input, b_data, b_ntree);
|
set_default_value(input, b_input, b_data, b_ntree);
|
||||||
}
|
}
|
||||||
for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
|
for (BL::NodeSocket &b_output : b_node.outputs) {
|
||||||
ShaderOutput *output = node_find_output_by_name(node, *b_node, *b_output);
|
ShaderOutput *output = node_find_output_by_name(node, b_node, b_output);
|
||||||
if (!output) {
|
if (!output) {
|
||||||
/* XXX should not happen, report error? */
|
/* XXX should not happen, report error? */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
output_map[b_output->ptr.data] = output;
|
output_map[b_output.ptr.data] = output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* connect nodes */
|
/* connect nodes */
|
||||||
BL::NodeTree::links_iterator b_link;
|
for (BL::NodeLink &b_link : b_ntree.links) {
|
||||||
|
|
||||||
for (b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
|
|
||||||
/* Ignore invalid links to avoid unwanted cycles created in graph.
|
/* Ignore invalid links to avoid unwanted cycles created in graph.
|
||||||
* Also ignore links with unavailable sockets. */
|
* Also ignore links with unavailable sockets. */
|
||||||
if (!(b_link->is_valid() && b_link->from_socket().enabled() &&
|
if (!(b_link.is_valid() && b_link.from_socket().enabled() && b_link.to_socket().enabled())) {
|
||||||
b_link->to_socket().enabled())) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* get blender link data */
|
/* get blender link data */
|
||||||
BL::NodeSocket b_from_sock = b_link->from_socket();
|
BL::NodeSocket b_from_sock = b_link.from_socket();
|
||||||
BL::NodeSocket b_to_sock = b_link->to_socket();
|
BL::NodeSocket b_to_sock = b_link.to_socket();
|
||||||
|
|
||||||
ShaderOutput *output = 0;
|
ShaderOutput *output = 0;
|
||||||
ShaderInput *input = 0;
|
ShaderInput *input = 0;
|
||||||
@@ -1298,13 +1287,12 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
|||||||
TaskPool pool;
|
TaskPool pool;
|
||||||
set<Shader *> updated_shaders;
|
set<Shader *> updated_shaders;
|
||||||
|
|
||||||
BL::Depsgraph::ids_iterator b_id;
|
for (BL::ID &b_id : b_depsgraph.ids) {
|
||||||
for (b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
|
if (!b_id.is_a(&RNA_Material)) {
|
||||||
if (!b_id->is_a(&RNA_Material)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BL::Material b_mat(*b_id);
|
BL::Material b_mat(b_id);
|
||||||
Shader *shader;
|
Shader *shader;
|
||||||
|
|
||||||
/* test if we need to sync */
|
/* test if we need to sync */
|
||||||
@@ -1497,7 +1485,6 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
|||||||
|
|
||||||
shader->set_graph(graph);
|
shader->set_graph(graph);
|
||||||
shader->tag_update(scene);
|
shader->tag_update(scene);
|
||||||
background->tag_update(scene);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||||
@@ -1517,8 +1504,7 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
|||||||
viewport_parameters.custom_viewport_parameters());
|
viewport_parameters.custom_viewport_parameters());
|
||||||
background->set_use_ao(background->get_use_ao() && view_layer.use_background_ao);
|
background->set_use_ao(background->get_use_ao() && view_layer.use_background_ao);
|
||||||
|
|
||||||
if (background->is_modified())
|
background->tag_update(scene);
|
||||||
background->tag_update(scene);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sync Lights */
|
/* Sync Lights */
|
||||||
@@ -1527,13 +1513,12 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
|
|||||||
{
|
{
|
||||||
shader_map.set_default(scene->default_light);
|
shader_map.set_default(scene->default_light);
|
||||||
|
|
||||||
BL::Depsgraph::ids_iterator b_id;
|
for (BL::ID &b_id : b_depsgraph.ids) {
|
||||||
for (b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
|
if (!b_id.is_a(&RNA_Light)) {
|
||||||
if (!b_id->is_a(&RNA_Light)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BL::Light b_light(*b_id);
|
BL::Light b_light(b_id);
|
||||||
Shader *shader;
|
Shader *shader;
|
||||||
|
|
||||||
/* test if we need to sync */
|
/* test if we need to sync */
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include "render/mesh.h"
|
#include "render/mesh.h"
|
||||||
#include "render/nodes.h"
|
#include "render/nodes.h"
|
||||||
#include "render/object.h"
|
#include "render/object.h"
|
||||||
|
#include "render/procedural.h"
|
||||||
#include "render/scene.h"
|
#include "render/scene.h"
|
||||||
#include "render/shader.h"
|
#include "render/shader.h"
|
||||||
|
|
||||||
@@ -131,9 +132,8 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate over all IDs in this depsgraph. */
|
/* Iterate over all IDs in this depsgraph. */
|
||||||
BL::Depsgraph::updates_iterator b_update;
|
for (BL::DepsgraphUpdate &b_update : b_depsgraph.updates) {
|
||||||
for (b_depsgraph.updates.begin(b_update); b_update != b_depsgraph.updates.end(); ++b_update) {
|
BL::ID b_id(b_update.id());
|
||||||
BL::ID b_id(b_update->id());
|
|
||||||
|
|
||||||
/* Material */
|
/* Material */
|
||||||
if (b_id.is_a(&RNA_Material)) {
|
if (b_id.is_a(&RNA_Material)) {
|
||||||
@@ -151,17 +151,17 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
|||||||
const bool is_geometry = object_is_geometry(b_ob);
|
const bool is_geometry = object_is_geometry(b_ob);
|
||||||
const bool is_light = !is_geometry && object_is_light(b_ob);
|
const bool is_light = !is_geometry && object_is_light(b_ob);
|
||||||
|
|
||||||
if (b_ob.is_instancer() && b_update->is_updated_shading()) {
|
if (b_ob.is_instancer() && b_update.is_updated_shading()) {
|
||||||
/* Needed for e.g. object color updates on instancer. */
|
/* Needed for e.g. object color updates on instancer. */
|
||||||
object_map.set_recalc(b_ob);
|
object_map.set_recalc(b_ob);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_geometry || is_light) {
|
if (is_geometry || is_light) {
|
||||||
const bool updated_geometry = b_update->is_updated_geometry();
|
const bool updated_geometry = b_update.is_updated_geometry();
|
||||||
|
|
||||||
/* Geometry (mesh, hair, volume). */
|
/* Geometry (mesh, hair, volume). */
|
||||||
if (is_geometry) {
|
if (is_geometry) {
|
||||||
if (b_update->is_updated_transform() || b_update->is_updated_shading()) {
|
if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
|
||||||
object_map.set_recalc(b_ob);
|
object_map.set_recalc(b_ob);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
|||||||
}
|
}
|
||||||
/* Light */
|
/* Light */
|
||||||
else if (is_light) {
|
else if (is_light) {
|
||||||
if (b_update->is_updated_transform() || b_update->is_updated_shading()) {
|
if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
|
||||||
object_map.set_recalc(b_ob);
|
object_map.set_recalc(b_ob);
|
||||||
light_map.set_recalc(b_ob);
|
light_map.set_recalc(b_ob);
|
||||||
}
|
}
|
||||||
@@ -302,11 +302,6 @@ void BlenderSync::sync_integrator()
|
|||||||
integrator->set_sample_clamp_direct(get_float(cscene, "sample_clamp_direct"));
|
integrator->set_sample_clamp_direct(get_float(cscene, "sample_clamp_direct"));
|
||||||
integrator->set_sample_clamp_indirect(get_float(cscene, "sample_clamp_indirect"));
|
integrator->set_sample_clamp_indirect(get_float(cscene, "sample_clamp_indirect"));
|
||||||
if (!preview) {
|
if (!preview) {
|
||||||
if (integrator->get_motion_blur() != r.use_motion_blur()) {
|
|
||||||
scene->object_manager->tag_update(scene);
|
|
||||||
scene->camera->tag_modified();
|
|
||||||
}
|
|
||||||
|
|
||||||
integrator->set_motion_blur(r.use_motion_blur());
|
integrator->set_motion_blur(r.use_motion_blur());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,8 +370,8 @@ void BlenderSync::sync_integrator()
|
|||||||
integrator->set_ao_bounces(0);
|
integrator->set_ao_bounces(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (integrator->is_modified())
|
/* UPDATE_NONE as we don't want to tag the integrator as modified, just tag dependent things */
|
||||||
integrator->tag_update(scene);
|
integrator->tag_update(scene, Integrator::UPDATE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Film */
|
/* Film */
|
||||||
@@ -471,16 +466,15 @@ void BlenderSync::sync_images()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Free buffers used by images which are not needed for render. */
|
/* Free buffers used by images which are not needed for render. */
|
||||||
BL::BlendData::images_iterator b_image;
|
for (BL::Image &b_image : b_data.images) {
|
||||||
for (b_data.images.begin(b_image); b_image != b_data.images.end(); ++b_image) {
|
|
||||||
/* TODO(sergey): Consider making it an utility function to check
|
/* TODO(sergey): Consider making it an utility function to check
|
||||||
* whether image is considered builtin.
|
* whether image is considered builtin.
|
||||||
*/
|
*/
|
||||||
const bool is_builtin = b_image->packed_file() ||
|
const bool is_builtin = b_image.packed_file() ||
|
||||||
b_image->source() == BL::Image::source_GENERATED ||
|
b_image.source() == BL::Image::source_GENERATED ||
|
||||||
b_image->source() == BL::Image::source_MOVIE || b_engine.is_preview();
|
b_image.source() == BL::Image::source_MOVIE || b_engine.is_preview();
|
||||||
if (is_builtin == false) {
|
if (is_builtin == false) {
|
||||||
b_image->buffers_free();
|
b_image.buffers_free();
|
||||||
}
|
}
|
||||||
/* TODO(sergey): Free builtin images not used by any shader. */
|
/* TODO(sergey): Free builtin images not used by any shader. */
|
||||||
}
|
}
|
||||||
@@ -581,10 +575,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
|
|||||||
vector<Pass> passes;
|
vector<Pass> passes;
|
||||||
|
|
||||||
/* loop over passes */
|
/* loop over passes */
|
||||||
BL::RenderLayer::passes_iterator b_pass_iter;
|
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
||||||
|
|
||||||
for (b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
|
|
||||||
BL::RenderPass b_pass(*b_pass_iter);
|
|
||||||
PassType pass_type = get_pass_type(b_pass);
|
PassType pass_type = get_pass_type(b_pass);
|
||||||
|
|
||||||
if (pass_type == PASS_MOTION && scene->integrator->get_motion_blur())
|
if (pass_type == PASS_MOTION && scene->integrator->get_motion_blur())
|
||||||
@@ -729,7 +720,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
|
|||||||
|
|
||||||
scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold());
|
scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold());
|
||||||
scene->film->tag_passes_update(scene, passes);
|
scene->film->tag_passes_update(scene, passes);
|
||||||
scene->integrator->tag_update(scene);
|
scene->integrator->tag_update(scene, Integrator::UPDATE_ALL);
|
||||||
|
|
||||||
return passes;
|
return passes;
|
||||||
}
|
}
|
||||||
@@ -752,9 +743,8 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
|
|||||||
/* TODO(sergey): We can actually remove the whole dependency graph,
|
/* TODO(sergey): We can actually remove the whole dependency graph,
|
||||||
* but that will need some API support first.
|
* but that will need some API support first.
|
||||||
*/
|
*/
|
||||||
BL::Depsgraph::objects_iterator b_ob;
|
for (BL::Object &b_ob : b_depsgraph.objects) {
|
||||||
for (b_depsgraph.objects.begin(b_ob); b_ob != b_depsgraph.objects.end(); ++b_ob) {
|
b_ob.cache_release();
|
||||||
b_ob->cache_release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,7 +843,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
|
|||||||
preview_samples = preview_samples * preview_samples;
|
preview_samples = preview_samples * preview_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_enum(cscene, "progressive") == 0 && (params.device.type != DEVICE_OPTIX)) {
|
if (get_enum(cscene, "progressive") == 0 && params.device.has_branched_path) {
|
||||||
if (background) {
|
if (background) {
|
||||||
params.samples = aa_samples;
|
params.samples = aa_samples;
|
||||||
}
|
}
|
||||||
|
@@ -134,6 +134,7 @@ class BlenderSync {
|
|||||||
void sync_view();
|
void sync_view();
|
||||||
|
|
||||||
/* Shader */
|
/* Shader */
|
||||||
|
array<Node *> find_used_shaders(BL::Object &b_ob);
|
||||||
void sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all);
|
void sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all);
|
||||||
void sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d);
|
void sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d);
|
||||||
void sync_nodes(Shader *shader, BL::ShaderNodeTree &b_ntree);
|
void sync_nodes(Shader *shader, BL::ShaderNodeTree &b_ntree);
|
||||||
|
@@ -538,11 +538,9 @@ static inline bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_
|
|||||||
|
|
||||||
static inline BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object &b_ob)
|
static inline BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object &b_ob)
|
||||||
{
|
{
|
||||||
BL::Object::modifiers_iterator b_mod;
|
for (BL::Modifier &b_mod : b_ob.modifiers) {
|
||||||
|
if (b_mod.is_a(&RNA_FluidModifier)) {
|
||||||
for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
|
BL::FluidModifier b_mmd(b_mod);
|
||||||
if (b_mod->is_a(&RNA_FluidModifier)) {
|
|
||||||
BL::FluidModifier b_mmd(*b_mod);
|
|
||||||
|
|
||||||
if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
|
if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
|
||||||
b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_LIQUID) {
|
b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_LIQUID) {
|
||||||
@@ -556,11 +554,9 @@ static inline BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object
|
|||||||
|
|
||||||
static inline BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b_ob)
|
static inline BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b_ob)
|
||||||
{
|
{
|
||||||
BL::Object::modifiers_iterator b_mod;
|
for (BL::Modifier &b_mod : b_ob.modifiers) {
|
||||||
|
if (b_mod.is_a(&RNA_FluidModifier)) {
|
||||||
for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
|
BL::FluidModifier b_mmd(b_mod);
|
||||||
if (b_mod->is_a(&RNA_FluidModifier)) {
|
|
||||||
BL::FluidModifier b_mmd(*b_mod);
|
|
||||||
|
|
||||||
if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
|
if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
|
||||||
b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_GAS) {
|
b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_GAS) {
|
||||||
|
@@ -222,9 +222,7 @@ class BlenderVolumeLoader : public VDBImageLoader {
|
|||||||
b_volume.grids.load(b_data.ptr.data);
|
b_volume.grids.load(b_data.ptr.data);
|
||||||
|
|
||||||
#ifdef WITH_OPENVDB
|
#ifdef WITH_OPENVDB
|
||||||
BL::Volume::grids_iterator b_grid_iter;
|
for (BL::VolumeGrid &b_volume_grid : b_volume.grids) {
|
||||||
for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
|
|
||||||
BL::VolumeGrid b_volume_grid(*b_grid_iter);
|
|
||||||
if (b_volume_grid.name() == grid_name) {
|
if (b_volume_grid.name() == grid_name) {
|
||||||
const bool unload = !b_volume_grid.is_loaded();
|
const bool unload = !b_volume_grid.is_loaded();
|
||||||
|
|
||||||
@@ -260,9 +258,7 @@ static void sync_volume_object(BL::BlendData &b_data,
|
|||||||
volume->set_object_space((b_render.space() == BL::VolumeRender::space_OBJECT));
|
volume->set_object_space((b_render.space() == BL::VolumeRender::space_OBJECT));
|
||||||
|
|
||||||
/* Find grid with matching name. */
|
/* Find grid with matching name. */
|
||||||
BL::Volume::grids_iterator b_grid_iter;
|
for (BL::VolumeGrid &b_grid : b_volume.grids) {
|
||||||
for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
|
|
||||||
BL::VolumeGrid b_grid = *b_grid_iter;
|
|
||||||
ustring name = ustring(b_grid.name());
|
ustring name = ustring(b_grid.name());
|
||||||
AttributeStandard std = ATTR_STD_NONE;
|
AttributeStandard std = ATTR_STD_NONE;
|
||||||
|
|
||||||
|
@@ -742,6 +742,7 @@ void CUDADevice::move_textures_to_host(size_t size, bool for_texture)
|
|||||||
size_t max_size = 0;
|
size_t max_size = 0;
|
||||||
bool max_is_image = false;
|
bool max_is_image = false;
|
||||||
|
|
||||||
|
thread_scoped_lock lock(cuda_mem_map_mutex);
|
||||||
foreach (CUDAMemMap::value_type &pair, cuda_mem_map) {
|
foreach (CUDAMemMap::value_type &pair, cuda_mem_map) {
|
||||||
device_memory &mem = *pair.first;
|
device_memory &mem = *pair.first;
|
||||||
CUDAMem *cmem = &pair.second;
|
CUDAMem *cmem = &pair.second;
|
||||||
@@ -773,6 +774,7 @@ void CUDADevice::move_textures_to_host(size_t size, bool for_texture)
|
|||||||
max_mem = &mem;
|
max_mem = &mem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
/* Move to host memory. This part is mutex protected since
|
/* Move to host memory. This part is mutex protected since
|
||||||
* multiple CUDA devices could be moving the memory. The
|
* multiple CUDA devices could be moving the memory. The
|
||||||
@@ -894,6 +896,7 @@ CUDADevice::CUDAMem *CUDADevice::generic_alloc(device_memory &mem, size_t pitch_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Insert into map of allocations. */
|
/* Insert into map of allocations. */
|
||||||
|
thread_scoped_lock lock(cuda_mem_map_mutex);
|
||||||
CUDAMem *cmem = &cuda_mem_map[&mem];
|
CUDAMem *cmem = &cuda_mem_map[&mem];
|
||||||
if (shared_pointer != 0) {
|
if (shared_pointer != 0) {
|
||||||
/* Replace host pointer with our host allocation. Only works if
|
/* Replace host pointer with our host allocation. Only works if
|
||||||
@@ -935,6 +938,7 @@ void CUDADevice::generic_copy_to(device_memory &mem)
|
|||||||
/* If use_mapped_host of mem is false, the current device only uses device memory allocated by
|
/* If use_mapped_host of mem is false, the current device only uses device memory allocated by
|
||||||
* cuMemAlloc regardless of mem.host_pointer and mem.shared_pointer, and should copy data from
|
* cuMemAlloc regardless of mem.host_pointer and mem.shared_pointer, and should copy data from
|
||||||
* mem.host_pointer. */
|
* mem.host_pointer. */
|
||||||
|
thread_scoped_lock lock(cuda_mem_map_mutex);
|
||||||
if (!cuda_mem_map[&mem].use_mapped_host || mem.host_pointer != mem.shared_pointer) {
|
if (!cuda_mem_map[&mem].use_mapped_host || mem.host_pointer != mem.shared_pointer) {
|
||||||
const CUDAContextScope scope(this);
|
const CUDAContextScope scope(this);
|
||||||
cuda_assert(
|
cuda_assert(
|
||||||
@@ -946,6 +950,7 @@ void CUDADevice::generic_free(device_memory &mem)
|
|||||||
{
|
{
|
||||||
if (mem.device_pointer) {
|
if (mem.device_pointer) {
|
||||||
CUDAContextScope scope(this);
|
CUDAContextScope scope(this);
|
||||||
|
thread_scoped_lock lock(cuda_mem_map_mutex);
|
||||||
const CUDAMem &cmem = cuda_mem_map[&mem];
|
const CUDAMem &cmem = cuda_mem_map[&mem];
|
||||||
|
|
||||||
/* If cmem.use_mapped_host is true, reference counting is used
|
/* If cmem.use_mapped_host is true, reference counting is used
|
||||||
@@ -990,7 +995,6 @@ void CUDADevice::mem_alloc(device_memory &mem)
|
|||||||
assert(!"mem_alloc not supported for global memory.");
|
assert(!"mem_alloc not supported for global memory.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
thread_scoped_lock lock(cuda_mem_map_mutex);
|
|
||||||
generic_alloc(mem);
|
generic_alloc(mem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1009,7 +1013,6 @@ void CUDADevice::mem_copy_to(device_memory &mem)
|
|||||||
tex_alloc((device_texture &)mem);
|
tex_alloc((device_texture &)mem);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
thread_scoped_lock lock(cuda_mem_map_mutex);
|
|
||||||
if (!mem.device_pointer) {
|
if (!mem.device_pointer) {
|
||||||
generic_alloc(mem);
|
generic_alloc(mem);
|
||||||
}
|
}
|
||||||
@@ -1073,7 +1076,6 @@ void CUDADevice::mem_free(device_memory &mem)
|
|||||||
tex_free((device_texture &)mem);
|
tex_free((device_texture &)mem);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
thread_scoped_lock lock(cuda_mem_map_mutex);
|
|
||||||
generic_free(mem);
|
generic_free(mem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1097,7 +1099,6 @@ void CUDADevice::const_copy_to(const char *name, void *host, size_t size)
|
|||||||
void CUDADevice::global_alloc(device_memory &mem)
|
void CUDADevice::global_alloc(device_memory &mem)
|
||||||
{
|
{
|
||||||
if (mem.is_resident(this)) {
|
if (mem.is_resident(this)) {
|
||||||
thread_scoped_lock lock(cuda_mem_map_mutex);
|
|
||||||
generic_alloc(mem);
|
generic_alloc(mem);
|
||||||
generic_copy_to(mem);
|
generic_copy_to(mem);
|
||||||
}
|
}
|
||||||
@@ -1108,7 +1109,6 @@ void CUDADevice::global_alloc(device_memory &mem)
|
|||||||
void CUDADevice::global_free(device_memory &mem)
|
void CUDADevice::global_free(device_memory &mem)
|
||||||
{
|
{
|
||||||
if (mem.is_resident(this) && mem.device_pointer) {
|
if (mem.is_resident(this) && mem.device_pointer) {
|
||||||
thread_scoped_lock lock(cuda_mem_map_mutex);
|
|
||||||
generic_free(mem);
|
generic_free(mem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1177,9 +1177,8 @@ void CUDADevice::tex_alloc(device_texture &mem)
|
|||||||
size_t src_pitch = mem.data_width * dsize * mem.data_elements;
|
size_t src_pitch = mem.data_width * dsize * mem.data_elements;
|
||||||
size_t dst_pitch = src_pitch;
|
size_t dst_pitch = src_pitch;
|
||||||
|
|
||||||
thread_scoped_lock lock(cuda_mem_map_mutex);
|
|
||||||
|
|
||||||
if (!mem.is_resident(this)) {
|
if (!mem.is_resident(this)) {
|
||||||
|
thread_scoped_lock lock(cuda_mem_map_mutex);
|
||||||
cmem = &cuda_mem_map[&mem];
|
cmem = &cuda_mem_map[&mem];
|
||||||
cmem->texobject = 0;
|
cmem->texobject = 0;
|
||||||
|
|
||||||
@@ -1229,6 +1228,7 @@ void CUDADevice::tex_alloc(device_texture &mem)
|
|||||||
mem.device_size = size;
|
mem.device_size = size;
|
||||||
stats.mem_alloc(size);
|
stats.mem_alloc(size);
|
||||||
|
|
||||||
|
thread_scoped_lock lock(cuda_mem_map_mutex);
|
||||||
cmem = &cuda_mem_map[&mem];
|
cmem = &cuda_mem_map[&mem];
|
||||||
cmem->texobject = 0;
|
cmem->texobject = 0;
|
||||||
cmem->array = array_3d;
|
cmem->array = array_3d;
|
||||||
@@ -1266,9 +1266,6 @@ void CUDADevice::tex_alloc(device_texture &mem)
|
|||||||
cuda_assert(cuMemcpyHtoD(mem.device_pointer, mem.host_pointer, size));
|
cuda_assert(cuMemcpyHtoD(mem.device_pointer, mem.host_pointer, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock mutex before resizing texture info, since that may attempt to lock it again. */
|
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
/* Resize once */
|
/* Resize once */
|
||||||
const uint slot = mem.slot;
|
const uint slot = mem.slot;
|
||||||
if (slot >= texture_info.size()) {
|
if (slot >= texture_info.size()) {
|
||||||
@@ -1317,9 +1314,7 @@ void CUDADevice::tex_alloc(device_texture &mem)
|
|||||||
texDesc.filterMode = filter_mode;
|
texDesc.filterMode = filter_mode;
|
||||||
texDesc.flags = CU_TRSF_NORMALIZED_COORDINATES;
|
texDesc.flags = CU_TRSF_NORMALIZED_COORDINATES;
|
||||||
|
|
||||||
/* Lock again and refresh the data pointer (in case another thread modified the map in the
|
thread_scoped_lock lock(cuda_mem_map_mutex);
|
||||||
* meantime). */
|
|
||||||
lock.lock();
|
|
||||||
cmem = &cuda_mem_map[&mem];
|
cmem = &cuda_mem_map[&mem];
|
||||||
|
|
||||||
cuda_assert(cuTexObjectCreate(&cmem->texobject, &resDesc, &texDesc, NULL));
|
cuda_assert(cuTexObjectCreate(&cmem->texobject, &resDesc, &texDesc, NULL));
|
||||||
@@ -1357,6 +1352,7 @@ void CUDADevice::tex_free(device_texture &mem)
|
|||||||
cuda_mem_map.erase(cuda_mem_map.find(&mem));
|
cuda_mem_map.erase(cuda_mem_map.find(&mem));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
lock.unlock();
|
||||||
generic_free(mem);
|
generic_free(mem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -620,6 +620,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
|
|||||||
|
|
||||||
info.has_half_images = true;
|
info.has_half_images = true;
|
||||||
info.has_volume_decoupled = true;
|
info.has_volume_decoupled = true;
|
||||||
|
info.has_branched_path = true;
|
||||||
info.has_adaptive_stop_per_sample = true;
|
info.has_adaptive_stop_per_sample = true;
|
||||||
info.has_osl = true;
|
info.has_osl = true;
|
||||||
info.has_profiling = true;
|
info.has_profiling = true;
|
||||||
@@ -665,6 +666,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
|
|||||||
/* Accumulate device info. */
|
/* Accumulate device info. */
|
||||||
info.has_half_images &= device.has_half_images;
|
info.has_half_images &= device.has_half_images;
|
||||||
info.has_volume_decoupled &= device.has_volume_decoupled;
|
info.has_volume_decoupled &= device.has_volume_decoupled;
|
||||||
|
info.has_branched_path &= device.has_branched_path;
|
||||||
info.has_adaptive_stop_per_sample &= device.has_adaptive_stop_per_sample;
|
info.has_adaptive_stop_per_sample &= device.has_adaptive_stop_per_sample;
|
||||||
info.has_osl &= device.has_osl;
|
info.has_osl &= device.has_osl;
|
||||||
info.has_profiling &= device.has_profiling;
|
info.has_profiling &= device.has_profiling;
|
||||||
|
@@ -79,6 +79,7 @@ class DeviceInfo {
|
|||||||
bool display_device; /* GPU is used as a display device. */
|
bool display_device; /* GPU is used as a display device. */
|
||||||
bool has_half_images; /* Support half-float textures. */
|
bool has_half_images; /* Support half-float textures. */
|
||||||
bool has_volume_decoupled; /* Decoupled volume shading. */
|
bool has_volume_decoupled; /* Decoupled volume shading. */
|
||||||
|
bool has_branched_path; /* Supports branched path tracing. */
|
||||||
bool has_adaptive_stop_per_sample; /* Per-sample adaptive sampling stopping. */
|
bool has_adaptive_stop_per_sample; /* Per-sample adaptive sampling stopping. */
|
||||||
bool has_osl; /* Support Open Shading Language. */
|
bool has_osl; /* Support Open Shading Language. */
|
||||||
bool use_split_kernel; /* Use split or mega kernel. */
|
bool use_split_kernel; /* Use split or mega kernel. */
|
||||||
@@ -99,6 +100,7 @@ class DeviceInfo {
|
|||||||
display_device = false;
|
display_device = false;
|
||||||
has_half_images = false;
|
has_half_images = false;
|
||||||
has_volume_decoupled = false;
|
has_volume_decoupled = false;
|
||||||
|
has_branched_path = true;
|
||||||
has_adaptive_stop_per_sample = false;
|
has_adaptive_stop_per_sample = false;
|
||||||
has_osl = false;
|
has_osl = false;
|
||||||
use_split_kernel = false;
|
use_split_kernel = false;
|
||||||
|
@@ -951,7 +951,7 @@ class CPUDevice : public Device {
|
|||||||
SIMD_SET_FLUSH_TO_ZERO;
|
SIMD_SET_FLUSH_TO_ZERO;
|
||||||
|
|
||||||
for (int sample = start_sample; sample < end_sample; sample++) {
|
for (int sample = start_sample; sample < end_sample; sample++) {
|
||||||
if (task.get_cancel() || task_pool.canceled()) {
|
if (task.get_cancel() || TaskPool::canceled()) {
|
||||||
if (task.need_finish_queue == false)
|
if (task.need_finish_queue == false)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1249,7 +1249,7 @@ class CPUDevice : public Device {
|
|||||||
|
|
||||||
void thread_render(DeviceTask &task)
|
void thread_render(DeviceTask &task)
|
||||||
{
|
{
|
||||||
if (task_pool.canceled()) {
|
if (TaskPool::canceled()) {
|
||||||
if (task.need_finish_queue == false)
|
if (task.need_finish_queue == false)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1319,7 +1319,7 @@ class CPUDevice : public Device {
|
|||||||
|
|
||||||
task.release_tile(tile);
|
task.release_tile(tile);
|
||||||
|
|
||||||
if (task_pool.canceled()) {
|
if (TaskPool::canceled()) {
|
||||||
if (task.need_finish_queue == false)
|
if (task.need_finish_queue == false)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1416,7 +1416,7 @@ class CPUDevice : public Device {
|
|||||||
task.offset,
|
task.offset,
|
||||||
sample);
|
sample);
|
||||||
|
|
||||||
if (task.get_cancel() || task_pool.canceled())
|
if (task.get_cancel() || TaskPool::canceled())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
task.update_progress(NULL);
|
task.update_progress(NULL);
|
||||||
|
@@ -259,6 +259,8 @@ class device_memory {
|
|||||||
device_ptr original_device_ptr;
|
device_ptr original_device_ptr;
|
||||||
size_t original_device_size;
|
size_t original_device_size;
|
||||||
Device *original_device;
|
Device *original_device;
|
||||||
|
bool need_realloc_;
|
||||||
|
bool modified;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Device Only Memory
|
/* Device Only Memory
|
||||||
@@ -329,6 +331,8 @@ template<typename T> class device_vector : public device_memory {
|
|||||||
{
|
{
|
||||||
data_type = device_type_traits<T>::data_type;
|
data_type = device_type_traits<T>::data_type;
|
||||||
data_elements = device_type_traits<T>::num_elements;
|
data_elements = device_type_traits<T>::num_elements;
|
||||||
|
modified = true;
|
||||||
|
need_realloc_ = true;
|
||||||
|
|
||||||
assert(data_elements > 0);
|
assert(data_elements > 0);
|
||||||
}
|
}
|
||||||
@@ -347,6 +351,7 @@ template<typename T> class device_vector : public device_memory {
|
|||||||
device_free();
|
device_free();
|
||||||
host_free();
|
host_free();
|
||||||
host_pointer = host_alloc(sizeof(T) * new_size);
|
host_pointer = host_alloc(sizeof(T) * new_size);
|
||||||
|
modified = true;
|
||||||
assert(device_pointer == 0);
|
assert(device_pointer == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,6 +405,19 @@ template<typename T> class device_vector : public device_memory {
|
|||||||
assert(device_pointer == 0);
|
assert(device_pointer == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void give_data(array<T> &to)
|
||||||
|
{
|
||||||
|
device_free();
|
||||||
|
|
||||||
|
to.set_data((T *)host_pointer, data_size);
|
||||||
|
data_size = 0;
|
||||||
|
data_width = 0;
|
||||||
|
data_height = 0;
|
||||||
|
data_depth = 0;
|
||||||
|
host_pointer = 0;
|
||||||
|
assert(device_pointer == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Free device and host memory. */
|
/* Free device and host memory. */
|
||||||
void free()
|
void free()
|
||||||
{
|
{
|
||||||
@@ -411,10 +429,40 @@ template<typename T> class device_vector : public device_memory {
|
|||||||
data_height = 0;
|
data_height = 0;
|
||||||
data_depth = 0;
|
data_depth = 0;
|
||||||
host_pointer = 0;
|
host_pointer = 0;
|
||||||
|
modified = true;
|
||||||
|
need_realloc_ = true;
|
||||||
assert(device_pointer == 0);
|
assert(device_pointer == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size()
|
void free_if_need_realloc(bool force_free)
|
||||||
|
{
|
||||||
|
if (need_realloc_ || force_free) {
|
||||||
|
free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_modified() const
|
||||||
|
{
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool need_realloc()
|
||||||
|
{
|
||||||
|
return need_realloc_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tag_modified()
|
||||||
|
{
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tag_realloc()
|
||||||
|
{
|
||||||
|
need_realloc_ = true;
|
||||||
|
tag_modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const
|
||||||
{
|
{
|
||||||
return data_size;
|
return data_size;
|
||||||
}
|
}
|
||||||
@@ -432,7 +480,24 @@ template<typename T> class device_vector : public device_memory {
|
|||||||
|
|
||||||
void copy_to_device()
|
void copy_to_device()
|
||||||
{
|
{
|
||||||
device_copy_to();
|
if (data_size != 0) {
|
||||||
|
device_copy_to();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_to_device_if_modified()
|
||||||
|
{
|
||||||
|
if (!modified) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_to_device();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_modified()
|
||||||
|
{
|
||||||
|
modified = false;
|
||||||
|
need_realloc_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_from_device()
|
void copy_from_device()
|
||||||
|
@@ -151,8 +151,6 @@ string device_opencl_capabilities()
|
|||||||
platform_ids.resize(num_platforms);
|
platform_ids.resize(num_platforms);
|
||||||
opencl_assert(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
|
opencl_assert(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
|
||||||
|
|
||||||
typedef char cl_string[1024];
|
|
||||||
|
|
||||||
# define APPEND_INFO(func, id, name, what, type) \
|
# define APPEND_INFO(func, id, name, what, type) \
|
||||||
do { \
|
do { \
|
||||||
type data; \
|
type data; \
|
||||||
@@ -160,22 +158,33 @@ string device_opencl_capabilities()
|
|||||||
opencl_assert(func(id, what, sizeof(data), &data, NULL)); \
|
opencl_assert(func(id, what, sizeof(data), &data, NULL)); \
|
||||||
result += string_printf("%s: %s\n", name, to_string(data).c_str()); \
|
result += string_printf("%s: %s\n", name, to_string(data).c_str()); \
|
||||||
} while (false)
|
} while (false)
|
||||||
# define APPEND_STRING_EXTENSION_INFO(func, id, name, what) \
|
# define APPEND_STRING_INFO_IMPL(func, id, name, what, is_optional) \
|
||||||
do { \
|
do { \
|
||||||
char data[1024] = "\0"; \
|
string value; \
|
||||||
size_t length = 0; \
|
size_t length = 0; \
|
||||||
if (func(id, what, sizeof(data), &data, &length) == CL_SUCCESS) { \
|
if (func(id, what, 0, NULL, &length) == CL_SUCCESS) { \
|
||||||
if (length != 0 && data[0] != '\0') { \
|
vector<char> buffer(length + 1); \
|
||||||
result += string_printf("%s: %s\n", name, data); \
|
if (func(id, what, buffer.size(), buffer.data(), NULL) == CL_SUCCESS) { \
|
||||||
|
value = string(buffer.data()); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
if (is_optional && !(length != 0 && value[0] != '\0')) { \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
result += string_printf("%s: %s\n", name, value.c_str()); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
# define APPEND_PLATFORM_STRING_INFO(id, name, what) \
|
||||||
|
APPEND_STRING_INFO_IMPL(clGetPlatformInfo, id, "\tPlatform " name, what, false)
|
||||||
|
# define APPEND_STRING_EXTENSION_INFO(func, id, name, what) \
|
||||||
|
APPEND_STRING_INFO_IMPL(clGetPlatformInfo, id, "\tPlatform " name, what, true)
|
||||||
# define APPEND_PLATFORM_INFO(id, name, what, type) \
|
# define APPEND_PLATFORM_INFO(id, name, what, type) \
|
||||||
APPEND_INFO(clGetPlatformInfo, id, "\tPlatform " name, what, type)
|
APPEND_INFO(clGetPlatformInfo, id, "\tPlatform " name, what, type)
|
||||||
# define APPEND_DEVICE_INFO(id, name, what, type) \
|
# define APPEND_DEVICE_INFO(id, name, what, type) \
|
||||||
APPEND_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what, type)
|
APPEND_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what, type)
|
||||||
|
# define APPEND_DEVICE_STRING_INFO(id, name, what) \
|
||||||
|
APPEND_STRING_INFO_IMPL(clGetDeviceInfo, id, "\t\t\tDevice " name, what, false)
|
||||||
# define APPEND_DEVICE_STRING_EXTENSION_INFO(id, name, what) \
|
# define APPEND_DEVICE_STRING_EXTENSION_INFO(id, name, what) \
|
||||||
APPEND_STRING_EXTENSION_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what)
|
APPEND_STRING_INFO_IMPL(clGetDeviceInfo, id, "\t\t\tDevice " name, what, true)
|
||||||
|
|
||||||
vector<cl_device_id> device_ids;
|
vector<cl_device_id> device_ids;
|
||||||
for (cl_uint platform = 0; platform < num_platforms; ++platform) {
|
for (cl_uint platform = 0; platform < num_platforms; ++platform) {
|
||||||
@@ -183,11 +192,11 @@ string device_opencl_capabilities()
|
|||||||
|
|
||||||
result += string_printf("Platform #%u\n", platform);
|
result += string_printf("Platform #%u\n", platform);
|
||||||
|
|
||||||
APPEND_PLATFORM_INFO(platform_id, "Name", CL_PLATFORM_NAME, cl_string);
|
APPEND_PLATFORM_STRING_INFO(platform_id, "Name", CL_PLATFORM_NAME);
|
||||||
APPEND_PLATFORM_INFO(platform_id, "Vendor", CL_PLATFORM_VENDOR, cl_string);
|
APPEND_PLATFORM_STRING_INFO(platform_id, "Vendor", CL_PLATFORM_VENDOR);
|
||||||
APPEND_PLATFORM_INFO(platform_id, "Version", CL_PLATFORM_VERSION, cl_string);
|
APPEND_PLATFORM_STRING_INFO(platform_id, "Version", CL_PLATFORM_VERSION);
|
||||||
APPEND_PLATFORM_INFO(platform_id, "Profile", CL_PLATFORM_PROFILE, cl_string);
|
APPEND_PLATFORM_STRING_INFO(platform_id, "Profile", CL_PLATFORM_PROFILE);
|
||||||
APPEND_PLATFORM_INFO(platform_id, "Extensions", CL_PLATFORM_EXTENSIONS, cl_string);
|
APPEND_PLATFORM_STRING_INFO(platform_id, "Extensions", CL_PLATFORM_EXTENSIONS);
|
||||||
|
|
||||||
cl_uint num_devices = 0;
|
cl_uint num_devices = 0;
|
||||||
opencl_assert(
|
opencl_assert(
|
||||||
@@ -202,13 +211,13 @@ string device_opencl_capabilities()
|
|||||||
|
|
||||||
result += string_printf("\t\tDevice: #%u\n", device);
|
result += string_printf("\t\tDevice: #%u\n", device);
|
||||||
|
|
||||||
APPEND_DEVICE_INFO(device_id, "Name", CL_DEVICE_NAME, cl_string);
|
APPEND_DEVICE_STRING_INFO(device_id, "Name", CL_DEVICE_NAME);
|
||||||
APPEND_DEVICE_STRING_EXTENSION_INFO(device_id, "Board Name", CL_DEVICE_BOARD_NAME_AMD);
|
APPEND_DEVICE_STRING_EXTENSION_INFO(device_id, "Board Name", CL_DEVICE_BOARD_NAME_AMD);
|
||||||
APPEND_DEVICE_INFO(device_id, "Vendor", CL_DEVICE_VENDOR, cl_string);
|
APPEND_DEVICE_STRING_INFO(device_id, "Vendor", CL_DEVICE_VENDOR);
|
||||||
APPEND_DEVICE_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION, cl_string);
|
APPEND_DEVICE_STRING_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION);
|
||||||
APPEND_DEVICE_INFO(device_id, "Profile", CL_DEVICE_PROFILE, cl_string);
|
APPEND_DEVICE_STRING_INFO(device_id, "Profile", CL_DEVICE_PROFILE);
|
||||||
APPEND_DEVICE_INFO(device_id, "Version", CL_DEVICE_VERSION, cl_string);
|
APPEND_DEVICE_STRING_INFO(device_id, "Version", CL_DEVICE_VERSION);
|
||||||
APPEND_DEVICE_INFO(device_id, "Extensions", CL_DEVICE_EXTENSIONS, cl_string);
|
APPEND_DEVICE_STRING_INFO(device_id, "Extensions", CL_DEVICE_EXTENSIONS);
|
||||||
APPEND_DEVICE_INFO(
|
APPEND_DEVICE_INFO(
|
||||||
device_id, "Max clock frequency (MHz)", CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint);
|
device_id, "Max clock frequency (MHz)", CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint);
|
||||||
APPEND_DEVICE_INFO(device_id, "Max compute units", CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint);
|
APPEND_DEVICE_INFO(device_id, "Max compute units", CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint);
|
||||||
@@ -216,9 +225,14 @@ string device_opencl_capabilities()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# undef APPEND_STRING_INFO
|
# undef APPEND_INFO
|
||||||
|
# undef APPEND_STRING_INFO_IMPL
|
||||||
# undef APPEND_PLATFORM_STRING_INFO
|
# undef APPEND_PLATFORM_STRING_INFO
|
||||||
|
# undef APPEND_STRING_EXTENSION_INFO
|
||||||
|
# undef APPEND_PLATFORM_INFO
|
||||||
|
# undef APPEND_DEVICE_INFO
|
||||||
# undef APPEND_DEVICE_STRING_INFO
|
# undef APPEND_DEVICE_STRING_INFO
|
||||||
|
# undef APPEND_DEVICE_STRING_EXTENSION_INFO
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -1857,6 +1857,7 @@ void device_optix_info(const vector<DeviceInfo> &cuda_devices, vector<DeviceInfo
|
|||||||
info.type = DEVICE_OPTIX;
|
info.type = DEVICE_OPTIX;
|
||||||
info.id += "_OptiX";
|
info.id += "_OptiX";
|
||||||
info.denoisers |= DENOISER_OPTIX;
|
info.denoisers |= DENOISER_OPTIX;
|
||||||
|
info.has_branched_path = false;
|
||||||
|
|
||||||
devices.push_back(info);
|
devices.push_back(info);
|
||||||
}
|
}
|
||||||
|
@@ -100,7 +100,9 @@ class DenoiseParams {
|
|||||||
neighbor_frames = 2;
|
neighbor_frames = 2;
|
||||||
clamp_input = true;
|
clamp_input = true;
|
||||||
|
|
||||||
input_passes = DENOISER_INPUT_RGB_ALBEDO_NORMAL;
|
/* Default to color + albedo only, since normal input does not always have the desired effect
|
||||||
|
* when denoising with OptiX. */
|
||||||
|
input_passes = DENOISER_INPUT_RGB_ALBEDO;
|
||||||
|
|
||||||
start_sample = 0;
|
start_sample = 0;
|
||||||
}
|
}
|
||||||
|
@@ -454,7 +454,7 @@ ccl_device_inline bool cylinder_culling_test(const float2 p1, const float2 p2, c
|
|||||||
/* Performs culling against a cylinder. */
|
/* Performs culling against a cylinder. */
|
||||||
const float2 dp = p2 - p1;
|
const float2 dp = p2 - p1;
|
||||||
const float num = dp.x * p1.y - dp.y * p1.x;
|
const float num = dp.x * p1.y - dp.y * p1.x;
|
||||||
const float den2 = dot(p2 - p1, p2 - p1);
|
const float den2 = dot(dp, dp);
|
||||||
return num * num <= r * r * den2;
|
return num * num <= r * r * den2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,46 +571,46 @@ ccl_device_inline bool ribbon_intersect(const float3 ray_org,
|
|||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
const float u = i * step_size;
|
const float u = i * step_size;
|
||||||
const float4 p1 = catmull_rom_basis_eval(curve, u + step_size);
|
const float4 p1 = catmull_rom_basis_eval(curve, u + step_size);
|
||||||
bool valid = cylinder_culling_test(
|
const bool valid = cylinder_culling_test(
|
||||||
make_float2(p0.x, p0.y), make_float2(p1.x, p1.y), max(p0.w, p1.w));
|
make_float2(p0.x, p0.y), make_float2(p1.x, p1.y), max(p0.w, p1.w));
|
||||||
if (!valid) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Evaluate next point. */
|
/* Evaluate next point. */
|
||||||
float3 dp1dt = float4_to_float3(catmull_rom_basis_derivative(curve, u + step_size));
|
float3 dp1dt = float4_to_float3(catmull_rom_basis_derivative(curve, u + step_size));
|
||||||
dp1dt = (max3(fabs(dp1dt)) < eps) ? float4_to_float3(p1 - p0) : dp1dt;
|
dp1dt = (max3(fabs(dp1dt)) < eps) ? float4_to_float3(p1 - p0) : dp1dt;
|
||||||
const float3 wn1 = normalize(make_float3(dp1dt.y, -dp1dt.x, 0.0f)) * p1.w;
|
const float3 wn1 = normalize(make_float3(dp1dt.y, -dp1dt.x, 0.0f)) * p1.w;
|
||||||
|
|
||||||
/* Construct quad coordinates. */
|
if (valid) {
|
||||||
const float3 lp0 = float4_to_float3(p0) + wn0;
|
/* Construct quad coordinates. */
|
||||||
const float3 lp1 = float4_to_float3(p1) + wn1;
|
const float3 lp0 = float4_to_float3(p0) + wn0;
|
||||||
const float3 up0 = float4_to_float3(p0) - wn0;
|
const float3 lp1 = float4_to_float3(p1) + wn1;
|
||||||
const float3 up1 = float4_to_float3(p1) - wn1;
|
const float3 up0 = float4_to_float3(p0) - wn0;
|
||||||
|
const float3 up1 = float4_to_float3(p1) - wn1;
|
||||||
|
|
||||||
/* Intersect quad. */
|
/* Intersect quad. */
|
||||||
float vu, vv, vt;
|
float vu, vv, vt;
|
||||||
bool valid0 = ribbon_intersect_quad(isect->t, lp0, lp1, up1, up0, &vu, &vv, &vt);
|
bool valid0 = ribbon_intersect_quad(isect->t, lp0, lp1, up1, up0, &vu, &vv, &vt);
|
||||||
|
|
||||||
if (valid0) {
|
|
||||||
/* ignore self intersections */
|
|
||||||
const float avoidance_factor = 2.0f;
|
|
||||||
if (avoidance_factor != 0.0f) {
|
|
||||||
float r = mix(p0.w, p1.w, vu);
|
|
||||||
valid0 = vt > avoidance_factor * r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid0) {
|
if (valid0) {
|
||||||
vv = 2.0f * vv - 1.0f;
|
/* ignore self intersections */
|
||||||
|
const float avoidance_factor = 2.0f;
|
||||||
|
if (avoidance_factor != 0.0f) {
|
||||||
|
float r = mix(p0.w, p1.w, vu);
|
||||||
|
valid0 = vt > avoidance_factor * r;
|
||||||
|
}
|
||||||
|
|
||||||
/* Record intersection. */
|
if (valid0) {
|
||||||
isect->t = vt;
|
vv = 2.0f * vv - 1.0f;
|
||||||
isect->u = u + vu * step_size;
|
|
||||||
isect->v = vv;
|
/* Record intersection. */
|
||||||
return true;
|
isect->t = vt;
|
||||||
|
isect->u = u + vu * step_size;
|
||||||
|
isect->v = vv;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Store point for next step. */
|
||||||
p0 = p1;
|
p0 = p1;
|
||||||
wn0 = wn1;
|
wn0 = wn1;
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef WITH_NANOVDB
|
#ifdef WITH_NANOVDB
|
||||||
|
/* Data type to replace `double` used in the NanoVDB headers. Cycles don't need doubles, and is
|
||||||
|
* safer and more portable to never use double datatype on GPU.
|
||||||
|
* Use a special structure, so that the following is true:
|
||||||
|
* - No unnoticed implicit cast or mathematical operations used on scalar 64bit type
|
||||||
|
* (which rules out trick like using `uint64_t` as a drop-in replacement for double).
|
||||||
|
* - Padding rules are matching exactly `double`
|
||||||
|
* (which rules out array of `uint8_t`). */
|
||||||
|
typedef struct ccl_vdb_double_t {
|
||||||
|
uint64_t i;
|
||||||
|
} ccl_vdb_double_t;
|
||||||
|
|
||||||
|
# define double ccl_vdb_double_t
|
||||||
# include "nanovdb/CNanoVDB.h"
|
# include "nanovdb/CNanoVDB.h"
|
||||||
|
# undef double
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For OpenCL we do manual lookup and interpolation. */
|
/* For OpenCL we do manual lookup and interpolation. */
|
||||||
|
@@ -43,7 +43,7 @@ class ColorSpaceProcessor;
|
|||||||
*
|
*
|
||||||
* Data needed by OSL render services, that is global to a rendering session.
|
* Data needed by OSL render services, that is global to a rendering session.
|
||||||
* This includes all OSL shaders, name to attribute mapping and texture handles.
|
* This includes all OSL shaders, name to attribute mapping and texture handles.
|
||||||
* */
|
*/
|
||||||
|
|
||||||
struct OSLGlobals {
|
struct OSLGlobals {
|
||||||
OSLGlobals()
|
OSLGlobals()
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <OSL/oslclosure.h>
|
#include <OSL/oslclosure.h>
|
||||||
#include <OSL/oslexec.h>
|
#include <OSL/oslexec.h>
|
||||||
|
#include <OSL/rendererservices.h>
|
||||||
|
|
||||||
#ifdef WITH_PTEX
|
#ifdef WITH_PTEX
|
||||||
class PtexCache;
|
class PtexCache;
|
||||||
|
@@ -23,6 +23,7 @@ set(INC_SYS
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(SRC
|
set(SRC
|
||||||
|
alembic.cpp
|
||||||
attribute.cpp
|
attribute.cpp
|
||||||
background.cpp
|
background.cpp
|
||||||
bake.cpp
|
bake.cpp
|
||||||
@@ -48,6 +49,7 @@ set(SRC
|
|||||||
mesh_displace.cpp
|
mesh_displace.cpp
|
||||||
mesh_subdivision.cpp
|
mesh_subdivision.cpp
|
||||||
nodes.cpp
|
nodes.cpp
|
||||||
|
procedural.cpp
|
||||||
object.cpp
|
object.cpp
|
||||||
osl.cpp
|
osl.cpp
|
||||||
particles.cpp
|
particles.cpp
|
||||||
@@ -64,6 +66,7 @@ set(SRC
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(SRC_HEADERS
|
set(SRC_HEADERS
|
||||||
|
alembic.h
|
||||||
attribute.h
|
attribute.h
|
||||||
bake.h
|
bake.h
|
||||||
background.h
|
background.h
|
||||||
@@ -90,6 +93,7 @@ set(SRC_HEADERS
|
|||||||
object.h
|
object.h
|
||||||
osl.h
|
osl.h
|
||||||
particles.h
|
particles.h
|
||||||
|
procedural.h
|
||||||
curves.h
|
curves.h
|
||||||
scene.h
|
scene.h
|
||||||
session.h
|
session.h
|
||||||
@@ -144,6 +148,16 @@ if(WITH_OPENVDB)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_ALEMBIC)
|
||||||
|
add_definitions(-DWITH_ALEMBIC)
|
||||||
|
list(APPEND INC_SYS
|
||||||
|
${ALEMBIC_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
list(APPEND LIB
|
||||||
|
${ALEMBIC_LIBRARIES}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_NANOVDB)
|
if(WITH_NANOVDB)
|
||||||
list(APPEND INC_SYS
|
list(APPEND INC_SYS
|
||||||
${NANOVDB_INCLUDE_DIRS}
|
${NANOVDB_INCLUDE_DIRS}
|
||||||
|
1869
intern/cycles/render/alembic.cpp
Normal file
1869
intern/cycles/render/alembic.cpp
Normal file
File diff suppressed because it is too large
Load Diff
404
intern/cycles/render/alembic.h
Normal file
404
intern/cycles/render/alembic.h
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2018 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "graph/node.h"
|
||||||
|
#include "render/attribute.h"
|
||||||
|
#include "render/procedural.h"
|
||||||
|
#include "util/util_set.h"
|
||||||
|
#include "util/util_transform.h"
|
||||||
|
#include "util/util_vector.h"
|
||||||
|
|
||||||
|
#ifdef WITH_ALEMBIC
|
||||||
|
|
||||||
|
# include <Alembic/AbcCoreFactory/All.h>
|
||||||
|
# include <Alembic/AbcGeom/All.h>
|
||||||
|
|
||||||
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class AlembicProcedural;
|
||||||
|
class Geometry;
|
||||||
|
class Object;
|
||||||
|
class Progress;
|
||||||
|
class Shader;
|
||||||
|
|
||||||
|
using MatrixSampleMap = std::map<Alembic::Abc::chrono_t, Alembic::Abc::M44d>;
|
||||||
|
|
||||||
|
/* Helpers to detect if some type is a ccl::array. */
|
||||||
|
template<typename> struct is_array : public std::false_type {
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> struct is_array<array<T>> : public std::true_type {
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Store the data set for an animation at every time points, or at the beginning of the animation
|
||||||
|
* for constant data.
|
||||||
|
*
|
||||||
|
* The data is supposed to be stored in chronological order, and is looked up using the current
|
||||||
|
* animation time in seconds using the TimeSampling from the Alembic property. */
|
||||||
|
template<typename T> class DataStore {
|
||||||
|
struct DataTimePair {
|
||||||
|
double time = 0;
|
||||||
|
T data{};
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<DataTimePair> data{};
|
||||||
|
Alembic::AbcCoreAbstract::TimeSampling time_sampling{};
|
||||||
|
|
||||||
|
double last_loaded_time = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling_)
|
||||||
|
{
|
||||||
|
time_sampling = time_sampling_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Alembic::AbcCoreAbstract::TimeSampling get_time_sampling() const
|
||||||
|
{
|
||||||
|
return time_sampling;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the data for the specified time.
|
||||||
|
* Return nullptr if there is no data or if the data for this time was already loaded. */
|
||||||
|
T *data_for_time(double time)
|
||||||
|
{
|
||||||
|
if (size() == 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
|
||||||
|
index_pair = time_sampling.getNearIndex(time, data.size());
|
||||||
|
DataTimePair &data_pair = data[index_pair.first];
|
||||||
|
|
||||||
|
if (last_loaded_time == data_pair.time) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_loaded_time = data_pair.time;
|
||||||
|
|
||||||
|
return &data_pair.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the data for the specified time, but do not check if the data was already loaded for this
|
||||||
|
* time return nullptr if there is no data */
|
||||||
|
T *data_for_time_no_check(double time)
|
||||||
|
{
|
||||||
|
if (size() == 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
|
||||||
|
index_pair = time_sampling.getNearIndex(time, data.size());
|
||||||
|
DataTimePair &data_pair = data[index_pair.first];
|
||||||
|
return &data_pair.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_data(T &data_, double time)
|
||||||
|
{
|
||||||
|
if constexpr (is_array<T>::value) {
|
||||||
|
data.emplace_back();
|
||||||
|
data.back().data.steal_data(data_);
|
||||||
|
data.back().time = time;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.push_back({time, data_});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_constant() const
|
||||||
|
{
|
||||||
|
return data.size() <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
invalidate_last_loaded_time();
|
||||||
|
data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate_last_loaded_time()
|
||||||
|
{
|
||||||
|
last_loaded_time = std::numeric_limits<double>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the data for the specified time to the node's socket. If there is no
|
||||||
|
* data for this time or it was already loaded, do nothing. */
|
||||||
|
void copy_to_socket(double time, Node *node, const SocketType *socket)
|
||||||
|
{
|
||||||
|
T *data_ = data_for_time(time);
|
||||||
|
|
||||||
|
if (data_ == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO(kevindietrich): arrays are emptied when passed to the sockets, so for now we copy the
|
||||||
|
* arrays to avoid reloading the data */
|
||||||
|
T value = *data_;
|
||||||
|
node->set(*socket, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Actual cache for the stored data.
|
||||||
|
* This caches the topological, transformation, and attribute data for a Mesh node or a Hair node
|
||||||
|
* inside of DataStores.
|
||||||
|
*/
|
||||||
|
struct CachedData {
|
||||||
|
DataStore<Transform> transforms{};
|
||||||
|
|
||||||
|
/* mesh data */
|
||||||
|
DataStore<array<float3>> vertices;
|
||||||
|
DataStore<array<int3>> triangles{};
|
||||||
|
/* triangle "loops" are the polygons' vertices indices used for indexing face varying attributes
|
||||||
|
* (like UVs) */
|
||||||
|
DataStore<array<int3>> triangles_loops{};
|
||||||
|
DataStore<array<int>> shader{};
|
||||||
|
|
||||||
|
/* subd data */
|
||||||
|
DataStore<array<int>> subd_start_corner;
|
||||||
|
DataStore<array<int>> subd_num_corners;
|
||||||
|
DataStore<array<bool>> subd_smooth;
|
||||||
|
DataStore<array<int>> subd_ptex_offset;
|
||||||
|
DataStore<array<int>> subd_face_corners;
|
||||||
|
DataStore<int> num_ngons;
|
||||||
|
DataStore<array<int>> subd_creases_edge;
|
||||||
|
DataStore<array<float>> subd_creases_weight;
|
||||||
|
|
||||||
|
/* hair data */
|
||||||
|
DataStore<array<float3>> curve_keys;
|
||||||
|
DataStore<array<float>> curve_radius;
|
||||||
|
DataStore<array<int>> curve_first_key;
|
||||||
|
DataStore<array<int>> curve_shader;
|
||||||
|
|
||||||
|
struct CachedAttribute {
|
||||||
|
AttributeStandard std;
|
||||||
|
AttributeElement element;
|
||||||
|
TypeDesc type_desc;
|
||||||
|
ustring name;
|
||||||
|
DataStore<array<char>> data{};
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<CachedAttribute> attributes{};
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
CachedAttribute &add_attribute(const ustring &name,
|
||||||
|
const Alembic::Abc::TimeSampling &time_sampling);
|
||||||
|
|
||||||
|
bool is_constant() const;
|
||||||
|
|
||||||
|
void invalidate_last_loaded_time(bool attributes_only = false);
|
||||||
|
|
||||||
|
void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Representation of an Alembic object for the AlembicProcedural.
|
||||||
|
*
|
||||||
|
* The AlembicObject holds the path to the Alembic IObject inside of the archive that is desired
|
||||||
|
* for rendering, as well as the list of shaders that it is using.
|
||||||
|
*
|
||||||
|
* The names of the shaders should correspond to the names of the FaceSets inside of the Alembic
|
||||||
|
* archive for per-triangle shader association. If there is no FaceSets, or the names do not
|
||||||
|
* match, the first shader is used for rendering for all triangles.
|
||||||
|
*/
|
||||||
|
class AlembicObject : public Node {
|
||||||
|
public:
|
||||||
|
NODE_DECLARE
|
||||||
|
|
||||||
|
/* Path to the IObject inside of the archive. */
|
||||||
|
NODE_SOCKET_API(ustring, path)
|
||||||
|
|
||||||
|
/* Shaders used for rendering. */
|
||||||
|
NODE_SOCKET_API_ARRAY(array<Node *>, used_shaders)
|
||||||
|
|
||||||
|
/* Maximum number of subdivisions for ISubD objects. */
|
||||||
|
NODE_SOCKET_API(int, subd_max_level)
|
||||||
|
|
||||||
|
/* Finest level of detail (in pixels) for the subdivision. */
|
||||||
|
NODE_SOCKET_API(float, subd_dicing_rate)
|
||||||
|
|
||||||
|
/* Scale the radius of points and curves. */
|
||||||
|
NODE_SOCKET_API(float, radius_scale)
|
||||||
|
|
||||||
|
AlembicObject();
|
||||||
|
~AlembicObject();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class AlembicProcedural;
|
||||||
|
|
||||||
|
void set_object(Object *object);
|
||||||
|
Object *get_object();
|
||||||
|
|
||||||
|
void load_all_data(AlembicProcedural *proc,
|
||||||
|
Alembic::AbcGeom::IPolyMeshSchema &schema,
|
||||||
|
float scale,
|
||||||
|
Progress &progress);
|
||||||
|
void load_all_data(AlembicProcedural *proc,
|
||||||
|
Alembic::AbcGeom::ISubDSchema &schema,
|
||||||
|
float scale,
|
||||||
|
Progress &progress);
|
||||||
|
void load_all_data(AlembicProcedural *proc,
|
||||||
|
const Alembic::AbcGeom::ICurvesSchema &schema,
|
||||||
|
float scale,
|
||||||
|
Progress &progress,
|
||||||
|
float default_radius);
|
||||||
|
|
||||||
|
bool has_data_loaded() const;
|
||||||
|
|
||||||
|
bool need_shader_update = true;
|
||||||
|
|
||||||
|
MatrixSampleMap xform_samples;
|
||||||
|
Alembic::AbcGeom::IObject iobject;
|
||||||
|
Transform xform;
|
||||||
|
|
||||||
|
CachedData &get_cached_data()
|
||||||
|
{
|
||||||
|
return cached_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_constant() const
|
||||||
|
{
|
||||||
|
return cached_data.is_constant();
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *object = nullptr;
|
||||||
|
|
||||||
|
bool data_loaded = false;
|
||||||
|
|
||||||
|
CachedData cached_data;
|
||||||
|
|
||||||
|
void update_shader_attributes(const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
|
||||||
|
Progress &progress);
|
||||||
|
|
||||||
|
void read_attribute(const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
|
||||||
|
const ustring &attr_name,
|
||||||
|
Progress &progress);
|
||||||
|
|
||||||
|
template<typename SchemaType>
|
||||||
|
void read_face_sets(SchemaType &schema,
|
||||||
|
array<int> &polygon_to_shader,
|
||||||
|
Alembic::AbcGeom::ISampleSelector sample_sel);
|
||||||
|
|
||||||
|
void setup_transform_cache(float scale);
|
||||||
|
|
||||||
|
AttributeRequestSet get_requested_attributes();
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Procedural to render objects from a single Alembic archive.
|
||||||
|
*
|
||||||
|
* Every object desired to be rendered should be passed as an AlembicObject through the objects
|
||||||
|
* socket.
|
||||||
|
*
|
||||||
|
* This procedural will load the data set for the entire animation in memory on the first frame,
|
||||||
|
* and directly set the data for the new frames on the created Nodes if needed. This allows for
|
||||||
|
* faster updates between frames as it avoids reseeking the data on disk.
|
||||||
|
*/
|
||||||
|
class AlembicProcedural : public Procedural {
|
||||||
|
Alembic::AbcGeom::IArchive archive;
|
||||||
|
bool objects_loaded;
|
||||||
|
Scene *scene_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NODE_DECLARE
|
||||||
|
|
||||||
|
/* The file path to the Alembic archive */
|
||||||
|
NODE_SOCKET_API(ustring, filepath)
|
||||||
|
|
||||||
|
/* The current frame to render. */
|
||||||
|
NODE_SOCKET_API(float, frame)
|
||||||
|
|
||||||
|
/* The first frame to load data for. */
|
||||||
|
NODE_SOCKET_API(float, start_frame)
|
||||||
|
|
||||||
|
/* The last frame to load data for. */
|
||||||
|
NODE_SOCKET_API(float, end_frame)
|
||||||
|
|
||||||
|
/* Subtracted to the current frame. */
|
||||||
|
NODE_SOCKET_API(float, frame_offset)
|
||||||
|
|
||||||
|
/* The frame rate used for rendering in units of frames per second. */
|
||||||
|
NODE_SOCKET_API(float, frame_rate)
|
||||||
|
|
||||||
|
/* List of AlembicObjects to render. */
|
||||||
|
NODE_SOCKET_API_ARRAY(array<Node *>, objects)
|
||||||
|
|
||||||
|
/* Set the default radius to use for curves when the Alembic Curves Schemas do not have radius
|
||||||
|
* information. */
|
||||||
|
NODE_SOCKET_API(float, default_radius)
|
||||||
|
|
||||||
|
/* Multiplier to account for differences in default units for measuring objects in various
|
||||||
|
* software. */
|
||||||
|
NODE_SOCKET_API(float, scale)
|
||||||
|
|
||||||
|
AlembicProcedural();
|
||||||
|
~AlembicProcedural();
|
||||||
|
|
||||||
|
/* Populates the Cycles scene with Nodes for every contained AlembicObject on the first
|
||||||
|
* invocation, and updates the data on subsequent invocations if the frame changed. */
|
||||||
|
void generate(Scene *scene, Progress &progress);
|
||||||
|
|
||||||
|
/* Add an object to our list of objects, and tag the socket as modified. */
|
||||||
|
void add_object(AlembicObject *object);
|
||||||
|
|
||||||
|
/* Tag for an update only if something was modified. */
|
||||||
|
void tag_update(Scene *scene);
|
||||||
|
|
||||||
|
/* Returns a pointer to an exisiting or a newly created AlembicObject for the given path. */
|
||||||
|
AlembicObject *get_or_create_object(const ustring &path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Load the data for all the objects whose data has not yet been loaded. */
|
||||||
|
void load_objects(Progress &progress);
|
||||||
|
|
||||||
|
/* Traverse the Alembic hierarchy to lookup the IObjects for the AlembicObjects that were
|
||||||
|
* specified in our objects socket, and accumulate all of the transformations samples along the
|
||||||
|
* way for each IObject. */
|
||||||
|
void walk_hierarchy(Alembic::AbcGeom::IObject parent,
|
||||||
|
const Alembic::AbcGeom::ObjectHeader &ohead,
|
||||||
|
MatrixSampleMap *xform_samples,
|
||||||
|
const unordered_map<string, AlembicObject *> &object_map,
|
||||||
|
Progress &progress);
|
||||||
|
|
||||||
|
/* Read the data for an IPolyMesh at the specified frame_time. Creates corresponding Geometry and
|
||||||
|
* Object Nodes in the Cycles scene if none exist yet. */
|
||||||
|
void read_mesh(Scene *scene,
|
||||||
|
AlembicObject *abc_object,
|
||||||
|
Alembic::AbcGeom::Abc::chrono_t frame_time,
|
||||||
|
Progress &progress);
|
||||||
|
|
||||||
|
/* Read the data for an ICurves at the specified frame_time. Creates corresponding Geometry and
|
||||||
|
* Object Nodes in the Cycles scene if none exist yet. */
|
||||||
|
void read_curves(Scene *scene,
|
||||||
|
AlembicObject *abc_object,
|
||||||
|
Alembic::AbcGeom::Abc::chrono_t frame_time,
|
||||||
|
Progress &progress);
|
||||||
|
|
||||||
|
/* Read the data for an ISubD at the specified frame_time. Creates corresponding Geometry and
|
||||||
|
* Object Nodes in the Cycles scene if none exist yet. */
|
||||||
|
void read_subd(Scene *scene,
|
||||||
|
AlembicObject *abc_object,
|
||||||
|
Alembic::AbcGeom::Abc::chrono_t frame_time,
|
||||||
|
Progress &progress);
|
||||||
|
};
|
||||||
|
|
||||||
|
CCL_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif
|
@@ -28,7 +28,7 @@ CCL_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
Attribute::Attribute(
|
Attribute::Attribute(
|
||||||
ustring name, TypeDesc type, AttributeElement element, Geometry *geom, AttributePrimitive prim)
|
ustring name, TypeDesc type, AttributeElement element, Geometry *geom, AttributePrimitive prim)
|
||||||
: name(name), std(ATTR_STD_NONE), type(type), element(element), flags(0)
|
: name(name), std(ATTR_STD_NONE), type(type), element(element), flags(0), modified(true)
|
||||||
{
|
{
|
||||||
/* string and matrix not supported! */
|
/* string and matrix not supported! */
|
||||||
assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
|
assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
|
||||||
@@ -82,6 +82,8 @@ void Attribute::add(const float &f)
|
|||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
|
||||||
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::add(const uchar4 &f)
|
void Attribute::add(const uchar4 &f)
|
||||||
@@ -93,6 +95,8 @@ void Attribute::add(const uchar4 &f)
|
|||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
|
||||||
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::add(const float2 &f)
|
void Attribute::add(const float2 &f)
|
||||||
@@ -104,6 +108,8 @@ void Attribute::add(const float2 &f)
|
|||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
|
||||||
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::add(const float3 &f)
|
void Attribute::add(const float3 &f)
|
||||||
@@ -115,6 +121,8 @@ void Attribute::add(const float3 &f)
|
|||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
|
||||||
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::add(const Transform &f)
|
void Attribute::add(const Transform &f)
|
||||||
@@ -126,6 +134,8 @@ void Attribute::add(const Transform &f)
|
|||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
|
||||||
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::add(const char *data)
|
void Attribute::add(const char *data)
|
||||||
@@ -134,6 +144,26 @@ void Attribute::add(const char *data)
|
|||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Attribute::set_data_from(Attribute &&other)
|
||||||
|
{
|
||||||
|
assert(other.std == std);
|
||||||
|
assert(other.type == type);
|
||||||
|
assert(other.element == element);
|
||||||
|
|
||||||
|
this->flags = other.flags;
|
||||||
|
|
||||||
|
if (this->buffer.size() != other.buffer.size()) {
|
||||||
|
this->buffer = std::move(other.buffer);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
else if (memcmp(this->data(), other.data(), other.buffer.size()) != 0) {
|
||||||
|
this->buffer = std::move(other.buffer);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Attribute::data_sizeof() const
|
size_t Attribute::data_sizeof() const
|
||||||
@@ -627,6 +657,42 @@ void AttributeSet::clear(bool preserve_voxel_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AttributeSet::update(AttributeSet &&new_attributes)
|
||||||
|
{
|
||||||
|
/* add or update old_attributes based on the new_attributes */
|
||||||
|
foreach (Attribute &attr, new_attributes.attributes) {
|
||||||
|
Attribute *nattr = add(attr.name, attr.type, attr.element);
|
||||||
|
nattr->std = attr.std;
|
||||||
|
nattr->set_data_from(std::move(attr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove any attributes not on new_attributes */
|
||||||
|
list<Attribute>::iterator it;
|
||||||
|
for (it = attributes.begin(); it != attributes.end();) {
|
||||||
|
if (it->std != ATTR_STD_NONE) {
|
||||||
|
if (new_attributes.find(it->std) == nullptr) {
|
||||||
|
attributes.erase(it++);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (it->name != "") {
|
||||||
|
if (new_attributes.find(it->name) == nullptr) {
|
||||||
|
attributes.erase(it++);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttributeSet::clear_modified()
|
||||||
|
{
|
||||||
|
foreach (Attribute &attr, attributes) {
|
||||||
|
attr.modified = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* AttributeRequest */
|
/* AttributeRequest */
|
||||||
|
|
||||||
AttributeRequest::AttributeRequest(ustring name_)
|
AttributeRequest::AttributeRequest(ustring name_)
|
||||||
|
@@ -54,6 +54,8 @@ class Attribute {
|
|||||||
AttributeElement element;
|
AttributeElement element;
|
||||||
uint flags; /* enum AttributeFlag */
|
uint flags; /* enum AttributeFlag */
|
||||||
|
|
||||||
|
bool modified;
|
||||||
|
|
||||||
Attribute(ustring name,
|
Attribute(ustring name,
|
||||||
TypeDesc type,
|
TypeDesc type,
|
||||||
AttributeElement element,
|
AttributeElement element,
|
||||||
@@ -159,6 +161,8 @@ class Attribute {
|
|||||||
void add(const Transform &tfm);
|
void add(const Transform &tfm);
|
||||||
void add(const char *data);
|
void add(const char *data);
|
||||||
|
|
||||||
|
void set_data_from(Attribute &&other);
|
||||||
|
|
||||||
static bool same_storage(TypeDesc a, TypeDesc b);
|
static bool same_storage(TypeDesc a, TypeDesc b);
|
||||||
static const char *standard_name(AttributeStandard std);
|
static const char *standard_name(AttributeStandard std);
|
||||||
static AttributeStandard name_standard(const char *name);
|
static AttributeStandard name_standard(const char *name);
|
||||||
@@ -194,6 +198,12 @@ class AttributeSet {
|
|||||||
|
|
||||||
void resize(bool reserve_only = false);
|
void resize(bool reserve_only = false);
|
||||||
void clear(bool preserve_voxel_data = false);
|
void clear(bool preserve_voxel_data = false);
|
||||||
|
|
||||||
|
/* Update the attributes in this AttributeSet with the ones from the new set,
|
||||||
|
* and remove any attribute not found on the new set from this. */
|
||||||
|
void update(AttributeSet &&new_attributes);
|
||||||
|
|
||||||
|
void clear_modified();
|
||||||
};
|
};
|
||||||
|
|
||||||
/* AttributeRequest
|
/* AttributeRequest
|
||||||
|
@@ -130,8 +130,9 @@ void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
|
|||||||
|
|
||||||
void Background::tag_update(Scene *scene)
|
void Background::tag_update(Scene *scene)
|
||||||
{
|
{
|
||||||
scene->integrator->tag_update(scene);
|
if (ao_factor_is_modified() || use_ao_is_modified()) {
|
||||||
tag_modified();
|
scene->integrator->tag_update(scene, Integrator::BACKGROUND_AO_MODIFIED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader *Background::get_shader(const Scene *scene)
|
Shader *Background::get_shader(const Scene *scene)
|
||||||
|
@@ -78,7 +78,7 @@ BakeManager::BakeManager()
|
|||||||
type = SHADER_EVAL_BAKE;
|
type = SHADER_EVAL_BAKE;
|
||||||
pass_filter = 0;
|
pass_filter = 0;
|
||||||
|
|
||||||
need_update = true;
|
need_update_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BakeManager::~BakeManager()
|
BakeManager::~BakeManager()
|
||||||
@@ -114,9 +114,9 @@ void BakeManager::set(Scene *scene,
|
|||||||
|
|
||||||
/* create device and update scene */
|
/* create device and update scene */
|
||||||
scene->film->tag_modified();
|
scene->film->tag_modified();
|
||||||
scene->integrator->tag_update(scene);
|
scene->integrator->tag_update(scene, Integrator::UPDATE_ALL);
|
||||||
|
|
||||||
need_update = true;
|
need_update_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BakeManager::device_update(Device * /*device*/,
|
void BakeManager::device_update(Device * /*device*/,
|
||||||
@@ -124,7 +124,7 @@ void BakeManager::device_update(Device * /*device*/,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress & /* progress */)
|
Progress & /* progress */)
|
||||||
{
|
{
|
||||||
if (!need_update)
|
if (!need_update())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
@@ -152,11 +152,21 @@ void BakeManager::device_update(Device * /*device*/,
|
|||||||
object_index++;
|
object_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
need_update = false;
|
need_update_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
|
void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BakeManager::tag_update()
|
||||||
|
{
|
||||||
|
need_update_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BakeManager::need_update() const
|
||||||
|
{
|
||||||
|
return need_update_;
|
||||||
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -36,9 +36,12 @@ class BakeManager {
|
|||||||
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
|
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
|
||||||
void device_free(Device *device, DeviceScene *dscene);
|
void device_free(Device *device, DeviceScene *dscene);
|
||||||
|
|
||||||
bool need_update;
|
void tag_update();
|
||||||
|
|
||||||
|
bool need_update() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool need_update_;
|
||||||
ShaderEvalType type;
|
ShaderEvalType type;
|
||||||
int pass_filter;
|
int pass_filter;
|
||||||
std::string object_name;
|
std::string object_name;
|
||||||
|
@@ -212,8 +212,8 @@ void Camera::compute_auto_viewplane()
|
|||||||
viewplane.top = 1.0f;
|
viewplane.top = 1.0f;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float aspect = (float)width / (float)height;
|
float aspect = (float)full_width / (float)full_height;
|
||||||
if (width >= height) {
|
if (full_width >= full_height) {
|
||||||
viewplane.left = -aspect;
|
viewplane.left = -aspect;
|
||||||
viewplane.right = aspect;
|
viewplane.right = aspect;
|
||||||
viewplane.bottom = -1.0f;
|
viewplane.bottom = -1.0f;
|
||||||
|
@@ -688,16 +688,16 @@ void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *sce
|
|||||||
void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool update_passes)
|
void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool update_passes)
|
||||||
{
|
{
|
||||||
if (Pass::contains(scene->passes, PASS_UV) != Pass::contains(passes_, PASS_UV)) {
|
if (Pass::contains(scene->passes, PASS_UV) != Pass::contains(passes_, PASS_UV)) {
|
||||||
scene->geometry_manager->tag_update(scene);
|
scene->geometry_manager->tag_update(scene, GeometryManager::UV_PASS_NEEDED);
|
||||||
|
|
||||||
foreach (Shader *shader, scene->shaders)
|
foreach (Shader *shader, scene->shaders)
|
||||||
shader->need_update_geometry = true;
|
shader->need_update_uvs = true;
|
||||||
}
|
}
|
||||||
else if (Pass::contains(scene->passes, PASS_MOTION) != Pass::contains(passes_, PASS_MOTION)) {
|
else if (Pass::contains(scene->passes, PASS_MOTION) != Pass::contains(passes_, PASS_MOTION)) {
|
||||||
scene->geometry_manager->tag_update(scene);
|
scene->geometry_manager->tag_update(scene, GeometryManager::MOTION_PASS_NEEDED);
|
||||||
}
|
}
|
||||||
else if (Pass::contains(scene->passes, PASS_AO) != Pass::contains(passes_, PASS_AO)) {
|
else if (Pass::contains(scene->passes, PASS_AO) != Pass::contains(passes_, PASS_AO)) {
|
||||||
scene->integrator->tag_update(scene);
|
scene->integrator->tag_update(scene, Integrator::AO_PASS_MODIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update_passes) {
|
if (update_passes) {
|
||||||
|
@@ -240,7 +240,6 @@ void Geometry::compute_bvh(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_modified();
|
|
||||||
need_update_rebuild = false;
|
need_update_rebuild = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,22 +261,21 @@ bool Geometry::has_voxel_attributes() const
|
|||||||
|
|
||||||
void Geometry::tag_update(Scene *scene, bool rebuild)
|
void Geometry::tag_update(Scene *scene, bool rebuild)
|
||||||
{
|
{
|
||||||
tag_modified();
|
|
||||||
|
|
||||||
if (rebuild) {
|
if (rebuild) {
|
||||||
need_update_rebuild = true;
|
need_update_rebuild = true;
|
||||||
scene->light_manager->need_update = true;
|
scene->light_manager->tag_update(scene, LightManager::MESH_NEED_REBUILD);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
foreach (Node *node, used_shaders) {
|
foreach (Node *node, used_shaders) {
|
||||||
Shader *shader = static_cast<Shader *>(node);
|
Shader *shader = static_cast<Shader *>(node);
|
||||||
if (shader->has_surface_emission)
|
if (shader->has_surface_emission) {
|
||||||
scene->light_manager->need_update = true;
|
scene->light_manager->tag_update(scene, LightManager::EMISSIVE_MESH_MODIFIED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scene->geometry_manager->need_update = true;
|
scene->geometry_manager->tag_update(scene, GeometryManager::GEOMETRY_MODIFIED);
|
||||||
scene->object_manager->need_update = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Geometry::tag_bvh_update(bool rebuild)
|
void Geometry::tag_bvh_update(bool rebuild)
|
||||||
@@ -293,7 +291,7 @@ void Geometry::tag_bvh_update(bool rebuild)
|
|||||||
|
|
||||||
GeometryManager::GeometryManager()
|
GeometryManager::GeometryManager()
|
||||||
{
|
{
|
||||||
need_update = true;
|
update_flags = UPDATE_ALL;
|
||||||
need_flags_update = true;
|
need_flags_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,6 +492,10 @@ void GeometryManager::update_svm_attributes(Device *,
|
|||||||
if (attr_map_size == 0)
|
if (attr_map_size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!dscene->attributes_map.need_realloc()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* create attribute map */
|
/* create attribute map */
|
||||||
uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size);
|
uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size);
|
||||||
memset(attr_map, 0, dscene->attributes_map.size() * sizeof(uint));
|
memset(attr_map, 0, dscene->attributes_map.size() * sizeof(uint));
|
||||||
@@ -602,8 +604,10 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
|
|||||||
offset = attr_uchar4_offset;
|
offset = attr_uchar4_offset;
|
||||||
|
|
||||||
assert(attr_uchar4.size() >= offset + size);
|
assert(attr_uchar4.size() >= offset + size);
|
||||||
for (size_t k = 0; k < size; k++) {
|
if (mattr->modified) {
|
||||||
attr_uchar4[offset + k] = data[k];
|
for (size_t k = 0; k < size; k++) {
|
||||||
|
attr_uchar4[offset + k] = data[k];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
attr_uchar4_offset += size;
|
attr_uchar4_offset += size;
|
||||||
}
|
}
|
||||||
@@ -612,8 +616,10 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
|
|||||||
offset = attr_float_offset;
|
offset = attr_float_offset;
|
||||||
|
|
||||||
assert(attr_float.size() >= offset + size);
|
assert(attr_float.size() >= offset + size);
|
||||||
for (size_t k = 0; k < size; k++) {
|
if (mattr->modified) {
|
||||||
attr_float[offset + k] = data[k];
|
for (size_t k = 0; k < size; k++) {
|
||||||
|
attr_float[offset + k] = data[k];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
attr_float_offset += size;
|
attr_float_offset += size;
|
||||||
}
|
}
|
||||||
@@ -622,8 +628,10 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
|
|||||||
offset = attr_float2_offset;
|
offset = attr_float2_offset;
|
||||||
|
|
||||||
assert(attr_float2.size() >= offset + size);
|
assert(attr_float2.size() >= offset + size);
|
||||||
for (size_t k = 0; k < size; k++) {
|
if (mattr->modified) {
|
||||||
attr_float2[offset + k] = data[k];
|
for (size_t k = 0; k < size; k++) {
|
||||||
|
attr_float2[offset + k] = data[k];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
attr_float2_offset += size;
|
attr_float2_offset += size;
|
||||||
}
|
}
|
||||||
@@ -632,8 +640,10 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
|
|||||||
offset = attr_float3_offset;
|
offset = attr_float3_offset;
|
||||||
|
|
||||||
assert(attr_float3.size() >= offset + size * 3);
|
assert(attr_float3.size() >= offset + size * 3);
|
||||||
for (size_t k = 0; k < size * 3; k++) {
|
if (mattr->modified) {
|
||||||
attr_float3[offset + k] = (&tfm->x)[k];
|
for (size_t k = 0; k < size * 3; k++) {
|
||||||
|
attr_float3[offset + k] = (&tfm->x)[k];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
attr_float3_offset += size * 3;
|
attr_float3_offset += size * 3;
|
||||||
}
|
}
|
||||||
@@ -642,8 +652,10 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
|
|||||||
offset = attr_float3_offset;
|
offset = attr_float3_offset;
|
||||||
|
|
||||||
assert(attr_float3.size() >= offset + size);
|
assert(attr_float3.size() >= offset + size);
|
||||||
for (size_t k = 0; k < size; k++) {
|
if (mattr->modified) {
|
||||||
attr_float3[offset + k] = data[k];
|
for (size_t k = 0; k < size; k++) {
|
||||||
|
attr_float3[offset + k] = data[k];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
attr_float3_offset += size;
|
attr_float3_offset += size;
|
||||||
}
|
}
|
||||||
@@ -808,6 +820,11 @@ void GeometryManager::device_update_attributes(Device *device,
|
|||||||
dscene->attributes_float3.alloc(attr_float3_size);
|
dscene->attributes_float3.alloc(attr_float3_size);
|
||||||
dscene->attributes_uchar4.alloc(attr_uchar4_size);
|
dscene->attributes_uchar4.alloc(attr_uchar4_size);
|
||||||
|
|
||||||
|
const bool copy_all_data = dscene->attributes_float.need_realloc() ||
|
||||||
|
dscene->attributes_float2.need_realloc() ||
|
||||||
|
dscene->attributes_float3.need_realloc() ||
|
||||||
|
dscene->attributes_uchar4.need_realloc();
|
||||||
|
|
||||||
size_t attr_float_offset = 0;
|
size_t attr_float_offset = 0;
|
||||||
size_t attr_float2_offset = 0;
|
size_t attr_float2_offset = 0;
|
||||||
size_t attr_float3_offset = 0;
|
size_t attr_float3_offset = 0;
|
||||||
@@ -822,6 +839,12 @@ void GeometryManager::device_update_attributes(Device *device,
|
|||||||
* they actually refer to the same mesh attributes, optimize */
|
* they actually refer to the same mesh attributes, optimize */
|
||||||
foreach (AttributeRequest &req, attributes.requests) {
|
foreach (AttributeRequest &req, attributes.requests) {
|
||||||
Attribute *attr = geom->attributes.find(req);
|
Attribute *attr = geom->attributes.find(req);
|
||||||
|
|
||||||
|
if (attr) {
|
||||||
|
/* force a copy if we need to reallocate all the data */
|
||||||
|
attr->modified |= copy_all_data;
|
||||||
|
}
|
||||||
|
|
||||||
update_attribute_element_offset(geom,
|
update_attribute_element_offset(geom,
|
||||||
dscene->attributes_float,
|
dscene->attributes_float,
|
||||||
attr_float_offset,
|
attr_float_offset,
|
||||||
@@ -840,6 +863,11 @@ void GeometryManager::device_update_attributes(Device *device,
|
|||||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||||
Attribute *subd_attr = mesh->subd_attributes.find(req);
|
Attribute *subd_attr = mesh->subd_attributes.find(req);
|
||||||
|
|
||||||
|
if (subd_attr) {
|
||||||
|
/* force a copy if we need to reallocate all the data */
|
||||||
|
subd_attr->modified |= copy_all_data;
|
||||||
|
}
|
||||||
|
|
||||||
update_attribute_element_offset(mesh,
|
update_attribute_element_offset(mesh,
|
||||||
dscene->attributes_float,
|
dscene->attributes_float,
|
||||||
attr_float_offset,
|
attr_float_offset,
|
||||||
@@ -903,18 +931,10 @@ void GeometryManager::device_update_attributes(Device *device,
|
|||||||
/* copy to device */
|
/* copy to device */
|
||||||
progress.set_status("Updating Mesh", "Copying Attributes to device");
|
progress.set_status("Updating Mesh", "Copying Attributes to device");
|
||||||
|
|
||||||
if (dscene->attributes_float.size()) {
|
dscene->attributes_float.copy_to_device();
|
||||||
dscene->attributes_float.copy_to_device();
|
dscene->attributes_float2.copy_to_device();
|
||||||
}
|
dscene->attributes_float3.copy_to_device();
|
||||||
if (dscene->attributes_float2.size()) {
|
dscene->attributes_uchar4.copy_to_device();
|
||||||
dscene->attributes_float2.copy_to_device();
|
|
||||||
}
|
|
||||||
if (dscene->attributes_float3.size()) {
|
|
||||||
dscene->attributes_float3.copy_to_device();
|
|
||||||
}
|
|
||||||
if (dscene->attributes_uchar4.size()) {
|
|
||||||
dscene->attributes_uchar4.copy_to_device();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel())
|
||||||
return;
|
return;
|
||||||
@@ -1066,17 +1086,34 @@ void GeometryManager::device_update_mesh(
|
|||||||
uint *tri_patch = dscene->tri_patch.alloc(tri_size);
|
uint *tri_patch = dscene->tri_patch.alloc(tri_size);
|
||||||
float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size);
|
float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size);
|
||||||
|
|
||||||
|
const bool copy_all_data = dscene->tri_shader.need_realloc() ||
|
||||||
|
dscene->tri_vindex.need_realloc() ||
|
||||||
|
dscene->tri_vnormal.need_realloc() ||
|
||||||
|
dscene->tri_patch.need_realloc() ||
|
||||||
|
dscene->tri_patch_uv.need_realloc();
|
||||||
|
|
||||||
foreach (Geometry *geom, scene->geometry) {
|
foreach (Geometry *geom, scene->geometry) {
|
||||||
if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
|
if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
|
||||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||||
mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]);
|
|
||||||
mesh->pack_normals(&vnormal[mesh->vert_offset]);
|
if (mesh->shader_is_modified() || mesh->smooth_is_modified() ||
|
||||||
mesh->pack_verts(tri_prim_index,
|
mesh->triangles_is_modified() || copy_all_data) {
|
||||||
&tri_vindex[mesh->prim_offset],
|
mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]);
|
||||||
&tri_patch[mesh->prim_offset],
|
}
|
||||||
&tri_patch_uv[mesh->vert_offset],
|
|
||||||
mesh->vert_offset,
|
if (mesh->verts_is_modified() || copy_all_data) {
|
||||||
mesh->prim_offset);
|
mesh->pack_normals(&vnormal[mesh->vert_offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh->triangles_is_modified() || mesh->vert_patch_uv_is_modified() || copy_all_data) {
|
||||||
|
mesh->pack_verts(tri_prim_index,
|
||||||
|
&tri_vindex[mesh->prim_offset],
|
||||||
|
&tri_patch[mesh->prim_offset],
|
||||||
|
&tri_patch_uv[mesh->vert_offset],
|
||||||
|
mesh->vert_offset,
|
||||||
|
mesh->prim_offset);
|
||||||
|
}
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1085,11 +1122,11 @@ void GeometryManager::device_update_mesh(
|
|||||||
/* vertex coordinates */
|
/* vertex coordinates */
|
||||||
progress.set_status("Updating Mesh", "Copying Mesh to device");
|
progress.set_status("Updating Mesh", "Copying Mesh to device");
|
||||||
|
|
||||||
dscene->tri_shader.copy_to_device();
|
dscene->tri_shader.copy_to_device_if_modified();
|
||||||
dscene->tri_vnormal.copy_to_device();
|
dscene->tri_vnormal.copy_to_device_if_modified();
|
||||||
dscene->tri_vindex.copy_to_device();
|
dscene->tri_vindex.copy_to_device_if_modified();
|
||||||
dscene->tri_patch.copy_to_device();
|
dscene->tri_patch.copy_to_device_if_modified();
|
||||||
dscene->tri_patch_uv.copy_to_device();
|
dscene->tri_patch_uv.copy_to_device_if_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curve_size != 0) {
|
if (curve_size != 0) {
|
||||||
@@ -1098,9 +1135,21 @@ void GeometryManager::device_update_mesh(
|
|||||||
float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size);
|
float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size);
|
||||||
float4 *curves = dscene->curves.alloc(curve_size);
|
float4 *curves = dscene->curves.alloc(curve_size);
|
||||||
|
|
||||||
|
const bool copy_all_data = dscene->curve_keys.need_realloc() || dscene->curves.need_realloc();
|
||||||
|
|
||||||
foreach (Geometry *geom, scene->geometry) {
|
foreach (Geometry *geom, scene->geometry) {
|
||||||
if (geom->is_hair()) {
|
if (geom->is_hair()) {
|
||||||
Hair *hair = static_cast<Hair *>(geom);
|
Hair *hair = static_cast<Hair *>(geom);
|
||||||
|
|
||||||
|
bool curve_keys_co_modified = hair->curve_radius_is_modified() ||
|
||||||
|
hair->curve_keys_is_modified();
|
||||||
|
bool curve_data_modified = hair->curve_shader_is_modified() ||
|
||||||
|
hair->curve_first_key_is_modified();
|
||||||
|
|
||||||
|
if (!curve_keys_co_modified && !curve_data_modified && !copy_all_data) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
hair->pack_curves(scene,
|
hair->pack_curves(scene,
|
||||||
&curve_keys[hair->curvekey_offset],
|
&curve_keys[hair->curvekey_offset],
|
||||||
&curves[hair->prim_offset],
|
&curves[hair->prim_offset],
|
||||||
@@ -1110,11 +1159,11 @@ void GeometryManager::device_update_mesh(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dscene->curve_keys.copy_to_device();
|
dscene->curve_keys.copy_to_device_if_modified();
|
||||||
dscene->curves.copy_to_device();
|
dscene->curves.copy_to_device_if_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patch_size != 0) {
|
if (patch_size != 0 && dscene->patches.need_realloc()) {
|
||||||
progress.set_status("Updating Mesh", "Copying Patches to device");
|
progress.set_status("Updating Mesh", "Copying Patches to device");
|
||||||
|
|
||||||
uint *patch_data = dscene->patches.alloc(patch_size);
|
uint *patch_data = dscene->patches.alloc(patch_size);
|
||||||
@@ -1180,16 +1229,25 @@ void GeometryManager::device_update_bvh(Device *device,
|
|||||||
|
|
||||||
VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
|
VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
|
||||||
|
|
||||||
delete scene->bvh;
|
const bool can_refit = scene->bvh != nullptr &&
|
||||||
BVH *bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
|
(bparams.bvh_layout == BVHLayout::BVH_LAYOUT_OPTIX);
|
||||||
device->build_bvh(bvh, progress, false);
|
const bool pack_all = scene->bvh == nullptr;
|
||||||
|
|
||||||
|
BVH *bvh = scene->bvh;
|
||||||
|
if (!scene->bvh) {
|
||||||
|
bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
device->build_bvh(bvh, progress, can_refit);
|
||||||
|
|
||||||
if (progress.get_cancel()) {
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool has_bvh2_layout = (bparams.bvh_layout == BVH_LAYOUT_BVH2);
|
||||||
|
|
||||||
PackedBVH pack;
|
PackedBVH pack;
|
||||||
if (bparams.bvh_layout == BVH_LAYOUT_BVH2) {
|
if (has_bvh2_layout) {
|
||||||
pack = std::move(static_cast<BVH2 *>(bvh)->pack);
|
pack = std::move(static_cast<BVH2 *>(bvh)->pack);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1210,12 +1268,22 @@ void GeometryManager::device_update_bvh(Device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pack.root_index = -1;
|
pack.root_index = -1;
|
||||||
pack.prim_tri_index.reserve(num_prims);
|
|
||||||
pack.prim_tri_verts.reserve(num_tri_verts);
|
if (!pack_all) {
|
||||||
pack.prim_type.reserve(num_prims);
|
/* if we do not need to recreate the BVH, then only the vertices are updated, so we can
|
||||||
pack.prim_index.reserve(num_prims);
|
* safely retake the memory */
|
||||||
pack.prim_object.reserve(num_prims);
|
dscene->prim_tri_verts.give_data(pack.prim_tri_verts);
|
||||||
pack.prim_visibility.reserve(num_prims);
|
}
|
||||||
|
else {
|
||||||
|
/* It is not strictly necessary to skip those resizes we if do not have to repack, as the OS
|
||||||
|
* will not allocate pages if we do not touch them, however it does help catching bugs. */
|
||||||
|
pack.prim_tri_index.resize(num_prims);
|
||||||
|
pack.prim_tri_verts.resize(num_tri_verts);
|
||||||
|
pack.prim_type.resize(num_prims);
|
||||||
|
pack.prim_index.resize(num_prims);
|
||||||
|
pack.prim_object.resize(num_prims);
|
||||||
|
pack.prim_visibility.resize(num_prims);
|
||||||
|
}
|
||||||
|
|
||||||
// Merge visibility flags of all objects and find object index for non-instanced geometry
|
// Merge visibility flags of all objects and find object index for non-instanced geometry
|
||||||
unordered_map<const Geometry *, pair<int, uint>> geometry_to_object_info;
|
unordered_map<const Geometry *, pair<int, uint>> geometry_to_object_info;
|
||||||
@@ -1229,17 +1297,27 @@ void GeometryManager::device_update_bvh(Device *device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TaskPool pool;
|
||||||
// Iterate over scene mesh list instead of objects, since 'optix_prim_offset' was calculated
|
// Iterate over scene mesh list instead of objects, since 'optix_prim_offset' was calculated
|
||||||
// based on that list, which may be ordered differently from the object list.
|
// based on that list, which may be ordered differently from the object list.
|
||||||
foreach (Geometry *geom, scene->geometry) {
|
foreach (Geometry *geom, scene->geometry) {
|
||||||
|
if (!pack_all && !geom->is_modified()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const pair<int, uint> &info = geometry_to_object_info[geom];
|
const pair<int, uint> &info = geometry_to_object_info[geom];
|
||||||
geom->pack_primitives(pack, info.first, info.second);
|
pool.push(function_bind(
|
||||||
|
&Geometry::pack_primitives, geom, &pack, info.first, info.second, pack_all));
|
||||||
}
|
}
|
||||||
|
pool.wait_work();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy to device */
|
/* copy to device */
|
||||||
progress.set_status("Updating Scene BVH", "Copying BVH to device");
|
progress.set_status("Updating Scene BVH", "Copying BVH to device");
|
||||||
|
|
||||||
|
/* When using BVH2, we always have to copy/update the data as its layout is dependent on the
|
||||||
|
* BVH's leaf nodes which may be different when the objects or vertices move. */
|
||||||
|
|
||||||
if (pack.nodes.size()) {
|
if (pack.nodes.size()) {
|
||||||
dscene->bvh_nodes.steal_data(pack.nodes);
|
dscene->bvh_nodes.steal_data(pack.nodes);
|
||||||
dscene->bvh_nodes.copy_to_device();
|
dscene->bvh_nodes.copy_to_device();
|
||||||
@@ -1252,7 +1330,7 @@ void GeometryManager::device_update_bvh(Device *device,
|
|||||||
dscene->object_node.steal_data(pack.object_node);
|
dscene->object_node.steal_data(pack.object_node);
|
||||||
dscene->object_node.copy_to_device();
|
dscene->object_node.copy_to_device();
|
||||||
}
|
}
|
||||||
if (pack.prim_tri_index.size()) {
|
if (pack.prim_tri_index.size() && (dscene->prim_tri_index.need_realloc() || has_bvh2_layout)) {
|
||||||
dscene->prim_tri_index.steal_data(pack.prim_tri_index);
|
dscene->prim_tri_index.steal_data(pack.prim_tri_index);
|
||||||
dscene->prim_tri_index.copy_to_device();
|
dscene->prim_tri_index.copy_to_device();
|
||||||
}
|
}
|
||||||
@@ -1260,23 +1338,23 @@ void GeometryManager::device_update_bvh(Device *device,
|
|||||||
dscene->prim_tri_verts.steal_data(pack.prim_tri_verts);
|
dscene->prim_tri_verts.steal_data(pack.prim_tri_verts);
|
||||||
dscene->prim_tri_verts.copy_to_device();
|
dscene->prim_tri_verts.copy_to_device();
|
||||||
}
|
}
|
||||||
if (pack.prim_type.size()) {
|
if (pack.prim_type.size() && (dscene->prim_type.need_realloc() || has_bvh2_layout)) {
|
||||||
dscene->prim_type.steal_data(pack.prim_type);
|
dscene->prim_type.steal_data(pack.prim_type);
|
||||||
dscene->prim_type.copy_to_device();
|
dscene->prim_type.copy_to_device();
|
||||||
}
|
}
|
||||||
if (pack.prim_visibility.size()) {
|
if (pack.prim_visibility.size() && (dscene->prim_visibility.need_realloc() || has_bvh2_layout)) {
|
||||||
dscene->prim_visibility.steal_data(pack.prim_visibility);
|
dscene->prim_visibility.steal_data(pack.prim_visibility);
|
||||||
dscene->prim_visibility.copy_to_device();
|
dscene->prim_visibility.copy_to_device();
|
||||||
}
|
}
|
||||||
if (pack.prim_index.size()) {
|
if (pack.prim_index.size() && (dscene->prim_index.need_realloc() || has_bvh2_layout)) {
|
||||||
dscene->prim_index.steal_data(pack.prim_index);
|
dscene->prim_index.steal_data(pack.prim_index);
|
||||||
dscene->prim_index.copy_to_device();
|
dscene->prim_index.copy_to_device();
|
||||||
}
|
}
|
||||||
if (pack.prim_object.size()) {
|
if (pack.prim_object.size() && (dscene->prim_object.need_realloc() || has_bvh2_layout)) {
|
||||||
dscene->prim_object.steal_data(pack.prim_object);
|
dscene->prim_object.steal_data(pack.prim_object);
|
||||||
dscene->prim_object.copy_to_device();
|
dscene->prim_object.copy_to_device();
|
||||||
}
|
}
|
||||||
if (pack.prim_time.size()) {
|
if (pack.prim_time.size() && (dscene->prim_time.need_realloc() || has_bvh2_layout)) {
|
||||||
dscene->prim_time.steal_data(pack.prim_time);
|
dscene->prim_time.steal_data(pack.prim_time);
|
||||||
dscene->prim_time.copy_to_device();
|
dscene->prim_time.copy_to_device();
|
||||||
}
|
}
|
||||||
@@ -1289,12 +1367,65 @@ void GeometryManager::device_update_bvh(Device *device,
|
|||||||
dscene->data.bvh.scene = NULL;
|
dscene->data.bvh.scene = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set of flags used to help determining what data has been modified or needs reallocation, so we
|
||||||
|
* can decide which device data to free or update. */
|
||||||
|
enum {
|
||||||
|
DEVICE_CURVE_DATA_MODIFIED = (1 << 0),
|
||||||
|
DEVICE_MESH_DATA_MODIFIED = (1 << 1),
|
||||||
|
|
||||||
|
ATTR_FLOAT_MODIFIED = (1 << 2),
|
||||||
|
ATTR_FLOAT2_MODIFIED = (1 << 3),
|
||||||
|
ATTR_FLOAT3_MODIFIED = (1 << 4),
|
||||||
|
ATTR_UCHAR4_MODIFIED = (1 << 5),
|
||||||
|
|
||||||
|
CURVE_DATA_NEED_REALLOC = (1 << 6),
|
||||||
|
MESH_DATA_NEED_REALLOC = (1 << 7),
|
||||||
|
|
||||||
|
ATTR_FLOAT_NEEDS_REALLOC = (1 << 8),
|
||||||
|
ATTR_FLOAT2_NEEDS_REALLOC = (1 << 9),
|
||||||
|
ATTR_FLOAT3_NEEDS_REALLOC = (1 << 10),
|
||||||
|
ATTR_UCHAR4_NEEDS_REALLOC = (1 << 11),
|
||||||
|
|
||||||
|
ATTRS_NEED_REALLOC = (ATTR_FLOAT_NEEDS_REALLOC | ATTR_FLOAT2_NEEDS_REALLOC |
|
||||||
|
ATTR_FLOAT3_NEEDS_REALLOC | ATTR_UCHAR4_NEEDS_REALLOC),
|
||||||
|
DEVICE_MESH_DATA_NEEDS_REALLOC = (CURVE_DATA_NEED_REALLOC | ATTRS_NEED_REALLOC),
|
||||||
|
DEVICE_CURVE_DATA_NEEDS_REALLOC = (MESH_DATA_NEED_REALLOC | ATTRS_NEED_REALLOC),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void update_device_flags_attribute(uint32_t &device_update_flags,
|
||||||
|
const AttributeSet &attributes)
|
||||||
|
{
|
||||||
|
foreach (const Attribute &attr, attributes.attributes) {
|
||||||
|
if (!attr.modified) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr.element == ATTR_ELEMENT_CORNER) {
|
||||||
|
device_update_flags |= ATTR_UCHAR4_MODIFIED;
|
||||||
|
}
|
||||||
|
else if (attr.type == TypeDesc::TypeFloat) {
|
||||||
|
device_update_flags |= ATTR_FLOAT_MODIFIED;
|
||||||
|
}
|
||||||
|
else if (attr.type == TypeFloat2) {
|
||||||
|
device_update_flags |= ATTR_FLOAT2_MODIFIED;
|
||||||
|
}
|
||||||
|
else if (attr.type == TypeDesc::TypeMatrix) {
|
||||||
|
device_update_flags |= ATTR_FLOAT3_MODIFIED;
|
||||||
|
}
|
||||||
|
else if (attr.element != ATTR_ELEMENT_VOXEL) {
|
||||||
|
device_update_flags |= ATTR_FLOAT3_MODIFIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress)
|
void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update && !need_flags_update) {
|
if (!need_update() && !need_flags_update) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t device_update_flags = 0;
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
scene->update_stats->geometry.times.add_entry({"device_update_preprocess", time});
|
scene->update_stats->geometry.times.add_entry({"device_update_preprocess", time});
|
||||||
@@ -1314,9 +1445,54 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
|
|||||||
if (shader->has_volume) {
|
if (shader->has_volume) {
|
||||||
geom->has_volume = true;
|
geom->has_volume = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader->has_surface_bssrdf) {
|
if (shader->has_surface_bssrdf) {
|
||||||
geom->has_surface_bssrdf = true;
|
geom->has_surface_bssrdf = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shader->need_update_uvs) {
|
||||||
|
device_update_flags |= ATTR_FLOAT2_NEEDS_REALLOC;
|
||||||
|
|
||||||
|
/* Attributes might need to be tesselated if added. */
|
||||||
|
if (geom->is_mesh()) {
|
||||||
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||||
|
if (mesh->need_tesselation()) {
|
||||||
|
mesh->tag_modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader->need_update_attribute) {
|
||||||
|
device_update_flags |= ATTRS_NEED_REALLOC;
|
||||||
|
|
||||||
|
/* Attributes might need to be tesselated if added. */
|
||||||
|
if (geom->is_mesh()) {
|
||||||
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||||
|
if (mesh->need_tesselation()) {
|
||||||
|
mesh->tag_modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader->need_update_displacement) {
|
||||||
|
/* tag displacement related sockets as modified */
|
||||||
|
if (geom->is_mesh()) {
|
||||||
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||||
|
mesh->tag_verts_modified();
|
||||||
|
mesh->tag_subd_dicing_rate_modified();
|
||||||
|
mesh->tag_subd_max_level_modified();
|
||||||
|
mesh->tag_subd_objecttoworld_modified();
|
||||||
|
|
||||||
|
device_update_flags |= ATTRS_NEED_REALLOC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* only check for modified attributes if we do not need to reallocate them already */
|
||||||
|
if ((device_update_flags & ATTRS_NEED_REALLOC) == 0) {
|
||||||
|
update_device_flags_attribute(device_update_flags, geom->attributes);
|
||||||
|
/* don't check for subd_attributes, as if they were modified, we would need to reallocate
|
||||||
|
* anyway */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Re-create volume mesh if we will rebuild or refit the BVH. Note we
|
/* Re-create volume mesh if we will rebuild or refit the BVH. Note we
|
||||||
@@ -1332,13 +1508,119 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
|
|||||||
|
|
||||||
Volume *volume = static_cast<Volume *>(geom);
|
Volume *volume = static_cast<Volume *>(geom);
|
||||||
create_volume_mesh(volume, progress);
|
create_volume_mesh(volume, progress);
|
||||||
|
|
||||||
|
/* always reallocate when we have a volume, as we need to rebuild the BVH */
|
||||||
|
device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geom->is_hair()) {
|
if (geom->is_hair()) {
|
||||||
/* Set curve shape, still a global scene setting for now. */
|
/* Set curve shape, still a global scene setting for now. */
|
||||||
Hair *hair = static_cast<Hair *>(geom);
|
Hair *hair = static_cast<Hair *>(geom);
|
||||||
hair->curve_shape = scene->params.hair_shape;
|
hair->curve_shape = scene->params.hair_shape;
|
||||||
|
|
||||||
|
if (hair->need_update_rebuild) {
|
||||||
|
device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
|
||||||
|
}
|
||||||
|
else if (hair->is_modified()) {
|
||||||
|
device_update_flags |= DEVICE_CURVE_DATA_MODIFIED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (geom->is_mesh()) {
|
||||||
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||||
|
|
||||||
|
if (mesh->need_update_rebuild) {
|
||||||
|
device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
|
||||||
|
}
|
||||||
|
else if (mesh->is_modified()) {
|
||||||
|
device_update_flags |= DEVICE_MESH_DATA_MODIFIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_flags & (MESH_ADDED | MESH_REMOVED)) {
|
||||||
|
device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_flags & (HAIR_ADDED | HAIR_REMOVED)) {
|
||||||
|
device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tag the device arrays for reallocation or modification */
|
||||||
|
DeviceScene *dscene = &scene->dscene;
|
||||||
|
|
||||||
|
if (device_update_flags & (DEVICE_MESH_DATA_NEEDS_REALLOC | DEVICE_CURVE_DATA_NEEDS_REALLOC)) {
|
||||||
|
delete scene->bvh;
|
||||||
|
scene->bvh = nullptr;
|
||||||
|
|
||||||
|
dscene->bvh_nodes.tag_realloc();
|
||||||
|
dscene->bvh_leaf_nodes.tag_realloc();
|
||||||
|
dscene->object_node.tag_realloc();
|
||||||
|
dscene->prim_tri_verts.tag_realloc();
|
||||||
|
dscene->prim_tri_index.tag_realloc();
|
||||||
|
dscene->prim_type.tag_realloc();
|
||||||
|
dscene->prim_visibility.tag_realloc();
|
||||||
|
dscene->prim_index.tag_realloc();
|
||||||
|
dscene->prim_object.tag_realloc();
|
||||||
|
dscene->prim_time.tag_realloc();
|
||||||
|
|
||||||
|
if (device_update_flags & DEVICE_MESH_DATA_NEEDS_REALLOC) {
|
||||||
|
dscene->tri_vnormal.tag_realloc();
|
||||||
|
dscene->tri_vindex.tag_realloc();
|
||||||
|
dscene->tri_patch.tag_realloc();
|
||||||
|
dscene->tri_vnormal.tag_realloc();
|
||||||
|
dscene->tri_patch_uv.tag_realloc();
|
||||||
|
dscene->patches.tag_realloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_update_flags & DEVICE_CURVE_DATA_NEEDS_REALLOC) {
|
||||||
|
dscene->curves.tag_realloc();
|
||||||
|
dscene->curve_keys.tag_realloc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_update_flags & ATTR_FLOAT_NEEDS_REALLOC) {
|
||||||
|
dscene->attributes_map.tag_realloc();
|
||||||
|
dscene->attributes_float.tag_realloc();
|
||||||
|
}
|
||||||
|
else if (device_update_flags & ATTR_FLOAT_MODIFIED) {
|
||||||
|
dscene->attributes_float.tag_modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_update_flags & ATTR_FLOAT2_NEEDS_REALLOC) {
|
||||||
|
dscene->attributes_map.tag_realloc();
|
||||||
|
dscene->attributes_float2.tag_realloc();
|
||||||
|
}
|
||||||
|
else if (device_update_flags & ATTR_FLOAT_MODIFIED) {
|
||||||
|
dscene->attributes_float.tag_modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_update_flags & ATTR_FLOAT3_NEEDS_REALLOC) {
|
||||||
|
dscene->attributes_map.tag_realloc();
|
||||||
|
dscene->attributes_float3.tag_realloc();
|
||||||
|
}
|
||||||
|
else if (device_update_flags & ATTR_FLOAT_MODIFIED) {
|
||||||
|
dscene->attributes_float.tag_modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_update_flags & ATTR_UCHAR4_NEEDS_REALLOC) {
|
||||||
|
dscene->attributes_map.tag_realloc();
|
||||||
|
dscene->attributes_uchar4.tag_realloc();
|
||||||
|
}
|
||||||
|
else if (device_update_flags & ATTR_UCHAR4_MODIFIED) {
|
||||||
|
dscene->attributes_uchar4.tag_modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_update_flags & DEVICE_MESH_DATA_MODIFIED) {
|
||||||
|
/* if anything else than vertices or shaders are modified, we would need to reallocate, so
|
||||||
|
* these are the only arrays that can be updated */
|
||||||
|
dscene->tri_vnormal.tag_modified();
|
||||||
|
dscene->tri_shader.tag_modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_update_flags & DEVICE_CURVE_DATA_MODIFIED) {
|
||||||
|
dscene->curve_keys.tag_modified();
|
||||||
|
dscene->curves.tag_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
need_flags_update = false;
|
need_flags_update = false;
|
||||||
@@ -1423,7 +1705,7 @@ void GeometryManager::device_update(Device *device,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress &progress)
|
Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update)
|
if (!need_update())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VLOG(1) << "Total " << scene->geometry.size() << " meshes.";
|
VLOG(1) << "Total " << scene->geometry.size() << " meshes.";
|
||||||
@@ -1439,12 +1721,6 @@ void GeometryManager::device_update(Device *device,
|
|||||||
});
|
});
|
||||||
|
|
||||||
foreach (Geometry *geom, scene->geometry) {
|
foreach (Geometry *geom, scene->geometry) {
|
||||||
foreach (Node *node, geom->get_used_shaders()) {
|
|
||||||
Shader *shader = static_cast<Shader *>(node);
|
|
||||||
if (shader->need_update_geometry)
|
|
||||||
geom->tag_modified();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (geom->is_modified() &&
|
if (geom->is_modified() &&
|
||||||
(geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME)) {
|
(geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME)) {
|
||||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||||
@@ -1541,7 +1817,7 @@ void GeometryManager::device_update(Device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Device update. */
|
/* Device update. */
|
||||||
device_free(device, dscene);
|
device_free(device, dscene, false);
|
||||||
|
|
||||||
const BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
|
const BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
|
||||||
device->get_bvh_layout_mask());
|
device->get_bvh_layout_mask());
|
||||||
@@ -1614,7 +1890,7 @@ void GeometryManager::device_update(Device *device,
|
|||||||
{"device_update (displacement: attributes)", time});
|
{"device_update (displacement: attributes)", time});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
device_free(device, dscene);
|
device_free(device, dscene, false);
|
||||||
|
|
||||||
device_update_attributes(device, dscene, scene, progress);
|
device_update_attributes(device, dscene, scene, progress);
|
||||||
if (progress.get_cancel()) {
|
if (progress.get_cancel()) {
|
||||||
@@ -1622,6 +1898,9 @@ void GeometryManager::device_update(Device *device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* update the bvh even when there is no geometry so the kernel bvh data is still valid,
|
||||||
|
* especially when removing all of the objects during interactive renders */
|
||||||
|
bool need_update_scene_bvh = (scene->bvh == nullptr);
|
||||||
{
|
{
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
@@ -1633,6 +1912,7 @@ void GeometryManager::device_update(Device *device,
|
|||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
foreach (Geometry *geom, scene->geometry) {
|
foreach (Geometry *geom, scene->geometry) {
|
||||||
if (geom->is_modified()) {
|
if (geom->is_modified()) {
|
||||||
|
need_update_scene_bvh = true;
|
||||||
pool.push(function_bind(
|
pool.push(function_bind(
|
||||||
&Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh));
|
&Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh));
|
||||||
if (geom->need_build_bvh(bvh_layout)) {
|
if (geom->need_build_bvh(bvh_layout)) {
|
||||||
@@ -1647,7 +1927,9 @@ void GeometryManager::device_update(Device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach (Shader *shader, scene->shaders) {
|
foreach (Shader *shader, scene->shaders) {
|
||||||
shader->need_update_geometry = false;
|
shader->need_update_uvs = false;
|
||||||
|
shader->need_update_attribute = false;
|
||||||
|
shader->need_update_displacement = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::MotionType need_motion = scene->need_motion();
|
Scene::MotionType need_motion = scene->need_motion();
|
||||||
@@ -1670,7 +1952,7 @@ void GeometryManager::device_update(Device *device,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (need_update_scene_bvh) {
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
scene->update_stats->geometry.times.add_entry({"device_update (build scene BVH)", time});
|
scene->update_stats->geometry.times.add_entry({"device_update (build scene BVH)", time});
|
||||||
@@ -1695,8 +1977,6 @@ void GeometryManager::device_update(Device *device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
need_update = false;
|
|
||||||
|
|
||||||
if (true_displacement_used) {
|
if (true_displacement_used) {
|
||||||
/* Re-tag flags for update, so they're re-evaluated
|
/* Re-tag flags for update, so they're re-evaluated
|
||||||
* for meshes with correct bounding boxes.
|
* for meshes with correct bounding boxes.
|
||||||
@@ -1706,33 +1986,71 @@ void GeometryManager::device_update(Device *device,
|
|||||||
*/
|
*/
|
||||||
scene->object_manager->need_flags_update = old_need_object_flags_update;
|
scene->object_manager->need_flags_update = old_need_object_flags_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* unset flags */
|
||||||
|
|
||||||
|
foreach (Geometry *geom, scene->geometry) {
|
||||||
|
geom->clear_modified();
|
||||||
|
geom->attributes.clear_modified();
|
||||||
|
|
||||||
|
if (geom->is_mesh()) {
|
||||||
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||||
|
mesh->subd_attributes.clear_modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update_flags = UPDATE_NONE;
|
||||||
|
|
||||||
|
dscene->bvh_nodes.clear_modified();
|
||||||
|
dscene->bvh_leaf_nodes.clear_modified();
|
||||||
|
dscene->object_node.clear_modified();
|
||||||
|
dscene->prim_tri_verts.clear_modified();
|
||||||
|
dscene->prim_tri_index.clear_modified();
|
||||||
|
dscene->prim_type.clear_modified();
|
||||||
|
dscene->prim_visibility.clear_modified();
|
||||||
|
dscene->prim_index.clear_modified();
|
||||||
|
dscene->prim_object.clear_modified();
|
||||||
|
dscene->prim_time.clear_modified();
|
||||||
|
dscene->tri_shader.clear_modified();
|
||||||
|
dscene->tri_vindex.clear_modified();
|
||||||
|
dscene->tri_patch.clear_modified();
|
||||||
|
dscene->tri_vnormal.clear_modified();
|
||||||
|
dscene->tri_patch_uv.clear_modified();
|
||||||
|
dscene->curves.clear_modified();
|
||||||
|
dscene->curve_keys.clear_modified();
|
||||||
|
dscene->patches.clear_modified();
|
||||||
|
dscene->attributes_map.clear_modified();
|
||||||
|
dscene->attributes_float.clear_modified();
|
||||||
|
dscene->attributes_float2.clear_modified();
|
||||||
|
dscene->attributes_float3.clear_modified();
|
||||||
|
dscene->attributes_uchar4.clear_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryManager::device_free(Device *device, DeviceScene *dscene)
|
void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool force_free)
|
||||||
{
|
{
|
||||||
dscene->bvh_nodes.free();
|
dscene->bvh_nodes.free_if_need_realloc(force_free);
|
||||||
dscene->bvh_leaf_nodes.free();
|
dscene->bvh_leaf_nodes.free_if_need_realloc(force_free);
|
||||||
dscene->object_node.free();
|
dscene->object_node.free_if_need_realloc(force_free);
|
||||||
dscene->prim_tri_verts.free();
|
dscene->prim_tri_verts.free_if_need_realloc(force_free);
|
||||||
dscene->prim_tri_index.free();
|
dscene->prim_tri_index.free_if_need_realloc(force_free);
|
||||||
dscene->prim_type.free();
|
dscene->prim_type.free_if_need_realloc(force_free);
|
||||||
dscene->prim_visibility.free();
|
dscene->prim_visibility.free_if_need_realloc(force_free);
|
||||||
dscene->prim_index.free();
|
dscene->prim_index.free_if_need_realloc(force_free);
|
||||||
dscene->prim_object.free();
|
dscene->prim_object.free_if_need_realloc(force_free);
|
||||||
dscene->prim_time.free();
|
dscene->prim_time.free_if_need_realloc(force_free);
|
||||||
dscene->tri_shader.free();
|
dscene->tri_shader.free_if_need_realloc(force_free);
|
||||||
dscene->tri_vnormal.free();
|
dscene->tri_vnormal.free_if_need_realloc(force_free);
|
||||||
dscene->tri_vindex.free();
|
dscene->tri_vindex.free_if_need_realloc(force_free);
|
||||||
dscene->tri_patch.free();
|
dscene->tri_patch.free_if_need_realloc(force_free);
|
||||||
dscene->tri_patch_uv.free();
|
dscene->tri_patch_uv.free_if_need_realloc(force_free);
|
||||||
dscene->curves.free();
|
dscene->curves.free_if_need_realloc(force_free);
|
||||||
dscene->curve_keys.free();
|
dscene->curve_keys.free_if_need_realloc(force_free);
|
||||||
dscene->patches.free();
|
dscene->patches.free_if_need_realloc(force_free);
|
||||||
dscene->attributes_map.free();
|
dscene->attributes_map.free_if_need_realloc(force_free);
|
||||||
dscene->attributes_float.free();
|
dscene->attributes_float.free_if_need_realloc(force_free);
|
||||||
dscene->attributes_float2.free();
|
dscene->attributes_float2.free_if_need_realloc(force_free);
|
||||||
dscene->attributes_float3.free();
|
dscene->attributes_float3.free_if_need_realloc(force_free);
|
||||||
dscene->attributes_uchar4.free();
|
dscene->attributes_uchar4.free_if_need_realloc(force_free);
|
||||||
|
|
||||||
/* Signal for shaders like displacement not to do ray tracing. */
|
/* Signal for shaders like displacement not to do ray tracing. */
|
||||||
dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE;
|
dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE;
|
||||||
@@ -1750,10 +2068,19 @@ void GeometryManager::device_free(Device *device, DeviceScene *dscene)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryManager::tag_update(Scene *scene)
|
void GeometryManager::tag_update(Scene *scene, uint32_t flag)
|
||||||
{
|
{
|
||||||
need_update = true;
|
update_flags |= flag;
|
||||||
scene->object_manager->need_update = true;
|
|
||||||
|
/* do not tag the object manager for an update if it is the one who tagged us */
|
||||||
|
if ((flag & OBJECT_MANAGER) == 0) {
|
||||||
|
scene->object_manager->tag_update(scene, ObjectManager::GEOMETRY_MANAGER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GeometryManager::need_update() const
|
||||||
|
{
|
||||||
|
return update_flags != UPDATE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryManager::collect_statistics(const Scene *scene, RenderStats *stats)
|
void GeometryManager::collect_statistics(const Scene *scene, RenderStats *stats)
|
||||||
|
@@ -125,7 +125,7 @@ class Geometry : public Node {
|
|||||||
int n,
|
int n,
|
||||||
int total);
|
int total);
|
||||||
|
|
||||||
virtual void pack_primitives(PackedBVH &pack, int object, uint visibility) = 0;
|
virtual void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) = 0;
|
||||||
|
|
||||||
/* Check whether the geometry should have own BVH built separately. Briefly,
|
/* Check whether the geometry should have own BVH built separately. Briefly,
|
||||||
* own BVH is needed for geometry, if:
|
* own BVH is needed for geometry, if:
|
||||||
@@ -155,6 +155,11 @@ class Geometry : public Node {
|
|||||||
return geometry_type == HAIR;
|
return geometry_type == HAIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_volume() const
|
||||||
|
{
|
||||||
|
return geometry_type == VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
/* Updates */
|
/* Updates */
|
||||||
void tag_update(Scene *scene, bool rebuild);
|
void tag_update(Scene *scene, bool rebuild);
|
||||||
|
|
||||||
@@ -164,9 +169,32 @@ class Geometry : public Node {
|
|||||||
/* Geometry Manager */
|
/* Geometry Manager */
|
||||||
|
|
||||||
class GeometryManager {
|
class GeometryManager {
|
||||||
|
uint32_t update_flags;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum : uint32_t {
|
||||||
|
UV_PASS_NEEDED = (1 << 0),
|
||||||
|
MOTION_PASS_NEEDED = (1 << 1),
|
||||||
|
GEOMETRY_MODIFIED = (1 << 2),
|
||||||
|
OBJECT_MANAGER = (1 << 3),
|
||||||
|
MESH_ADDED = (1 << 4),
|
||||||
|
MESH_REMOVED = (1 << 5),
|
||||||
|
HAIR_ADDED = (1 << 6),
|
||||||
|
HAIR_REMOVED = (1 << 7),
|
||||||
|
|
||||||
|
SHADER_ATTRIBUTE_MODIFIED = (1 << 8),
|
||||||
|
SHADER_DISPLACEMENT_MODIFIED = (1 << 9),
|
||||||
|
|
||||||
|
GEOMETRY_ADDED = MESH_ADDED | HAIR_ADDED,
|
||||||
|
GEOMETRY_REMOVED = MESH_REMOVED | HAIR_REMOVED,
|
||||||
|
|
||||||
|
/* tag everything in the manager for an update */
|
||||||
|
UPDATE_ALL = ~0u,
|
||||||
|
|
||||||
|
UPDATE_NONE = 0u,
|
||||||
|
};
|
||||||
|
|
||||||
/* Update Flags */
|
/* Update Flags */
|
||||||
bool need_update;
|
|
||||||
bool need_flags_update;
|
bool need_flags_update;
|
||||||
|
|
||||||
/* Constructor/Destructor */
|
/* Constructor/Destructor */
|
||||||
@@ -176,10 +204,12 @@ class GeometryManager {
|
|||||||
/* Device Updates */
|
/* Device Updates */
|
||||||
void device_update_preprocess(Device *device, Scene *scene, Progress &progress);
|
void device_update_preprocess(Device *device, Scene *scene, Progress &progress);
|
||||||
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
|
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
|
||||||
void device_free(Device *device, DeviceScene *dscene);
|
void device_free(Device *device, DeviceScene *dscene, bool force_free);
|
||||||
|
|
||||||
/* Updates */
|
/* Updates */
|
||||||
void tag_update(Scene *scene);
|
void tag_update(Scene *scene, uint32_t flag);
|
||||||
|
|
||||||
|
bool need_update() const;
|
||||||
|
|
||||||
/* Statistics */
|
/* Statistics */
|
||||||
void collect_statistics(const Scene *scene, RenderStats *stats);
|
void collect_statistics(const Scene *scene, RenderStats *stats);
|
||||||
|
@@ -494,33 +494,38 @@ void Hair::pack_curves(Scene *scene,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hair::pack_primitives(PackedBVH &pack, int object, uint visibility)
|
void Hair::pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all)
|
||||||
{
|
{
|
||||||
if (curve_first_key.empty())
|
if (curve_first_key.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const size_t num_prims = num_segments();
|
/* If the BVH does not have to be recreated, we can bail out. */
|
||||||
pack.prim_tri_index.reserve(pack.prim_tri_index.size() + num_prims);
|
if (!pack_all) {
|
||||||
pack.prim_type.reserve(pack.prim_type.size() + num_prims);
|
return;
|
||||||
pack.prim_visibility.reserve(pack.prim_visibility.size() + num_prims);
|
}
|
||||||
pack.prim_index.reserve(pack.prim_index.size() + num_prims);
|
|
||||||
pack.prim_object.reserve(pack.prim_object.size() + num_prims);
|
unsigned int *prim_tri_index = &pack->prim_tri_index[optix_prim_offset];
|
||||||
// 'pack.prim_time' is unused by Embree and OptiX
|
int *prim_type = &pack->prim_type[optix_prim_offset];
|
||||||
|
unsigned int *prim_visibility = &pack->prim_visibility[optix_prim_offset];
|
||||||
|
int *prim_index = &pack->prim_index[optix_prim_offset];
|
||||||
|
int *prim_object = &pack->prim_object[optix_prim_offset];
|
||||||
|
// 'pack->prim_time' is unused by Embree and OptiX
|
||||||
|
|
||||||
uint type = has_motion_blur() ?
|
uint type = has_motion_blur() ?
|
||||||
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON :
|
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON :
|
||||||
PRIMITIVE_MOTION_CURVE_THICK) :
|
PRIMITIVE_MOTION_CURVE_THICK) :
|
||||||
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : PRIMITIVE_CURVE_THICK);
|
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : PRIMITIVE_CURVE_THICK);
|
||||||
|
|
||||||
|
size_t index = 0;
|
||||||
for (size_t j = 0; j < num_curves(); ++j) {
|
for (size_t j = 0; j < num_curves(); ++j) {
|
||||||
Curve curve = get_curve(j);
|
Curve curve = get_curve(j);
|
||||||
for (size_t k = 0; k < curve.num_segments(); ++k) {
|
for (size_t k = 0; k < curve.num_segments(); ++k, ++index) {
|
||||||
pack.prim_tri_index.push_back_reserved(-1);
|
prim_tri_index[index] = -1;
|
||||||
pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(type, k));
|
prim_type[index] = PRIMITIVE_PACK_SEGMENT(type, k);
|
||||||
pack.prim_visibility.push_back_reserved(visibility);
|
prim_visibility[index] = visibility;
|
||||||
// Each curve segment points back to its curve index
|
// Each curve segment points back to its curve index
|
||||||
pack.prim_index.push_back_reserved(j + prim_offset);
|
prim_index[index] = j + prim_offset;
|
||||||
pack.prim_object.push_back_reserved(object);
|
prim_object[index] = object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -146,7 +146,7 @@ class Hair : public Geometry {
|
|||||||
/* BVH */
|
/* BVH */
|
||||||
void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
|
void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
|
||||||
|
|
||||||
void pack_primitives(PackedBVH &pack, int object, uint visibility) override;
|
void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -298,7 +298,7 @@ bool ImageLoader::is_vdb_loader() const
|
|||||||
|
|
||||||
ImageManager::ImageManager(const DeviceInfo &info)
|
ImageManager::ImageManager(const DeviceInfo &info)
|
||||||
{
|
{
|
||||||
need_update = true;
|
need_update_ = true;
|
||||||
osl_texture_system = NULL;
|
osl_texture_system = NULL;
|
||||||
animation_frame = 0;
|
animation_frame = 0;
|
||||||
|
|
||||||
@@ -451,7 +451,7 @@ int ImageManager::add_image_slot(ImageLoader *loader,
|
|||||||
|
|
||||||
images[slot] = img;
|
images[slot] = img;
|
||||||
|
|
||||||
need_update = true;
|
need_update_ = true;
|
||||||
|
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
@@ -478,7 +478,7 @@ void ImageManager::remove_image_user(int slot)
|
|||||||
* the reasons for this is that on shader changes we add and remove nodes
|
* the reasons for this is that on shader changes we add and remove nodes
|
||||||
* that use them, but we do not want to reload the image all the time. */
|
* that use them, but we do not want to reload the image all the time. */
|
||||||
if (image->users == 0)
|
if (image->users == 0)
|
||||||
need_update = true;
|
need_update_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool image_associate_alpha(ImageManager::Image *img)
|
static bool image_associate_alpha(ImageManager::Image *img)
|
||||||
@@ -810,7 +810,7 @@ void ImageManager::device_free_image(Device *, int slot)
|
|||||||
|
|
||||||
void ImageManager::device_update(Device *device, Scene *scene, Progress &progress)
|
void ImageManager::device_update(Device *device, Scene *scene, Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update) {
|
if (!need_update()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -834,7 +834,7 @@ void ImageManager::device_update(Device *device, Scene *scene, Progress &progres
|
|||||||
|
|
||||||
pool.wait_work();
|
pool.wait_work();
|
||||||
|
|
||||||
need_update = false;
|
need_update_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageManager::device_update_slot(Device *device, Scene *scene, int slot, Progress *progress)
|
void ImageManager::device_update_slot(Device *device, Scene *scene, int slot, Progress *progress)
|
||||||
@@ -854,7 +854,7 @@ void ImageManager::device_load_builtin(Device *device, Scene *scene, Progress &p
|
|||||||
{
|
{
|
||||||
/* Load only builtin images, Blender needs this to load evaluated
|
/* Load only builtin images, Blender needs this to load evaluated
|
||||||
* scene data from depsgraph before it is freed. */
|
* scene data from depsgraph before it is freed. */
|
||||||
if (!need_update) {
|
if (!need_update()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -896,4 +896,14 @@ void ImageManager::collect_statistics(RenderStats *stats)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageManager::tag_update()
|
||||||
|
{
|
||||||
|
need_update_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageManager::need_update() const
|
||||||
|
{
|
||||||
|
return need_update_;
|
||||||
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -189,7 +189,9 @@ class ImageManager {
|
|||||||
|
|
||||||
void collect_statistics(RenderStats *stats);
|
void collect_statistics(RenderStats *stats);
|
||||||
|
|
||||||
bool need_update;
|
void tag_update();
|
||||||
|
|
||||||
|
bool need_update() const;
|
||||||
|
|
||||||
struct Image {
|
struct Image {
|
||||||
ImageParams params;
|
ImageParams params;
|
||||||
@@ -209,6 +211,7 @@ class ImageManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool need_update_;
|
||||||
bool has_half_images;
|
bool has_half_images;
|
||||||
|
|
||||||
thread_mutex device_mutex;
|
thread_mutex device_mutex;
|
||||||
|
@@ -17,9 +17,11 @@
|
|||||||
#include "render/integrator.h"
|
#include "render/integrator.h"
|
||||||
#include "device/device.h"
|
#include "device/device.h"
|
||||||
#include "render/background.h"
|
#include "render/background.h"
|
||||||
|
#include "render/camera.h"
|
||||||
#include "render/film.h"
|
#include "render/film.h"
|
||||||
#include "render/jitter.h"
|
#include "render/jitter.h"
|
||||||
#include "render/light.h"
|
#include "render/light.h"
|
||||||
|
#include "render/object.h"
|
||||||
#include "render/scene.h"
|
#include "render/scene.h"
|
||||||
#include "render/shader.h"
|
#include "render/shader.h"
|
||||||
#include "render/sobol.h"
|
#include "render/sobol.h"
|
||||||
@@ -113,6 +115,18 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const bool need_update_lut = ao_samples_is_modified() || diffuse_samples_is_modified() ||
|
||||||
|
glossy_samples_is_modified() || max_bounce_is_modified() ||
|
||||||
|
max_transmission_bounce_is_modified() ||
|
||||||
|
mesh_light_samples_is_modified() || method_is_modified() ||
|
||||||
|
sampling_pattern_is_modified() ||
|
||||||
|
subsurface_samples_is_modified() ||
|
||||||
|
transmission_samples_is_modified() || volume_samples_is_modified();
|
||||||
|
|
||||||
|
if (need_update_lut) {
|
||||||
|
dscene->sample_pattern_lut.tag_realloc();
|
||||||
|
}
|
||||||
|
|
||||||
device_free(device, dscene);
|
device_free(device, dscene);
|
||||||
|
|
||||||
KernelIntegrator *kintegrator = &dscene->data.integrator;
|
KernelIntegrator *kintegrator = &dscene->data.integrator;
|
||||||
@@ -168,7 +182,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||||||
FLT_MAX :
|
FLT_MAX :
|
||||||
sample_clamp_indirect * 3.0f;
|
sample_clamp_indirect * 3.0f;
|
||||||
|
|
||||||
kintegrator->branched = (method == BRANCHED_PATH);
|
kintegrator->branched = (method == BRANCHED_PATH) && device->info.has_branched_path;
|
||||||
kintegrator->volume_decoupled = device->info.has_volume_decoupled;
|
kintegrator->volume_decoupled = device->info.has_volume_decoupled;
|
||||||
kintegrator->diffuse_samples = diffuse_samples;
|
kintegrator->diffuse_samples = diffuse_samples;
|
||||||
kintegrator->glossy_samples = glossy_samples;
|
kintegrator->glossy_samples = glossy_samples;
|
||||||
@@ -179,7 +193,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||||||
kintegrator->volume_samples = volume_samples;
|
kintegrator->volume_samples = volume_samples;
|
||||||
kintegrator->start_sample = start_sample;
|
kintegrator->start_sample = start_sample;
|
||||||
|
|
||||||
if (method == BRANCHED_PATH) {
|
if (kintegrator->branched) {
|
||||||
kintegrator->sample_all_lights_direct = sample_all_lights_direct;
|
kintegrator->sample_all_lights_direct = sample_all_lights_direct;
|
||||||
kintegrator->sample_all_lights_indirect = sample_all_lights_indirect;
|
kintegrator->sample_all_lights_indirect = sample_all_lights_indirect;
|
||||||
}
|
}
|
||||||
@@ -224,7 +238,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||||||
/* sobol directions table */
|
/* sobol directions table */
|
||||||
int max_samples = 1;
|
int max_samples = 1;
|
||||||
|
|
||||||
if (method == BRANCHED_PATH) {
|
if (kintegrator->branched) {
|
||||||
foreach (Light *light, scene->lights)
|
foreach (Light *light, scene->lights)
|
||||||
max_samples = max(max_samples, light->get_samples());
|
max_samples = max(max_samples, light->get_samples());
|
||||||
|
|
||||||
@@ -242,45 +256,69 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||||||
int dimensions = PRNG_BASE_NUM + max_samples * PRNG_BOUNCE_NUM;
|
int dimensions = PRNG_BASE_NUM + max_samples * PRNG_BOUNCE_NUM;
|
||||||
dimensions = min(dimensions, SOBOL_MAX_DIMENSIONS);
|
dimensions = min(dimensions, SOBOL_MAX_DIMENSIONS);
|
||||||
|
|
||||||
if (sampling_pattern == SAMPLING_PATTERN_SOBOL) {
|
if (need_update_lut) {
|
||||||
uint *directions = dscene->sample_pattern_lut.alloc(SOBOL_BITS * dimensions);
|
if (sampling_pattern == SAMPLING_PATTERN_SOBOL) {
|
||||||
|
uint *directions = dscene->sample_pattern_lut.alloc(SOBOL_BITS * dimensions);
|
||||||
|
|
||||||
sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
|
sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
|
||||||
|
|
||||||
dscene->sample_pattern_lut.copy_to_device();
|
dscene->sample_pattern_lut.copy_to_device();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
constexpr int sequence_size = NUM_PMJ_SAMPLES;
|
constexpr int sequence_size = NUM_PMJ_SAMPLES;
|
||||||
constexpr int num_sequences = NUM_PMJ_PATTERNS;
|
constexpr int num_sequences = NUM_PMJ_PATTERNS;
|
||||||
float2 *directions = (float2 *)dscene->sample_pattern_lut.alloc(sequence_size * num_sequences *
|
float2 *directions = (float2 *)dscene->sample_pattern_lut.alloc(sequence_size *
|
||||||
2);
|
num_sequences * 2);
|
||||||
TaskPool pool;
|
TaskPool pool;
|
||||||
for (int j = 0; j < num_sequences; ++j) {
|
for (int j = 0; j < num_sequences; ++j) {
|
||||||
float2 *sequence = directions + j * sequence_size;
|
float2 *sequence = directions + j * sequence_size;
|
||||||
pool.push(
|
pool.push(
|
||||||
function_bind(&progressive_multi_jitter_02_generate_2D, sequence, sequence_size, j));
|
function_bind(&progressive_multi_jitter_02_generate_2D, sequence, sequence_size, j));
|
||||||
|
}
|
||||||
|
pool.wait_work();
|
||||||
|
dscene->sample_pattern_lut.copy_to_device();
|
||||||
}
|
}
|
||||||
pool.wait_work();
|
|
||||||
dscene->sample_pattern_lut.copy_to_device();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dscene->sample_pattern_lut.clear_modified();
|
||||||
clear_modified();
|
clear_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Integrator::device_free(Device *, DeviceScene *dscene)
|
void Integrator::device_free(Device *, DeviceScene *dscene, bool force_free)
|
||||||
{
|
{
|
||||||
dscene->sample_pattern_lut.free();
|
dscene->sample_pattern_lut.free_if_need_realloc(force_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Integrator::tag_update(Scene *scene)
|
void Integrator::tag_update(Scene *scene, uint32_t flag)
|
||||||
{
|
{
|
||||||
foreach (Shader *shader, scene->shaders) {
|
if (flag & UPDATE_ALL) {
|
||||||
if (shader->has_integrator_dependency) {
|
tag_modified();
|
||||||
scene->shader_manager->need_update = true;
|
}
|
||||||
break;
|
|
||||||
|
if (flag & (AO_PASS_MODIFIED | BACKGROUND_AO_MODIFIED)) {
|
||||||
|
/* tag only the ao_bounces socket as modified so we avoid updating sample_pattern_lut
|
||||||
|
* unnecessarily */
|
||||||
|
tag_ao_bounces_modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flag & LIGHT_SAMPLES_MODIFIED) && (method == BRANCHED_PATH)) {
|
||||||
|
/* the number of light samples may affect the size of the sample_pattern_lut */
|
||||||
|
tag_sampling_pattern_modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_glossy_is_modified()) {
|
||||||
|
foreach (Shader *shader, scene->shaders) {
|
||||||
|
if (shader->has_integrator_dependency) {
|
||||||
|
scene->shader_manager->tag_update(scene, ShaderManager::INTEGRATOR_MODIFIED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tag_modified();
|
|
||||||
|
if (motion_blur_is_modified()) {
|
||||||
|
scene->object_manager->tag_update(scene, ObjectManager::MOTION_BLUR_MODIFIED);
|
||||||
|
scene->camera->tag_modified();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -89,13 +89,24 @@ class Integrator : public Node {
|
|||||||
|
|
||||||
NODE_SOCKET_API(SamplingPattern, sampling_pattern)
|
NODE_SOCKET_API(SamplingPattern, sampling_pattern)
|
||||||
|
|
||||||
|
enum : uint32_t {
|
||||||
|
AO_PASS_MODIFIED = (1 << 0),
|
||||||
|
BACKGROUND_AO_MODIFIED = (1 << 1),
|
||||||
|
LIGHT_SAMPLES_MODIFIED = (1 << 2),
|
||||||
|
|
||||||
|
/* tag everything in the manager for an update */
|
||||||
|
UPDATE_ALL = ~0u,
|
||||||
|
|
||||||
|
UPDATE_NONE = 0u,
|
||||||
|
};
|
||||||
|
|
||||||
Integrator();
|
Integrator();
|
||||||
~Integrator();
|
~Integrator();
|
||||||
|
|
||||||
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
|
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
|
||||||
void device_free(Device *device, DeviceScene *dscene);
|
void device_free(Device *device, DeviceScene *dscene, bool force_free = false);
|
||||||
|
|
||||||
void tag_update(Scene *scene);
|
void tag_update(Scene *scene, uint32_t flag);
|
||||||
};
|
};
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -162,7 +162,13 @@ Light::Light() : Node(node_type)
|
|||||||
|
|
||||||
void Light::tag_update(Scene *scene)
|
void Light::tag_update(Scene *scene)
|
||||||
{
|
{
|
||||||
scene->light_manager->need_update = is_modified();
|
if (is_modified()) {
|
||||||
|
scene->light_manager->tag_update(scene, LightManager::LIGHT_MODIFIED);
|
||||||
|
|
||||||
|
if (samples_is_modified()) {
|
||||||
|
scene->integrator->tag_update(scene, Integrator::LIGHT_SAMPLES_MODIFIED);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Light::has_contribution(Scene *scene)
|
bool Light::has_contribution(Scene *scene)
|
||||||
@@ -183,7 +189,7 @@ bool Light::has_contribution(Scene *scene)
|
|||||||
|
|
||||||
LightManager::LightManager()
|
LightManager::LightManager()
|
||||||
{
|
{
|
||||||
need_update = true;
|
update_flags = UPDATE_ALL;
|
||||||
need_update_background = true;
|
need_update_background = true;
|
||||||
use_light_visibility = false;
|
use_light_visibility = false;
|
||||||
last_background_enabled = false;
|
last_background_enabled = false;
|
||||||
@@ -962,7 +968,7 @@ void LightManager::device_update(Device *device,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress &progress)
|
Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update)
|
if (!need_update())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
@@ -1000,7 +1006,7 @@ void LightManager::device_update(Device *device,
|
|||||||
|
|
||||||
scene->film->set_use_light_visibility(use_light_visibility);
|
scene->film->set_use_light_visibility(use_light_visibility);
|
||||||
|
|
||||||
need_update = false;
|
update_flags = UPDATE_NONE;
|
||||||
need_update_background = false;
|
need_update_background = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1015,9 +1021,14 @@ void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_ba
|
|||||||
dscene->ies_lights.free();
|
dscene->ies_lights.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightManager::tag_update(Scene * /*scene*/)
|
void LightManager::tag_update(Scene * /*scene*/, uint32_t flag)
|
||||||
{
|
{
|
||||||
need_update = true;
|
update_flags |= flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LightManager::need_update() const
|
||||||
|
{
|
||||||
|
return update_flags != UPDATE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LightManager::add_ies_from_file(const string &filename)
|
int LightManager::add_ies_from_file(const string &filename)
|
||||||
@@ -1063,7 +1074,7 @@ int LightManager::add_ies(const string &content)
|
|||||||
ies_slots[slot]->users = 1;
|
ies_slots[slot]->users = 1;
|
||||||
ies_slots[slot]->hash = hash;
|
ies_slots[slot]->hash = hash;
|
||||||
|
|
||||||
need_update = true;
|
update_flags = UPDATE_ALL;
|
||||||
need_update_background = true;
|
need_update_background = true;
|
||||||
|
|
||||||
return slot;
|
return slot;
|
||||||
@@ -1082,8 +1093,10 @@ void LightManager::remove_ies(int slot)
|
|||||||
ies_slots[slot]->users--;
|
ies_slots[slot]->users--;
|
||||||
|
|
||||||
/* If the slot has no more users, update the device to remove it. */
|
/* If the slot has no more users, update the device to remove it. */
|
||||||
need_update |= (ies_slots[slot]->users == 0);
|
if (ies_slots[slot]->users == 0) {
|
||||||
need_update_background |= need_update;
|
update_flags |= UPDATE_ALL;
|
||||||
|
need_update_background = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightManager::device_update_ies(DeviceScene *dscene)
|
void LightManager::device_update_ies(DeviceScene *dscene)
|
||||||
|
@@ -91,8 +91,23 @@ class Light : public Node {
|
|||||||
|
|
||||||
class LightManager {
|
class LightManager {
|
||||||
public:
|
public:
|
||||||
|
enum : uint32_t {
|
||||||
|
MESH_NEED_REBUILD = (1 << 0),
|
||||||
|
EMISSIVE_MESH_MODIFIED = (1 << 1),
|
||||||
|
LIGHT_MODIFIED = (1 << 2),
|
||||||
|
LIGHT_ADDED = (1 << 3),
|
||||||
|
LIGHT_REMOVED = (1 << 4),
|
||||||
|
OBJECT_MANAGER = (1 << 5),
|
||||||
|
SHADER_COMPILED = (1 << 6),
|
||||||
|
SHADER_MODIFIED = (1 << 7),
|
||||||
|
|
||||||
|
/* tag everything in the manager for an update */
|
||||||
|
UPDATE_ALL = ~0u,
|
||||||
|
|
||||||
|
UPDATE_NONE = 0u,
|
||||||
|
};
|
||||||
|
|
||||||
bool use_light_visibility;
|
bool use_light_visibility;
|
||||||
bool need_update;
|
|
||||||
|
|
||||||
/* Need to update background (including multiple importance map) */
|
/* Need to update background (including multiple importance map) */
|
||||||
bool need_update_background;
|
bool need_update_background;
|
||||||
@@ -108,7 +123,9 @@ class LightManager {
|
|||||||
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
|
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
|
||||||
void device_free(Device *device, DeviceScene *dscene, const bool free_background = true);
|
void device_free(Device *device, DeviceScene *dscene, const bool free_background = true);
|
||||||
|
|
||||||
void tag_update(Scene *scene);
|
void tag_update(Scene *scene, uint32_t flag);
|
||||||
|
|
||||||
|
bool need_update() const;
|
||||||
|
|
||||||
/* Check whether there is a background light. */
|
/* Check whether there is a background light. */
|
||||||
bool has_background_light(Scene *scene);
|
bool has_background_light(Scene *scene);
|
||||||
@@ -145,6 +162,8 @@ class LightManager {
|
|||||||
|
|
||||||
bool last_background_enabled;
|
bool last_background_enabled;
|
||||||
int last_background_resolution;
|
int last_background_resolution;
|
||||||
|
|
||||||
|
uint32_t update_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -805,34 +805,42 @@ void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, ui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::pack_primitives(PackedBVH &pack, int object, uint visibility)
|
void Mesh::pack_primitives(ccl::PackedBVH *pack, int object, uint visibility, bool pack_all)
|
||||||
{
|
{
|
||||||
if (triangles.empty())
|
if (triangles.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const size_t num_prims = num_triangles();
|
const size_t num_prims = num_triangles();
|
||||||
pack.prim_tri_index.reserve(pack.prim_tri_index.size() + num_prims);
|
|
||||||
pack.prim_tri_verts.reserve(pack.prim_tri_verts.size() + num_prims * 3);
|
/* Use prim_offset for indexing as it is computed per geometry type, and prim_tri_verts does not
|
||||||
pack.prim_type.reserve(pack.prim_type.size() + num_prims);
|
* contain data for Hair geometries. */
|
||||||
pack.prim_visibility.reserve(pack.prim_visibility.size() + num_prims);
|
float4 *prim_tri_verts = &pack->prim_tri_verts[prim_offset * 3];
|
||||||
pack.prim_index.reserve(pack.prim_index.size() + num_prims);
|
// 'pack->prim_time' is unused by Embree and OptiX
|
||||||
pack.prim_object.reserve(pack.prim_object.size() + num_prims);
|
|
||||||
// 'pack.prim_time' is unused by Embree and OptiX
|
|
||||||
|
|
||||||
uint type = has_motion_blur() ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE;
|
uint type = has_motion_blur() ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE;
|
||||||
|
|
||||||
|
if (pack_all) {
|
||||||
|
/* Use optix_prim_offset for indexing as those arrays also contain data for Hair geometries. */
|
||||||
|
unsigned int *prim_tri_index = &pack->prim_tri_index[optix_prim_offset];
|
||||||
|
int *prim_type = &pack->prim_type[optix_prim_offset];
|
||||||
|
unsigned int *prim_visibility = &pack->prim_visibility[optix_prim_offset];
|
||||||
|
int *prim_index = &pack->prim_index[optix_prim_offset];
|
||||||
|
int *prim_object = &pack->prim_object[optix_prim_offset];
|
||||||
|
|
||||||
|
for (size_t k = 0; k < num_prims; ++k) {
|
||||||
|
prim_tri_index[k] = (prim_offset + k) * 3;
|
||||||
|
prim_type[k] = type;
|
||||||
|
prim_index[k] = prim_offset + k;
|
||||||
|
prim_object[k] = object;
|
||||||
|
prim_visibility[k] = visibility;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t k = 0; k < num_prims; ++k) {
|
for (size_t k = 0; k < num_prims; ++k) {
|
||||||
pack.prim_tri_index.push_back_reserved(pack.prim_tri_verts.size());
|
|
||||||
|
|
||||||
const Mesh::Triangle t = get_triangle(k);
|
const Mesh::Triangle t = get_triangle(k);
|
||||||
pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[0]]));
|
prim_tri_verts[k * 3] = float3_to_float4(verts[t.v[0]]);
|
||||||
pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[1]]));
|
prim_tri_verts[k * 3 + 1] = float3_to_float4(verts[t.v[1]]);
|
||||||
pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[2]]));
|
prim_tri_verts[k * 3 + 2] = float3_to_float4(verts[t.v[2]]);
|
||||||
|
|
||||||
pack.prim_type.push_back_reserved(type);
|
|
||||||
pack.prim_visibility.push_back_reserved(visibility);
|
|
||||||
pack.prim_index.push_back_reserved(k + prim_offset);
|
|
||||||
pack.prim_object.push_back_reserved(object);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -232,7 +232,7 @@ class Mesh : public Geometry {
|
|||||||
size_t tri_offset);
|
size_t tri_offset);
|
||||||
void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset);
|
void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset);
|
||||||
|
|
||||||
void pack_primitives(PackedBVH &pack, int object, uint visibility) override;
|
void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) override;
|
||||||
|
|
||||||
void tessellate(DiagSplit *split);
|
void tessellate(DiagSplit *split);
|
||||||
|
|
||||||
|
@@ -153,6 +153,10 @@ void Object::update_motion()
|
|||||||
|
|
||||||
void Object::compute_bounds(bool motion_blur)
|
void Object::compute_bounds(bool motion_blur)
|
||||||
{
|
{
|
||||||
|
if (!is_modified() && !geometry->is_modified()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BoundBox mbounds = geometry->bounds;
|
BoundBox mbounds = geometry->bounds;
|
||||||
|
|
||||||
if (motion_blur && use_motion()) {
|
if (motion_blur && use_motion()) {
|
||||||
@@ -205,20 +209,39 @@ void Object::apply_transform(bool apply_to_motion)
|
|||||||
|
|
||||||
void Object::tag_update(Scene *scene)
|
void Object::tag_update(Scene *scene)
|
||||||
{
|
{
|
||||||
|
uint32_t flag = ObjectManager::UPDATE_NONE;
|
||||||
|
|
||||||
|
if (is_modified()) {
|
||||||
|
flag |= ObjectManager::OBJECT_MODIFIED;
|
||||||
|
|
||||||
|
if (use_holdout_is_modified()) {
|
||||||
|
flag |= ObjectManager::HOLDOUT_MODIFIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (geometry) {
|
if (geometry) {
|
||||||
if (geometry->transform_applied)
|
if (tfm_is_modified()) {
|
||||||
geometry->tag_modified();
|
/* tag the geometry as modified so the BVH is updated, but do not tag everything as modified
|
||||||
|
*/
|
||||||
|
if (geometry->is_mesh() || geometry->is_volume()) {
|
||||||
|
Mesh *mesh = static_cast<Mesh *>(geometry);
|
||||||
|
mesh->tag_verts_modified();
|
||||||
|
}
|
||||||
|
else if (geometry->is_hair()) {
|
||||||
|
Hair *hair = static_cast<Hair *>(geometry);
|
||||||
|
hair->tag_curve_keys_modified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (Node *node, geometry->get_used_shaders()) {
|
foreach (Node *node, geometry->get_used_shaders()) {
|
||||||
Shader *shader = static_cast<Shader *>(node);
|
Shader *shader = static_cast<Shader *>(node);
|
||||||
if (shader->get_use_mis() && shader->has_surface_emission)
|
if (shader->get_use_mis() && shader->has_surface_emission)
|
||||||
scene->light_manager->need_update = true;
|
scene->light_manager->tag_update(scene, LightManager::EMISSIVE_MESH_MODIFIED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scene->camera->need_flags_update = true;
|
scene->camera->need_flags_update = true;
|
||||||
scene->geometry_manager->need_update = true;
|
scene->object_manager->tag_update(scene, flag);
|
||||||
scene->object_manager->need_update = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Object::use_motion() const
|
bool Object::use_motion() const
|
||||||
@@ -361,7 +384,7 @@ int Object::get_device_index() const
|
|||||||
|
|
||||||
ObjectManager::ObjectManager()
|
ObjectManager::ObjectManager()
|
||||||
{
|
{
|
||||||
need_update = true;
|
update_flags = UPDATE_ALL;
|
||||||
need_flags_update = true;
|
need_flags_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +405,9 @@ static float object_volume_density(const Transform &tfm, Geometry *geom)
|
|||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state, Object *ob)
|
void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state,
|
||||||
|
Object *ob,
|
||||||
|
bool update_all)
|
||||||
{
|
{
|
||||||
KernelObject &kobject = state->objects[ob->index];
|
KernelObject &kobject = state->objects[ob->index];
|
||||||
Transform *object_motion_pass = state->object_motion_pass;
|
Transform *object_motion_pass = state->object_motion_pass;
|
||||||
@@ -456,8 +481,11 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
|
|||||||
kobject.motion_offset = state->motion_offset[ob->index];
|
kobject.motion_offset = state->motion_offset[ob->index];
|
||||||
|
|
||||||
/* Decompose transforms for interpolation. */
|
/* Decompose transforms for interpolation. */
|
||||||
DecomposedTransform *decomp = state->object_motion + kobject.motion_offset;
|
if (ob->tfm_is_modified() || update_all) {
|
||||||
transform_motion_decompose(decomp, ob->motion.data(), ob->motion.size());
|
DecomposedTransform *decomp = state->object_motion + kobject.motion_offset;
|
||||||
|
transform_motion_decompose(decomp, ob->motion.data(), ob->motion.size());
|
||||||
|
}
|
||||||
|
|
||||||
flag |= SD_OBJECT_MOTION;
|
flag |= SD_OBJECT_MOTION;
|
||||||
state->have_motion = true;
|
state->have_motion = true;
|
||||||
}
|
}
|
||||||
@@ -480,10 +508,14 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
|
|||||||
0;
|
0;
|
||||||
kobject.patch_map_offset = 0;
|
kobject.patch_map_offset = 0;
|
||||||
kobject.attribute_map_offset = 0;
|
kobject.attribute_map_offset = 0;
|
||||||
uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
|
|
||||||
uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
|
if (ob->asset_name_is_modified() || update_all) {
|
||||||
kobject.cryptomatte_object = util_hash_to_float(hash_name);
|
uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
|
||||||
kobject.cryptomatte_asset = util_hash_to_float(hash_asset);
|
uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
|
||||||
|
kobject.cryptomatte_object = util_hash_to_float(hash_name);
|
||||||
|
kobject.cryptomatte_asset = util_hash_to_float(hash_asset);
|
||||||
|
}
|
||||||
|
|
||||||
kobject.shadow_terminator_offset = 1.0f / (1.0f - 0.5f * ob->shadow_terminator_offset);
|
kobject.shadow_terminator_offset = 1.0f / (1.0f - 0.5f * ob->shadow_terminator_offset);
|
||||||
|
|
||||||
/* Object flag. */
|
/* Object flag. */
|
||||||
@@ -544,6 +576,9 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
|
|||||||
numparticles += psys->particles.size();
|
numparticles += psys->particles.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* as all the arrays are the same size, checking only dscene.objects is sufficient */
|
||||||
|
const bool update_all = dscene->objects.need_realloc();
|
||||||
|
|
||||||
/* Parallel object update, with grain size to avoid too much threading overhead
|
/* Parallel object update, with grain size to avoid too much threading overhead
|
||||||
* for individual objects. */
|
* for individual objects. */
|
||||||
static const int OBJECTS_PER_TASK = 32;
|
static const int OBJECTS_PER_TASK = 32;
|
||||||
@@ -551,7 +586,7 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
|
|||||||
[&](const blocked_range<size_t> &r) {
|
[&](const blocked_range<size_t> &r) {
|
||||||
for (size_t i = r.begin(); i != r.end(); i++) {
|
for (size_t i = r.begin(); i != r.end(); i++) {
|
||||||
Object *ob = state.scene->objects[i];
|
Object *ob = state.scene->objects[i];
|
||||||
device_update_object_transform(&state, ob);
|
device_update_object_transform(&state, ob, update_all);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -559,7 +594,7 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dscene->objects.copy_to_device();
|
dscene->objects.copy_to_device_if_modified();
|
||||||
if (state.need_motion == Scene::MOTION_PASS) {
|
if (state.need_motion == Scene::MOTION_PASS) {
|
||||||
dscene->object_motion_pass.copy_to_device();
|
dscene->object_motion_pass.copy_to_device();
|
||||||
}
|
}
|
||||||
@@ -569,6 +604,10 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
|
|||||||
|
|
||||||
dscene->data.bvh.have_motion = state.have_motion;
|
dscene->data.bvh.have_motion = state.have_motion;
|
||||||
dscene->data.bvh.have_curves = state.have_curves;
|
dscene->data.bvh.have_curves = state.have_curves;
|
||||||
|
|
||||||
|
dscene->objects.clear_modified();
|
||||||
|
dscene->object_motion_pass.clear_modified();
|
||||||
|
dscene->object_motion.clear_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::device_update(Device *device,
|
void ObjectManager::device_update(Device *device,
|
||||||
@@ -576,12 +615,28 @@ void ObjectManager::device_update(Device *device,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress &progress)
|
Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update)
|
if (!need_update())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (update_flags & (OBJECT_ADDED | OBJECT_REMOVED)) {
|
||||||
|
dscene->objects.tag_realloc();
|
||||||
|
dscene->object_motion_pass.tag_realloc();
|
||||||
|
dscene->object_motion.tag_realloc();
|
||||||
|
dscene->object_flag.tag_realloc();
|
||||||
|
dscene->object_volume_step.tag_realloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_flags & HOLDOUT_MODIFIED) {
|
||||||
|
dscene->object_flag.tag_modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_flags & PARTICLE_MODIFIED) {
|
||||||
|
dscene->objects.tag_modified();
|
||||||
|
}
|
||||||
|
|
||||||
VLOG(1) << "Total " << scene->objects.size() << " objects.";
|
VLOG(1) << "Total " << scene->objects.size() << " objects.";
|
||||||
|
|
||||||
device_free(device, dscene);
|
device_free(device, dscene, false);
|
||||||
|
|
||||||
if (scene->objects.size() == 0)
|
if (scene->objects.size() == 0)
|
||||||
return;
|
return;
|
||||||
@@ -597,6 +652,16 @@ void ObjectManager::device_update(Device *device,
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
foreach (Object *object, scene->objects) {
|
foreach (Object *object, scene->objects) {
|
||||||
object->index = index++;
|
object->index = index++;
|
||||||
|
|
||||||
|
/* this is a bit too broad, however a bigger refactor might be needed to properly separate
|
||||||
|
* update each type of data (transform, flags, etc.) */
|
||||||
|
if (object->is_modified()) {
|
||||||
|
dscene->objects.tag_modified();
|
||||||
|
dscene->object_motion_pass.tag_modified();
|
||||||
|
dscene->object_motion.tag_modified();
|
||||||
|
dscene->object_flag.tag_modified();
|
||||||
|
dscene->object_volume_step.tag_modified();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,7 +703,7 @@ void ObjectManager::device_update(Device *device,
|
|||||||
void ObjectManager::device_update_flags(
|
void ObjectManager::device_update_flags(
|
||||||
Device *, DeviceScene *dscene, Scene *scene, Progress & /*progress*/, bool bounds_valid)
|
Device *, DeviceScene *dscene, Scene *scene, Progress & /*progress*/, bool bounds_valid)
|
||||||
{
|
{
|
||||||
if (!need_update && !need_flags_update)
|
if (!need_update() && !need_flags_update)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
@@ -647,7 +712,7 @@ void ObjectManager::device_update_flags(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
need_update = false;
|
update_flags = UPDATE_NONE;
|
||||||
need_flags_update = false;
|
need_flags_update = false;
|
||||||
|
|
||||||
if (scene->objects.size() == 0)
|
if (scene->objects.size() == 0)
|
||||||
@@ -717,6 +782,9 @@ void ObjectManager::device_update_flags(
|
|||||||
/* Copy object flag. */
|
/* Copy object flag. */
|
||||||
dscene->object_flag.copy_to_device();
|
dscene->object_flag.copy_to_device();
|
||||||
dscene->object_volume_step.copy_to_device();
|
dscene->object_volume_step.copy_to_device();
|
||||||
|
|
||||||
|
dscene->object_flag.clear_modified();
|
||||||
|
dscene->object_volume_step.clear_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Scene *scene)
|
void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Scene *scene)
|
||||||
@@ -764,13 +832,13 @@ void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Sc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::device_free(Device *, DeviceScene *dscene)
|
void ObjectManager::device_free(Device *, DeviceScene *dscene, bool force_free)
|
||||||
{
|
{
|
||||||
dscene->objects.free();
|
dscene->objects.free_if_need_realloc(force_free);
|
||||||
dscene->object_motion_pass.free();
|
dscene->object_motion_pass.free_if_need_realloc(force_free);
|
||||||
dscene->object_motion.free();
|
dscene->object_motion.free_if_need_realloc(force_free);
|
||||||
dscene->object_flag.free();
|
dscene->object_flag.free_if_need_realloc(force_free);
|
||||||
dscene->object_volume_step.free();
|
dscene->object_volume_step.free_if_need_realloc(force_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
|
void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
|
||||||
@@ -841,11 +909,21 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::tag_update(Scene *scene)
|
void ObjectManager::tag_update(Scene *scene, uint32_t flag)
|
||||||
{
|
{
|
||||||
need_update = true;
|
update_flags |= flag;
|
||||||
scene->geometry_manager->need_update = true;
|
|
||||||
scene->light_manager->need_update = true;
|
/* avoid infinite loops if the geometry manager tagged us for an update */
|
||||||
|
if ((flag & GEOMETRY_MANAGER) == 0) {
|
||||||
|
scene->geometry_manager->tag_update(scene, GeometryManager::OBJECT_MANAGER);
|
||||||
|
}
|
||||||
|
|
||||||
|
scene->light_manager->tag_update(scene, LightManager::OBJECT_MANAGER);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectManager::need_update() const
|
||||||
|
{
|
||||||
|
return update_flags != UPDATE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
string ObjectManager::get_cryptomatte_objects(Scene *scene)
|
string ObjectManager::get_cryptomatte_objects(Scene *scene)
|
||||||
|
@@ -122,8 +122,24 @@ class Object : public Node {
|
|||||||
/* Object Manager */
|
/* Object Manager */
|
||||||
|
|
||||||
class ObjectManager {
|
class ObjectManager {
|
||||||
|
uint32_t update_flags;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool need_update;
|
enum : uint32_t {
|
||||||
|
PARTICLE_MODIFIED = (1 << 0),
|
||||||
|
GEOMETRY_MANAGER = (1 << 1),
|
||||||
|
MOTION_BLUR_MODIFIED = (1 << 2),
|
||||||
|
OBJECT_ADDED = (1 << 3),
|
||||||
|
OBJECT_REMOVED = (1 << 4),
|
||||||
|
OBJECT_MODIFIED = (1 << 5),
|
||||||
|
HOLDOUT_MODIFIED = (1 << 6),
|
||||||
|
|
||||||
|
/* tag everything in the manager for an update */
|
||||||
|
UPDATE_ALL = ~0u,
|
||||||
|
|
||||||
|
UPDATE_NONE = 0u,
|
||||||
|
};
|
||||||
|
|
||||||
bool need_flags_update;
|
bool need_flags_update;
|
||||||
|
|
||||||
ObjectManager();
|
ObjectManager();
|
||||||
@@ -139,9 +155,11 @@ class ObjectManager {
|
|||||||
bool bounds_valid = true);
|
bool bounds_valid = true);
|
||||||
void device_update_mesh_offsets(Device *device, DeviceScene *dscene, Scene *scene);
|
void device_update_mesh_offsets(Device *device, DeviceScene *dscene, Scene *scene);
|
||||||
|
|
||||||
void device_free(Device *device, DeviceScene *dscene);
|
void device_free(Device *device, DeviceScene *dscene, bool force_free);
|
||||||
|
|
||||||
void tag_update(Scene *scene);
|
void tag_update(Scene *scene, uint32_t flag);
|
||||||
|
|
||||||
|
bool need_update() const;
|
||||||
|
|
||||||
void apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress);
|
void apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress);
|
||||||
|
|
||||||
@@ -149,7 +167,9 @@ class ObjectManager {
|
|||||||
string get_cryptomatte_assets(Scene *scene);
|
string get_cryptomatte_assets(Scene *scene);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void device_update_object_transform(UpdateObjectTransformState *state, Object *ob);
|
void device_update_object_transform(UpdateObjectTransformState *state,
|
||||||
|
Object *ob,
|
||||||
|
bool update_all);
|
||||||
void device_update_object_transform_task(UpdateObjectTransformState *state);
|
void device_update_object_transform_task(UpdateObjectTransformState *state);
|
||||||
bool device_update_object_transform_pop_work(UpdateObjectTransformState *state,
|
bool device_update_object_transform_pop_work(UpdateObjectTransformState *state,
|
||||||
int *start_index,
|
int *start_index,
|
||||||
|
@@ -96,7 +96,7 @@ void OSLShaderManager::device_update(Device *device,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress &progress)
|
Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update)
|
if (!need_update())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
@@ -132,7 +132,7 @@ void OSLShaderManager::device_update(Device *device,
|
|||||||
compiler.compile(og, shader);
|
compiler.compile(og, shader);
|
||||||
|
|
||||||
if (shader->get_use_mis() && shader->has_surface_emission)
|
if (shader->get_use_mis() && shader->has_surface_emission)
|
||||||
scene->light_manager->need_update = true;
|
scene->light_manager->tag_update(scene, LightManager::SHADER_COMPILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup shader engine */
|
/* setup shader engine */
|
||||||
@@ -147,7 +147,7 @@ void OSLShaderManager::device_update(Device *device,
|
|||||||
foreach (Shader *shader, scene->shaders)
|
foreach (Shader *shader, scene->shaders)
|
||||||
shader->clear_modified();
|
shader->clear_modified();
|
||||||
|
|
||||||
need_update = false;
|
update_flags = UPDATE_NONE;
|
||||||
|
|
||||||
/* add special builtin texture types */
|
/* add special builtin texture types */
|
||||||
services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
|
services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
|
||||||
@@ -323,7 +323,7 @@ bool OSLShaderManager::osl_compile(const string &inputfile, const string &output
|
|||||||
string include_path_arg = string("-I") + shader_path;
|
string include_path_arg = string("-I") + shader_path;
|
||||||
options.push_back(include_path_arg);
|
options.push_back(include_path_arg);
|
||||||
|
|
||||||
stdosl_path = path_get("shader/stdcycles.h");
|
stdosl_path = path_join(shader_path, "stdcycles.h");
|
||||||
|
|
||||||
/* compile */
|
/* compile */
|
||||||
OSL::OSLCompiler *compiler = new OSL::OSLCompiler(&OSL::ErrorHandler::default_handler());
|
OSL::OSLCompiler *compiler = new OSL::OSLCompiler(&OSL::ErrorHandler::default_handler());
|
||||||
|
@@ -46,14 +46,14 @@ ParticleSystem::~ParticleSystem()
|
|||||||
|
|
||||||
void ParticleSystem::tag_update(Scene *scene)
|
void ParticleSystem::tag_update(Scene *scene)
|
||||||
{
|
{
|
||||||
scene->particle_system_manager->need_update = true;
|
scene->particle_system_manager->tag_update(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Particle System Manager */
|
/* Particle System Manager */
|
||||||
|
|
||||||
ParticleSystemManager::ParticleSystemManager()
|
ParticleSystemManager::ParticleSystemManager()
|
||||||
{
|
{
|
||||||
need_update = true;
|
need_update_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParticleSystemManager::~ParticleSystemManager()
|
ParticleSystemManager::~ParticleSystemManager()
|
||||||
@@ -109,7 +109,7 @@ void ParticleSystemManager::device_update(Device *device,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress &progress)
|
Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update)
|
if (!need_update())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
@@ -128,7 +128,7 @@ void ParticleSystemManager::device_update(Device *device,
|
|||||||
if (progress.get_cancel())
|
if (progress.get_cancel())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
need_update = false;
|
need_update_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleSystemManager::device_free(Device *, DeviceScene *dscene)
|
void ParticleSystemManager::device_free(Device *, DeviceScene *dscene)
|
||||||
@@ -138,7 +138,12 @@ void ParticleSystemManager::device_free(Device *, DeviceScene *dscene)
|
|||||||
|
|
||||||
void ParticleSystemManager::tag_update(Scene * /*scene*/)
|
void ParticleSystemManager::tag_update(Scene * /*scene*/)
|
||||||
{
|
{
|
||||||
need_update = true;
|
need_update_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParticleSystemManager::need_update() const
|
||||||
|
{
|
||||||
|
return need_update_;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -57,9 +57,9 @@ class ParticleSystem : public Node {
|
|||||||
/* ParticleSystem Manager */
|
/* ParticleSystem Manager */
|
||||||
|
|
||||||
class ParticleSystemManager {
|
class ParticleSystemManager {
|
||||||
public:
|
bool need_update_;
|
||||||
bool need_update;
|
|
||||||
|
|
||||||
|
public:
|
||||||
ParticleSystemManager();
|
ParticleSystemManager();
|
||||||
~ParticleSystemManager();
|
~ParticleSystemManager();
|
||||||
|
|
||||||
@@ -71,6 +71,8 @@ class ParticleSystemManager {
|
|||||||
void device_free(Device *device, DeviceScene *dscene);
|
void device_free(Device *device, DeviceScene *dscene);
|
||||||
|
|
||||||
void tag_update(Scene *scene);
|
void tag_update(Scene *scene);
|
||||||
|
|
||||||
|
bool need_update() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
89
intern/cycles/render/procedural.cpp
Normal file
89
intern/cycles/render/procedural.cpp
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2018 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 "procedural.h"
|
||||||
|
|
||||||
|
#include "render/scene.h"
|
||||||
|
#include "render/stats.h"
|
||||||
|
|
||||||
|
#include "util/util_foreach.h"
|
||||||
|
#include "util/util_progress.h"
|
||||||
|
|
||||||
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
NODE_ABSTRACT_DEFINE(Procedural)
|
||||||
|
{
|
||||||
|
NodeType *type = NodeType::add("procedural_base", NULL);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Procedural::Procedural(const NodeType *type) : Node(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Procedural::~Procedural()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ProceduralManager::ProceduralManager()
|
||||||
|
{
|
||||||
|
need_update_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProceduralManager::~ProceduralManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralManager::update(Scene *scene, Progress &progress)
|
||||||
|
{
|
||||||
|
if (!need_update()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.set_status("Updating Procedurals");
|
||||||
|
|
||||||
|
scoped_callback_timer timer([scene](double time) {
|
||||||
|
if (scene->update_stats) {
|
||||||
|
scene->update_stats->procedurals.times.add_entry({"update", time});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (Procedural *procedural, scene->procedurals) {
|
||||||
|
if (progress.get_cancel()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
procedural->generate(scene, progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progress.get_cancel()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
need_update_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralManager::tag_update()
|
||||||
|
{
|
||||||
|
need_update_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProceduralManager::need_update() const
|
||||||
|
{
|
||||||
|
return need_update_;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCL_NAMESPACE_END
|
73
intern/cycles/render/procedural.h
Normal file
73
intern/cycles/render/procedural.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2018 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "graph/node.h"
|
||||||
|
|
||||||
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class Progress;
|
||||||
|
class Scene;
|
||||||
|
|
||||||
|
/* A Procedural is a Node which can create other Nodes before rendering starts.
|
||||||
|
*
|
||||||
|
* The Procedural is supposed to be the owner of any nodes that it creates. It can also create
|
||||||
|
* Nodes directly in the Scene (through Scene.create_node), it should still be set as the owner of
|
||||||
|
* those Nodes.
|
||||||
|
*/
|
||||||
|
class Procedural : public Node, public NodeOwner {
|
||||||
|
public:
|
||||||
|
NODE_ABSTRACT_DECLARE
|
||||||
|
|
||||||
|
explicit Procedural(const NodeType *type);
|
||||||
|
virtual ~Procedural();
|
||||||
|
|
||||||
|
/* Called each time the ProceduralManager is tagged for an update, this function is the entry
|
||||||
|
* point for the data generated by this Procedural. */
|
||||||
|
virtual void generate(Scene *scene, Progress &progress) = 0;
|
||||||
|
|
||||||
|
/* Create a node and set this Procedural as the owner. */
|
||||||
|
template<typename T> T *create_node()
|
||||||
|
{
|
||||||
|
T *node = new T();
|
||||||
|
node->set_owner(this);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete a Node created and owned by this Procedural. */
|
||||||
|
template<typename T> void delete_node(T *node)
|
||||||
|
{
|
||||||
|
assert(node->get_owner() == this);
|
||||||
|
delete node;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ProceduralManager {
|
||||||
|
bool need_update_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProceduralManager();
|
||||||
|
~ProceduralManager();
|
||||||
|
|
||||||
|
void update(Scene *scene, Progress &progress);
|
||||||
|
|
||||||
|
void tag_update();
|
||||||
|
|
||||||
|
bool need_update() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
CCL_NAMESPACE_END
|
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "bvh/bvh.h"
|
#include "bvh/bvh.h"
|
||||||
#include "device/device.h"
|
#include "device/device.h"
|
||||||
|
#include "render/alembic.h"
|
||||||
#include "render/background.h"
|
#include "render/background.h"
|
||||||
#include "render/bake.h"
|
#include "render/bake.h"
|
||||||
#include "render/camera.h"
|
#include "render/camera.h"
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
#include "render/object.h"
|
#include "render/object.h"
|
||||||
#include "render/osl.h"
|
#include "render/osl.h"
|
||||||
#include "render/particles.h"
|
#include "render/particles.h"
|
||||||
|
#include "render/procedural.h"
|
||||||
#include "render/scene.h"
|
#include "render/scene.h"
|
||||||
#include "render/session.h"
|
#include "render/session.h"
|
||||||
#include "render/shader.h"
|
#include "render/shader.h"
|
||||||
@@ -114,6 +116,7 @@ Scene::Scene(const SceneParams ¶ms_, Device *device)
|
|||||||
image_manager = new ImageManager(device->info);
|
image_manager = new ImageManager(device->info);
|
||||||
particle_system_manager = new ParticleSystemManager();
|
particle_system_manager = new ParticleSystemManager();
|
||||||
bake_manager = new BakeManager();
|
bake_manager = new BakeManager();
|
||||||
|
procedural_manager = new ProceduralManager();
|
||||||
kernels_loaded = false;
|
kernels_loaded = false;
|
||||||
|
|
||||||
/* TODO(sergey): Check if it's indeed optimal value for the split kernel. */
|
/* TODO(sergey): Check if it's indeed optimal value for the split kernel. */
|
||||||
@@ -142,6 +145,9 @@ void Scene::free_memory(bool final)
|
|||||||
|
|
||||||
foreach (Shader *s, shaders)
|
foreach (Shader *s, shaders)
|
||||||
delete s;
|
delete s;
|
||||||
|
/* delete procedurals before other types as they may hold pointers to those types */
|
||||||
|
foreach (Procedural *p, procedurals)
|
||||||
|
delete p;
|
||||||
foreach (Geometry *g, geometry)
|
foreach (Geometry *g, geometry)
|
||||||
delete g;
|
delete g;
|
||||||
foreach (Object *o, objects)
|
foreach (Object *o, objects)
|
||||||
@@ -156,15 +162,16 @@ void Scene::free_memory(bool final)
|
|||||||
objects.clear();
|
objects.clear();
|
||||||
lights.clear();
|
lights.clear();
|
||||||
particle_systems.clear();
|
particle_systems.clear();
|
||||||
|
procedurals.clear();
|
||||||
|
|
||||||
if (device) {
|
if (device) {
|
||||||
camera->device_free(device, &dscene, this);
|
camera->device_free(device, &dscene, this);
|
||||||
film->device_free(device, &dscene, this);
|
film->device_free(device, &dscene, this);
|
||||||
background->device_free(device, &dscene);
|
background->device_free(device, &dscene);
|
||||||
integrator->device_free(device, &dscene);
|
integrator->device_free(device, &dscene, true);
|
||||||
|
|
||||||
object_manager->device_free(device, &dscene);
|
object_manager->device_free(device, &dscene, true);
|
||||||
geometry_manager->device_free(device, &dscene);
|
geometry_manager->device_free(device, &dscene, true);
|
||||||
shader_manager->device_free(device, &dscene, this);
|
shader_manager->device_free(device, &dscene, this);
|
||||||
light_manager->device_free(device, &dscene);
|
light_manager->device_free(device, &dscene);
|
||||||
|
|
||||||
@@ -195,6 +202,7 @@ void Scene::free_memory(bool final)
|
|||||||
delete image_manager;
|
delete image_manager;
|
||||||
delete bake_manager;
|
delete bake_manager;
|
||||||
delete update_stats;
|
delete update_stats;
|
||||||
|
delete procedural_manager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +244,11 @@ void Scene::device_update(Device *device_, Progress &progress)
|
|||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
procedural_manager->update(this, progress);
|
||||||
|
|
||||||
|
if (progress.get_cancel())
|
||||||
|
return;
|
||||||
|
|
||||||
progress.set_status("Updating Background");
|
progress.set_status("Updating Background");
|
||||||
background->device_update(device, &dscene, this);
|
background->device_update(device, &dscene, this);
|
||||||
|
|
||||||
@@ -386,11 +399,12 @@ bool Scene::need_update()
|
|||||||
|
|
||||||
bool Scene::need_data_update()
|
bool Scene::need_data_update()
|
||||||
{
|
{
|
||||||
return (background->is_modified() || image_manager->need_update || object_manager->need_update ||
|
return (background->is_modified() || image_manager->need_update() ||
|
||||||
geometry_manager->need_update || light_manager->need_update ||
|
object_manager->need_update() || geometry_manager->need_update() ||
|
||||||
lookup_tables->need_update || integrator->is_modified() || shader_manager->need_update ||
|
light_manager->need_update() || lookup_tables->need_update() ||
|
||||||
particle_system_manager->need_update || bake_manager->need_update ||
|
integrator->is_modified() || shader_manager->need_update() ||
|
||||||
film->is_modified());
|
particle_system_manager->need_update() || bake_manager->need_update() ||
|
||||||
|
film->is_modified() || procedural_manager->need_update());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scene::need_reset()
|
bool Scene::need_reset()
|
||||||
@@ -407,12 +421,15 @@ void Scene::reset()
|
|||||||
camera->tag_modified();
|
camera->tag_modified();
|
||||||
dicing_camera->tag_modified();
|
dicing_camera->tag_modified();
|
||||||
film->tag_modified();
|
film->tag_modified();
|
||||||
|
background->tag_modified();
|
||||||
|
|
||||||
background->tag_update(this);
|
background->tag_update(this);
|
||||||
integrator->tag_update(this);
|
integrator->tag_update(this, Integrator::UPDATE_ALL);
|
||||||
object_manager->tag_update(this);
|
object_manager->tag_update(this, ObjectManager::UPDATE_ALL);
|
||||||
geometry_manager->tag_update(this);
|
geometry_manager->tag_update(this, GeometryManager::UPDATE_ALL);
|
||||||
light_manager->tag_update(this);
|
light_manager->tag_update(this, LightManager::UPDATE_ALL);
|
||||||
particle_system_manager->tag_update(this);
|
particle_system_manager->tag_update(this);
|
||||||
|
procedural_manager->tag_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::device_free()
|
void Scene::device_free()
|
||||||
@@ -596,7 +613,7 @@ template<> Light *Scene::create_node<Light>()
|
|||||||
Light *node = new Light();
|
Light *node = new Light();
|
||||||
node->set_owner(this);
|
node->set_owner(this);
|
||||||
lights.push_back(node);
|
lights.push_back(node);
|
||||||
light_manager->tag_update(this);
|
light_manager->tag_update(this, LightManager::LIGHT_ADDED);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,7 +622,7 @@ template<> Mesh *Scene::create_node<Mesh>()
|
|||||||
Mesh *node = new Mesh();
|
Mesh *node = new Mesh();
|
||||||
node->set_owner(this);
|
node->set_owner(this);
|
||||||
geometry.push_back(node);
|
geometry.push_back(node);
|
||||||
geometry_manager->tag_update(this);
|
geometry_manager->tag_update(this, GeometryManager::MESH_ADDED);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,7 +631,7 @@ template<> Hair *Scene::create_node<Hair>()
|
|||||||
Hair *node = new Hair();
|
Hair *node = new Hair();
|
||||||
node->set_owner(this);
|
node->set_owner(this);
|
||||||
geometry.push_back(node);
|
geometry.push_back(node);
|
||||||
geometry_manager->tag_update(this);
|
geometry_manager->tag_update(this, GeometryManager::HAIR_ADDED);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,7 +640,7 @@ template<> Volume *Scene::create_node<Volume>()
|
|||||||
Volume *node = new Volume();
|
Volume *node = new Volume();
|
||||||
node->set_owner(this);
|
node->set_owner(this);
|
||||||
geometry.push_back(node);
|
geometry.push_back(node);
|
||||||
geometry_manager->tag_update(this);
|
geometry_manager->tag_update(this, GeometryManager::MESH_ADDED);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,7 +649,7 @@ template<> Object *Scene::create_node<Object>()
|
|||||||
Object *node = new Object();
|
Object *node = new Object();
|
||||||
node->set_owner(this);
|
node->set_owner(this);
|
||||||
objects.push_back(node);
|
objects.push_back(node);
|
||||||
object_manager->tag_update(this);
|
object_manager->tag_update(this, ObjectManager::OBJECT_ADDED);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,10 +667,23 @@ template<> Shader *Scene::create_node<Shader>()
|
|||||||
Shader *node = new Shader();
|
Shader *node = new Shader();
|
||||||
node->set_owner(this);
|
node->set_owner(this);
|
||||||
shaders.push_back(node);
|
shaders.push_back(node);
|
||||||
shader_manager->need_update = true;
|
shader_manager->tag_update(this, ShaderManager::SHADER_ADDED);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> AlembicProcedural *Scene::create_node<AlembicProcedural>()
|
||||||
|
{
|
||||||
|
#ifdef WITH_ALEMBIC
|
||||||
|
AlembicProcedural *node = new AlembicProcedural();
|
||||||
|
node->set_owner(this);
|
||||||
|
procedurals.push_back(node);
|
||||||
|
procedural_manager->tag_update();
|
||||||
|
return node;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T> void delete_node_from_array(vector<T> &nodes, T node)
|
template<typename T> void delete_node_from_array(vector<T> &nodes, T node)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < nodes.size(); ++i) {
|
for (size_t i = 0; i < nodes.size(); ++i) {
|
||||||
@@ -664,43 +694,52 @@ template<typename T> void delete_node_from_array(vector<T> &nodes, T node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nodes.resize(nodes.size() - 1);
|
nodes.resize(nodes.size() - 1);
|
||||||
|
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Scene::delete_node_impl(Light *node)
|
template<> void Scene::delete_node_impl(Light *node)
|
||||||
{
|
{
|
||||||
delete_node_from_array(lights, node);
|
delete_node_from_array(lights, node);
|
||||||
light_manager->tag_update(this);
|
light_manager->tag_update(this, LightManager::LIGHT_REMOVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Scene::delete_node_impl(Mesh *node)
|
template<> void Scene::delete_node_impl(Mesh *node)
|
||||||
{
|
{
|
||||||
delete_node_from_array(geometry, static_cast<Geometry *>(node));
|
delete_node_from_array(geometry, static_cast<Geometry *>(node));
|
||||||
geometry_manager->tag_update(this);
|
geometry_manager->tag_update(this, GeometryManager::MESH_REMOVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Scene::delete_node_impl(Hair *node)
|
template<> void Scene::delete_node_impl(Hair *node)
|
||||||
{
|
{
|
||||||
delete_node_from_array(geometry, static_cast<Geometry *>(node));
|
delete_node_from_array(geometry, static_cast<Geometry *>(node));
|
||||||
geometry_manager->tag_update(this);
|
geometry_manager->tag_update(this, GeometryManager::HAIR_REMOVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Scene::delete_node_impl(Volume *node)
|
template<> void Scene::delete_node_impl(Volume *node)
|
||||||
{
|
{
|
||||||
delete_node_from_array(geometry, static_cast<Geometry *>(node));
|
delete_node_from_array(geometry, static_cast<Geometry *>(node));
|
||||||
geometry_manager->tag_update(this);
|
geometry_manager->tag_update(this, GeometryManager::MESH_REMOVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Scene::delete_node_impl(Geometry *node)
|
template<> void Scene::delete_node_impl(Geometry *node)
|
||||||
{
|
{
|
||||||
|
uint flag;
|
||||||
|
if (node->is_hair()) {
|
||||||
|
flag = GeometryManager::HAIR_REMOVED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
flag = GeometryManager::MESH_REMOVED;
|
||||||
|
}
|
||||||
|
|
||||||
delete_node_from_array(geometry, node);
|
delete_node_from_array(geometry, node);
|
||||||
geometry_manager->tag_update(this);
|
geometry_manager->tag_update(this, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Scene::delete_node_impl(Object *node)
|
template<> void Scene::delete_node_impl(Object *node)
|
||||||
{
|
{
|
||||||
delete_node_from_array(objects, node);
|
delete_node_from_array(objects, node);
|
||||||
object_manager->tag_update(this);
|
object_manager->tag_update(this, ObjectManager::OBJECT_REMOVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Scene::delete_node_impl(ParticleSystem *node)
|
template<> void Scene::delete_node_impl(ParticleSystem *node)
|
||||||
@@ -714,6 +753,21 @@ template<> void Scene::delete_node_impl(Shader * /*node*/)
|
|||||||
/* don't delete unused shaders, not supported */
|
/* don't delete unused shaders, not supported */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> void Scene::delete_node_impl(Procedural *node)
|
||||||
|
{
|
||||||
|
delete_node_from_array(procedurals, node);
|
||||||
|
procedural_manager->tag_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> void Scene::delete_node_impl(AlembicProcedural *node)
|
||||||
|
{
|
||||||
|
#ifdef WITH_ALEMBIC
|
||||||
|
delete_node_impl(static_cast<Procedural *>(node));
|
||||||
|
#else
|
||||||
|
(void)node;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void remove_nodes_in_set(const set<T *> &nodes_set,
|
static void remove_nodes_in_set(const set<T *> &nodes_set,
|
||||||
vector<T *> &nodes_array,
|
vector<T *> &nodes_array,
|
||||||
@@ -742,19 +796,19 @@ static void remove_nodes_in_set(const set<T *> &nodes_set,
|
|||||||
template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner)
|
template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner)
|
||||||
{
|
{
|
||||||
remove_nodes_in_set(nodes, lights, owner);
|
remove_nodes_in_set(nodes, lights, owner);
|
||||||
light_manager->tag_update(this);
|
light_manager->tag_update(this, LightManager::LIGHT_REMOVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner)
|
template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner)
|
||||||
{
|
{
|
||||||
remove_nodes_in_set(nodes, geometry, owner);
|
remove_nodes_in_set(nodes, geometry, owner);
|
||||||
geometry_manager->tag_update(this);
|
geometry_manager->tag_update(this, GeometryManager::GEOMETRY_REMOVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Scene::delete_nodes(const set<Object *> &nodes, const NodeOwner *owner)
|
template<> void Scene::delete_nodes(const set<Object *> &nodes, const NodeOwner *owner)
|
||||||
{
|
{
|
||||||
remove_nodes_in_set(nodes, objects, owner);
|
remove_nodes_in_set(nodes, objects, owner);
|
||||||
object_manager->tag_update(this);
|
object_manager->tag_update(this, ObjectManager::OBJECT_REMOVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const NodeOwner *owner)
|
template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const NodeOwner *owner)
|
||||||
@@ -768,4 +822,10 @@ template<> void Scene::delete_nodes(const set<Shader *> & /*nodes*/, const NodeO
|
|||||||
/* don't delete unused shaders, not supported */
|
/* don't delete unused shaders, not supported */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> void Scene::delete_nodes(const set<Procedural *> &nodes, const NodeOwner *owner)
|
||||||
|
{
|
||||||
|
remove_nodes_in_set(nodes, procedurals, owner);
|
||||||
|
procedural_manager->tag_update();
|
||||||
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
CCL_NAMESPACE_BEGIN
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class AlembicProcedural;
|
||||||
class AttributeRequestSet;
|
class AttributeRequestSet;
|
||||||
class Background;
|
class Background;
|
||||||
class BVH;
|
class BVH;
|
||||||
@@ -53,6 +54,8 @@ class Object;
|
|||||||
class ObjectManager;
|
class ObjectManager;
|
||||||
class ParticleSystemManager;
|
class ParticleSystemManager;
|
||||||
class ParticleSystem;
|
class ParticleSystem;
|
||||||
|
class Procedural;
|
||||||
|
class ProceduralManager;
|
||||||
class CurveSystemManager;
|
class CurveSystemManager;
|
||||||
class Shader;
|
class Shader;
|
||||||
class ShaderManager;
|
class ShaderManager;
|
||||||
@@ -236,6 +239,7 @@ class Scene : public NodeOwner {
|
|||||||
vector<Light *> lights;
|
vector<Light *> lights;
|
||||||
vector<ParticleSystem *> particle_systems;
|
vector<ParticleSystem *> particle_systems;
|
||||||
vector<Pass> passes;
|
vector<Pass> passes;
|
||||||
|
vector<Procedural *> procedurals;
|
||||||
|
|
||||||
/* data managers */
|
/* data managers */
|
||||||
ImageManager *image_manager;
|
ImageManager *image_manager;
|
||||||
@@ -245,6 +249,7 @@ class Scene : public NodeOwner {
|
|||||||
ObjectManager *object_manager;
|
ObjectManager *object_manager;
|
||||||
ParticleSystemManager *particle_system_manager;
|
ParticleSystemManager *particle_system_manager;
|
||||||
BakeManager *bake_manager;
|
BakeManager *bake_manager;
|
||||||
|
ProceduralManager *procedural_manager;
|
||||||
|
|
||||||
/* default shaders */
|
/* default shaders */
|
||||||
Shader *default_surface;
|
Shader *default_surface;
|
||||||
@@ -379,6 +384,8 @@ template<> ParticleSystem *Scene::create_node<ParticleSystem>();
|
|||||||
|
|
||||||
template<> Shader *Scene::create_node<Shader>();
|
template<> Shader *Scene::create_node<Shader>();
|
||||||
|
|
||||||
|
template<> AlembicProcedural *Scene::create_node<AlembicProcedural>();
|
||||||
|
|
||||||
template<> void Scene::delete_node_impl(Light *node);
|
template<> void Scene::delete_node_impl(Light *node);
|
||||||
|
|
||||||
template<> void Scene::delete_node_impl(Mesh *node);
|
template<> void Scene::delete_node_impl(Mesh *node);
|
||||||
@@ -395,6 +402,10 @@ template<> void Scene::delete_node_impl(ParticleSystem *node);
|
|||||||
|
|
||||||
template<> void Scene::delete_node_impl(Shader *node);
|
template<> void Scene::delete_node_impl(Shader *node);
|
||||||
|
|
||||||
|
template<> void Scene::delete_node_impl(Procedural *node);
|
||||||
|
|
||||||
|
template<> void Scene::delete_node_impl(AlembicProcedural *node);
|
||||||
|
|
||||||
template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner);
|
template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner);
|
||||||
|
|
||||||
template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner);
|
template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner);
|
||||||
@@ -405,6 +416,8 @@ template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const No
|
|||||||
|
|
||||||
template<> void Scene::delete_nodes(const set<Shader *> &nodes, const NodeOwner *owner);
|
template<> void Scene::delete_nodes(const set<Shader *> &nodes, const NodeOwner *owner);
|
||||||
|
|
||||||
|
template<> void Scene::delete_nodes(const set<Procedural *> &nodes, const NodeOwner *owner);
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
|
||||||
#endif /* __SCENE_H__ */
|
#endif /* __SCENE_H__ */
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user