Compare commits
2668 Commits
temp_displ
...
transform-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7576ad3d04 | ||
![]() |
db0f67f464 | ||
9ecb196237 | |||
![]() |
f10219a977 | ||
![]() |
fa317eb69c | ||
![]() |
69f7b513b5 | ||
![]() |
a0ef482124 | ||
7fc84d4e32 | |||
92aeb84fde | |||
7b149bfde6 | |||
5ce95df2c6 | |||
a63a31dd12 | |||
![]() |
c8cff31922 | ||
![]() |
c87bfb1f7d | ||
![]() |
0e95270eb7 | ||
![]() |
1baa236acb | ||
![]() |
5eac4e3057 | ||
8a60d84327 | |||
ffac92e385 | |||
b93ddfd8ac | |||
ca5ccf5cd4 | |||
4f7eb3ad12 | |||
373d362e4a | |||
4fe8395215 | |||
0c68c92840 | |||
e9944fee33 | |||
ccaa21df6d | |||
4a8aaab0b2 | |||
ccd8353d58 | |||
682c4dcd1e | |||
eca256bc32 | |||
8e0bfee1e5 | |||
46cd87f5da | |||
![]() |
a78e97b206 | ||
![]() |
d31c4c5666 | ||
![]() |
db6b4639fc | ||
![]() |
ee6f858c91 | ||
728f75c6a7 | |||
e741804ce3 | |||
5884c9f1ba | |||
cc93a66e71 | |||
2aa0215ec5 | |||
d27ef3913a | |||
3b6eaf8d96 | |||
fbcb920748 | |||
54a60eff24 | |||
ab347c8380 | |||
368b74315a | |||
f65d6ea954 | |||
d1e55be96e | |||
3bf0026bec | |||
e1fb080743 | |||
eba09b1520 | |||
![]() |
97b9afda37 | ||
![]() |
5bfa6d8455 | ||
![]() |
4c2f5ab33e | ||
![]() |
b0998df608 | ||
![]() |
d9b89ca0d0 | ||
![]() |
1f17b72efe | ||
6c42079b78 | |||
25ab3aac9d | |||
90df1142a3 | |||
27d20a04b5 | |||
![]() |
d1f402acfd | ||
70fdf0fe37 | |||
ff693959d8 | |||
7f7c807a92 | |||
e5fa738ce9 | |||
0be064067a | |||
4b7d95290f | |||
d097c2a1b3 | |||
e254aa8965 | |||
8bd61ea54d | |||
14c2083460 | |||
4cfac9edab | |||
![]() |
3fdbd78a6b | ||
![]() |
f2c6c831e3 | ||
![]() |
ce3c7e8ff5 | ||
5b3b0b4778 | |||
843be91002 | |||
![]() |
98e69631b0 | ||
a88801b99b | |||
![]() |
3f6a74560e | ||
ced8fff5de | |||
![]() |
35b731c9c8 | ||
![]() |
f4d597efff | ||
9b1564a862 | |||
10b27bd30a | |||
126ee42a30 | |||
0dc30e9dd8 | |||
31e6249256 | |||
4743fa52ac | |||
ccb9f683e5 | |||
![]() |
15336eb262 | ||
![]() |
e922e42fe6 | ||
![]() |
61134dc02c | ||
![]() |
08875452b0 | ||
![]() |
9571811b5d | ||
![]() |
63bbf753fc | ||
![]() |
328dcae3a9 | ||
![]() |
40f764f922 | ||
![]() |
539e41f226 | ||
66ef0b8834 | |||
48fa2c83eb | |||
be17445714 | |||
cc7386ec6b | |||
5af4e1ca15 | |||
270df9a60f | |||
30bed91b78 | |||
0579eaae1f | |||
![]() |
b0581cd92c | ||
![]() |
ac08482886 | ||
![]() |
38d0ea4f69 | ||
61db9ee27a | |||
![]() |
870440dee9 | ||
2be098a1a0 | |||
c2d3bb7090 | |||
dd662c74ae | |||
a7ca991841 | |||
cb6ec44fc7 | |||
6332e0e1f7 | |||
df7f6a3e2e | |||
b3f9ae0125 | |||
15ff75d06b | |||
ac43e5cc87 | |||
286adfde38 | |||
4c7f4e4662 | |||
4f69dca547 | |||
d808557d15 | |||
02b2094847 | |||
![]() |
ff3e1fa760 | ||
93426cb295 | |||
6ea54fe9ff | |||
69aa6577b3 | |||
855b56b90c | |||
59bb4ca1b0 | |||
3f61280327 | |||
885260117d | |||
e1909958d9 | |||
bed327f1ce | |||
39172c6f34 | |||
1b5acbb329 | |||
6d21970aa0 | |||
4d3d10f625 | |||
21d0f71963 | |||
5ce120b865 | |||
6a5e92c022 | |||
7a65f9b171 | |||
0df33cc52d | |||
0cfc557c5d | |||
6435983876 | |||
bd053ac7ba | |||
0396a15cbb | |||
b33693cb44 | |||
deda6a43fc | |||
7ee41920fa | |||
e54d8eeab2 | |||
![]() |
522ca18281 | ||
2a05292efa | |||
8d48ea0233 | |||
![]() |
e07ffcbd1c | ||
![]() |
8ada7f7397 | ||
d14e39622a | |||
7979bc4c51 | |||
ebdff8c3b8 | |||
8f620f2e85 | |||
271471bbe6 | |||
b95ee78ed3 | |||
159f56f4ab | |||
2e88237ee6 | |||
5aaa643947 | |||
086320a62e | |||
8b204831f2 | |||
4c08c5b192 | |||
2a7e4c3040 | |||
cc53c180ac | |||
a68cc0dc26 | |||
67ffad8cd2 | |||
356aacab6b | |||
505b3b7328 | |||
2830f687aa | |||
4bdb2d4885 | |||
fa63515c37 | |||
001fce167a | |||
ed072e1dcd | |||
15143a7464 | |||
8c0682a93c | |||
f8e02c75ba | |||
393efccb19 | |||
59c5623372 | |||
0495e689e6 | |||
d2c94c7873 | |||
8f4d58de4a | |||
![]() |
fe3fb23697 | ||
86730f1f35 | |||
f730e386eb | |||
edd2c556cd | |||
0c93bc2b63 | |||
7cb2974182 | |||
a6f74453b6 | |||
f68145011f | |||
a7f16c17c2 | |||
dab3865c0b | |||
e9770adf63 | |||
8e58e197fd | |||
5b45715f8a | |||
6aa972ebd4 | |||
467d824f80 | |||
e32710d2d7 | |||
85a5fbf2ce | |||
a14fb77fee | |||
d52191616b | |||
178708f142 | |||
d23459f516 | |||
bc0b5d611c | |||
50f9fc7a53 | |||
0453c807e0 | |||
6a6566a7fc | |||
5d6e9f237b | |||
096602d3a8 | |||
05b7591c62 | |||
9af6f40e4d | |||
96e1b46791 | |||
a96110e710 | |||
27248c8636 | |||
ba8c7d2ba1 | |||
a1348dde2e | |||
2a5d7b5b1e | |||
a5b6742ed2 | |||
f8a999c965 | |||
b797a5ff78 | |||
aa0602130b | |||
1c5cceb7af | |||
e8ff06186e | |||
5c06ff8bb9 | |||
e04970b392 | |||
3de5e71501 | |||
f98d9baea9 | |||
2c78b0c71f | |||
b48ba0909a | |||
476f5c473a | |||
51d4743033 | |||
6cfa962986 | |||
7c094f6079 | |||
092d673689 | |||
339d0170d1 | |||
1729dd9998 | |||
33e32c341a | |||
ec3989441f | |||
1978ac65c4 | |||
89631485cc | |||
0b9041905f | |||
1600b93fb8 | |||
4f4a484b9b | |||
09ad684249 | |||
c2366009c0 | |||
4d82d525f8 | |||
a63ba2739e | |||
b69f0479a4 | |||
005b7bfbdc | |||
559bfd973e | |||
12b62b58e1 | |||
cd37248f90 | |||
8abc315a23 | |||
26c140fbc8 | |||
762319e911 | |||
4646ecf749 | |||
d8b34a17ac | |||
c7a4f96f88 | |||
98a0dd6888 | |||
0c2fd1357d | |||
2ba1868c3f | |||
387ba87ad3 | |||
![]() |
505cc694b3 | ||
![]() |
6883a983e6 | ||
dc5007648c | |||
![]() |
412220c8d3 | ||
797b1d5053 | |||
2b44db4cfc | |||
8563d3b254 | |||
d0253b2ea4 | |||
253281f9d6 | |||
4e92ed87ac | |||
c2f3ec4378 | |||
78878a132f | |||
0a274df536 | |||
6d2aca5a96 | |||
7aad5cf573 | |||
20d02be6b8 | |||
3bd831d1d6 | |||
7870bde275 | |||
80e6638ad3 | |||
a0f16e12a0 | |||
7780a108b3 | |||
a41240439b | |||
fceb1d0781 | |||
d409c48310 | |||
8fe9e94a52 | |||
4a01ff278d | |||
bef63acbd6 | |||
54bed786a6 | |||
231b5d96bb | |||
0c47923fca | |||
938613f720 | |||
06f7fba6aa | |||
74434beb1c | |||
eb1a57b12c | |||
8fff6cc2f5 | |||
13d8661503 | |||
3c4df13924 | |||
d544a61e8a | |||
060243a8ae | |||
9ca0e08236 | |||
fc72a2ff4b | |||
a201b99c5a | |||
69a17bce1a | |||
21b361194f | |||
6b86b446d3 | |||
18bf900b31 | |||
![]() |
a6d4ac28f5 | ||
![]() |
01c4e598e5 | ||
06159e6a58 | |||
dbc8b81ecf | |||
eaf88f564c | |||
fa11d41113 | |||
3f818c7898 | |||
df76616d74 | |||
19d493ee10 | |||
84935998a7 | |||
56d3cc9341 | |||
9bdda427e6 | |||
2fbc50e4c1 | |||
3ceb68c833 | |||
e392bb4937 | |||
4137f30928 | |||
cddde85f2c | |||
c4644b484d | |||
b7355425cd | |||
8cad48df28 | |||
d863b5182e | |||
cf62424e47 | |||
![]() |
2977a8cd21 | ||
![]() |
a96008f3aa | ||
9d873fc3de | |||
ea3d7a7f58 | |||
![]() |
4b190e312f | ||
d6b4fb6429 | |||
502c4be56e | |||
722451e146 | |||
a8c7152eea | |||
a58350b07f | |||
98b81493f3 | |||
e361adbca2 | |||
439a277aa5 | |||
2cae58524c | |||
60a344b43d | |||
63fb57fbc6 | |||
c669bf126c | |||
4452bea2f1 | |||
b27e224276 | |||
750c0dd4de | |||
d4d8da28fc | |||
b4e8dc8c82 | |||
b2d3956e7b | |||
db04980678 | |||
f7793bd53c | |||
![]() |
7eecc2e1c4 | ||
e2df9ab386 | |||
1f65ab606b | |||
fa9bd04483 | |||
fc61cdf142 | |||
0434053f13 | |||
68e58f1991 | |||
6d8875bd61 | |||
c4e07dd29b | |||
aad9dd2f1b | |||
dd3ae7bad7 | |||
1cad64900e | |||
1ff753baa4 | |||
26620f3f87 | |||
4833a71621 | |||
d68a84d1d2 | |||
dd7b60c638 | |||
0fc4cf7637 | |||
0895550d24 | |||
c5f97dfe59 | |||
![]() |
0d0d68d39d | ||
![]() |
a449214854 | ||
375ede0f3f | |||
![]() |
209d4d6993 | ||
68496c0b38 | |||
![]() |
7f596d39df | ||
104a03beed | |||
c832354e33 | |||
fce0ff0a31 | |||
![]() |
8892c7869e | ||
c44cdd5905 | |||
c5dba540d7 | |||
![]() |
81dc8dd42a | ||
19b3b11c64 | |||
e016a29ba0 | |||
6b720dffc9 | |||
6d71169478 | |||
![]() |
d78b1147be | ||
![]() |
c6c85a8c6b | ||
c10fbc002b | |||
![]() |
c16796089c | ||
![]() |
32d90220c2 | ||
![]() |
f274332bb3 | ||
![]() |
6d8a25920d | ||
![]() |
9f366aee3b | ||
![]() |
e00f52aeab | ||
![]() |
279bcd8492 | ||
![]() |
c72d319b47 | ||
d4b3068f36 | |||
407f8eed7d | |||
79f94674fb | |||
af1d9ecd40 | |||
9ad252d157 | |||
6a5487e021 | |||
1d5ba269c1 | |||
f13c729b26 | |||
647fb6ef1e | |||
4877c9362a | |||
76ec329dd1 | |||
1208792adb | |||
582f9ddeb7 | |||
5ba51de84a | |||
43f7d5643f | |||
![]() |
da6cd77628 | ||
f3ff03b3c1 | |||
284701e371 | |||
1410ea0478 | |||
521133682c | |||
8dd0355c21 | |||
0ee1cdab7e | |||
4c5374d46a | |||
0f13f5a683 | |||
91837cd5b0 | |||
810982a95c | |||
3ee0723b7d | |||
225e3a6857 | |||
9bf0b246ac | |||
ac276e1541 | |||
b4157dedb0 | |||
0e40f1bac4 | |||
![]() |
ddedcf7ada | ||
76acaefdd7 | |||
0c72008592 | |||
aa36c73c33 | |||
2b3cc24388 | |||
ecce1fabca | |||
![]() |
f169ff8b88 | ||
![]() |
7bc76f8a3c | ||
8794a43b68 | |||
4dacda58f9 | |||
e8021f5e3b | |||
10404e3e56 | |||
6d3d2b15cb | |||
9c6b9e889c | |||
b759d3c9c5 | |||
18ed060bc3 | |||
6521307dcd | |||
f28376d8d9 | |||
![]() |
8ca11f5b72 | ||
3f94836922 | |||
68ca973f7f | |||
40532b9c3b | |||
76015f98ae | |||
acd4fc3b7a | |||
e29e63c0ba | |||
b90a61917a | |||
fbb1b311ea | |||
bcc8c04db4 | |||
98045648ab | |||
304315d181 | |||
ce155ad2f6 | |||
96868a3941 | |||
5afe4c787f | |||
5be8adf8c0 | |||
f667593b6a | |||
2d3c44389a | |||
c374e9f1f5 | |||
![]() |
cdb7498f66 | ||
![]() |
176698b2eb | ||
![]() |
736a32e7bf | ||
![]() |
fcd3bf5275 | ||
![]() |
0d7dfd9f46 | ||
![]() |
0210df079c | ||
![]() |
e9dd97405e | ||
b6713dcbe5 | |||
a81ea40836 | |||
![]() |
6730202510 | ||
103ae04fbc | |||
![]() |
1100ddeaa9 | ||
![]() |
13f5bed32e | ||
![]() |
989632417b | ||
![]() |
08cde7c785 | ||
15eb83c8b3 | |||
9d6acc34a1 | |||
59fd21296a | |||
![]() |
8e303aae25 | ||
b3bb4a6936 | |||
![]() |
c70eb87305 | ||
17b3097205 | |||
6038583909 | |||
3dbb560331 | |||
12e681909f | |||
4a2cde3f0e | |||
17689f8bb6 | |||
6a8cb92404 | |||
e37538b472 | |||
85fa1403f4 | |||
6ce1d71914 | |||
55a56a31a0 | |||
711ac90481 | |||
![]() |
4c746bb3b0 | ||
![]() |
aca29bcc65 | ||
62cc226101 | |||
![]() |
01b2071c14 | ||
![]() |
51737a2c8c | ||
![]() |
fc53c6f953 | ||
![]() |
8a6d055f37 | ||
![]() |
9de9f25b24 | ||
![]() |
06c051363b | ||
![]() |
e8b5a5bf5b | ||
![]() |
57e26627c4 | ||
![]() |
6c942db30d | ||
![]() |
528cb8877f | ||
88e8e7a074 | |||
b40a4f66b2 | |||
696ed6d3ca | |||
a68c631cf8 | |||
8d98362710 | |||
2a62ec8003 | |||
49ef1a25b8 | |||
4b31f1e591 | |||
3b91989a09 | |||
![]() |
d9f42e5fab | ||
![]() |
3a1748146b | ||
![]() |
9b2877ad88 | ||
4ab322fdd2 | |||
c837bd5ea5 | |||
45b764e95b | |||
817e975dee | |||
a42a0b5ef3 | |||
97c4c2689f | |||
05dfe9c318 | |||
c24d045a23 | |||
9af0c8b00a | |||
6f3f891c58 | |||
75cb4850f0 | |||
ecfbfe478b | |||
![]() |
04a391c2f8 | ||
712f7c3640 | |||
ef7c36f5ed | |||
a095611eb8 | |||
3505be8361 | |||
64751552f7 | |||
fe7cc94dfa | |||
306034790f | |||
997e345bd2 | |||
18e50927f7 | |||
223f45818e | |||
cd7d5669d1 | |||
4cf501b835 | |||
5b8f1c8d34 | |||
b78e543af9 | |||
817873cc83 | |||
0892352bfe | |||
352ee7c3ef | |||
a87766416f | |||
365a4239c5 | |||
230c00d872 | |||
520b53364c | |||
dfd6055eb0 | |||
bc652766e8 | |||
0f56f7a811 | |||
1345d29806 | |||
696bb47c6e | |||
9e566b06e3 | |||
347410a322 | |||
55c2cd85f0 | |||
2f722f1a49 | |||
a07ad02156 | |||
9522f8acf0 | |||
35d78121f0 | |||
![]() |
af076031d6 | ||
![]() |
ca796f872e | ||
76ae10f580 | |||
78d9a0a563 | |||
def4ffd1c5 | |||
583373f049 | |||
517db46b34 | |||
aa44b77129 | |||
15fa806160 | |||
f1c764fd8f | |||
0e995e0bfe | |||
![]() |
a5cba9aab9 | ||
b498db06eb | |||
3623f32b48 | |||
355ad008a2 | |||
dc9a7f861f | |||
d4e7288af9 | |||
![]() |
80444effc6 | ||
33c093ef70 | |||
b36f93fa37 | |||
ff96f527fd | |||
747ac66800 | |||
45b42d3fb7 | |||
608b96c49b | |||
e72af060ab | |||
5f98cd6360 | |||
a461216885 | |||
3caeb51d7f | |||
f75b52eca1 | |||
4a4d71414e | |||
76c9f1a649 | |||
2089a17f7e | |||
6b9d73e8a7 | |||
a514fea932 | |||
87d5f670a0 | |||
0215b3e957 | |||
af1635eeb0 | |||
29683d623c | |||
053589da7d | |||
3fdffc1e95 | |||
3381cf98cb | |||
6999e82693 | |||
b3a4b61a3b | |||
7b92b64742 | |||
2e8398c095 | |||
18c2a44333 | |||
5f05dac28f | |||
17cf423f30 | |||
0c5b197447 | |||
91ce13e90d | |||
![]() |
2a82162618 | ||
c0d0ef142f | |||
25de610876 | |||
cdfae957f2 | |||
810d7d4694 | |||
![]() |
22df0b2fe2 | ||
df88d54284 | |||
8cf524cec9 | |||
c2baf3e486 | |||
e0a2bd43dd | |||
85945849a9 | |||
bb8a172dfb | |||
0c1c646118 | |||
33758c7cb8 | |||
![]() |
a99495d291 | ||
![]() |
5ce6388f7c | ||
42cb93205c | |||
![]() |
0322700d87 | ||
![]() |
146a88dd60 | ||
![]() |
209021a703 | ||
![]() |
083bc48816 | ||
![]() |
aa845eed1e | ||
561d11c5e6 | |||
0b6fa1a0fb | |||
![]() |
a78717a72d | ||
![]() |
e7dc46d278 | ||
![]() |
7b1de2b407 | ||
![]() |
4bf9a65da9 | ||
a83a68b9b6 | |||
87f8bb8d1d | |||
499faa8b11 | |||
![]() |
007fcfc193 | ||
![]() |
a65af5d0cf | ||
869f2940c2 | |||
b463cd2ab8 | |||
aa102283da | |||
043c90fdcd | |||
26fc6c71c4 | |||
856077618a | |||
![]() |
3baa186724 | ||
![]() |
0f7a664731 | ||
193827e59b | |||
49c99549eb | |||
278fce1170 | |||
7fcae7ba60 | |||
ecee40e919 | |||
![]() |
18684e546f | ||
![]() |
b00b9dadd8 | ||
c1f43c9dc6 | |||
8901263b5f | |||
714e85b534 | |||
32c5f3d772 | |||
f64df0e102 | |||
f0cf15b5c6 | |||
351c9239ed | |||
3626521346 | |||
e142793815 | |||
14627cc2ee | |||
![]() |
6ee70312bb | ||
![]() |
0b0347dcca | ||
![]() |
512fb74980 | ||
![]() |
fcbae6c3b3 | ||
![]() |
f35907444e | ||
3176bb8346 | |||
2a8dd3c5ff | |||
7b1e5e8620 | |||
2fcdb6df10 | |||
![]() |
c0e055fa7e | ||
5e889ebf19 | |||
c1012c6c3a | |||
87f236cd10 | |||
54ed1b7324 | |||
7175838b61 | |||
96d63d2232 | |||
677f066634 | |||
![]() |
6af21b4e7f | ||
efe78d824e | |||
a581b65822 | |||
2de9bf1138 | |||
811e90c957 | |||
08e654935c | |||
6a3dd21edd | |||
8a76049e84 | |||
e7d57628c9 | |||
6d1ac79514 | |||
![]() |
5138fe3c0a | ||
![]() |
c24b4e0cd0 | ||
6ab9af0083 | |||
![]() |
bf243752fc | ||
![]() |
b5dd04b7e7 | ||
4fa4132e45 | |||
cd5c853307 | |||
416bd1bbe8 | |||
2342cd0a0f | |||
691ffb60b9 | |||
bf7006c15a | |||
5acac13eb4 | |||
f1b21d5960 | |||
209a64111e | |||
00ceb6d2f4 | |||
f7d67835e9 | |||
cc78690be3 | |||
238db604c5 | |||
845ba1a6fb | |||
![]() |
35290f5d4e | ||
![]() |
edba025c92 | ||
406398213c | |||
![]() |
aff8ce438a | ||
16b2005bfb | |||
6dabcdf69e | |||
712530eb93 | |||
![]() |
fabde06b37 | ||
631ecbc4ca | |||
112e4de885 | |||
![]() |
20a105d54c | ||
0561aa771b | |||
2724fad582 | |||
e9011100f7 | |||
3cf2821f2f | |||
5c3216e233 | |||
d66d5790e9 | |||
94ca09e01c | |||
2c4564b044 | |||
a0b8a9fe68 | |||
8c5826f59a | |||
15f1072ee2 | |||
bda0456933 | |||
caaf5f0a09 | |||
9062c086b4 | |||
1e29286c8c | |||
f49e28bae7 | |||
1f453a8909 | |||
1e7475a5d7 | |||
![]() |
0584c82ad7 | ||
![]() |
2f9a0dfe64 | ||
![]() |
8261a84ffb | ||
![]() |
4c8d8da2e7 | ||
9dd86e2758 | |||
4c6190d08f | |||
c2453007f4 | |||
7b744f9e1a | |||
ab8958bbd5 | |||
2ea5446197 | |||
ccec97ea0a | |||
c9e8584e7f | |||
6628446bdf | |||
44ea6fb857 | |||
45711c3fde | |||
071fdfbfb3 | |||
e437841239 | |||
3d8f4fedd0 | |||
e5799d1389 | |||
4c164487bc | |||
29859d0d5e | |||
34c07c0d6d | |||
dec323659d | |||
c067f1d0d4 | |||
c7ad27fc07 | |||
6a249bb000 | |||
2e83814e18 | |||
50328b41a7 | |||
4e12113bea | |||
13e075600a | |||
ef60979029 | |||
9eb647f1c8 | |||
d751676cf3 | |||
b46b2834b9 | |||
60592f6778 | |||
9dd194716b | |||
![]() |
53a9dec2bf | ||
3b3ed19c18 | |||
30420845b9 | |||
![]() |
7359cc1060 | ||
![]() |
a8d6e41bbc | ||
43299f9465 | |||
5e1d4714fe | |||
b637db2a7a | |||
![]() |
9c106ff211 | ||
efc499cb99 | |||
![]() |
f1d59073cc | ||
![]() |
910b7dec8d | ||
e003499f6f | |||
99947e2943 | |||
3952349a81 | |||
48752d8802 | |||
d4f0e10cc4 | |||
eff5924c75 | |||
75cc33fa20 | |||
cd0d335183 | |||
48aeb0b640 | |||
6dbc6dfc14 | |||
e05d3d5d9b | |||
36c4fc1ea9 | |||
2c30fd83f1 | |||
ae1c1cd8c0 | |||
3622074bf7 | |||
4e9b17da4c | |||
34a502c16a | |||
4f2375b82f | |||
5c39aad283 | |||
696836af1d | |||
75ce4ebc12 | |||
333dc8d60f | |||
86d8dc12c1 | |||
22119f976e | |||
446625c561 | |||
c8b7e7973a | |||
9f839a2ff5 | |||
9992e6a169 | |||
3f5b2e2682 | |||
fae895125e | |||
![]() |
ab6993811f | ||
![]() |
b30044d4af | ||
39e212eb05 | |||
b41c5c81c6 | |||
a54e461b84 | |||
322b1d3187 | |||
![]() |
cb36dbe606 | ||
6f1493f68f | |||
![]() |
7868c0aa8b | ||
![]() |
df56721931 | ||
![]() |
65a75e112c | ||
![]() |
1ed20a692f | ||
50fb3ea3de | |||
![]() |
9cb44cbba1 | ||
31123f09cd | |||
![]() |
7884406f33 | ||
![]() |
5a14578116 | ||
84141f27a6 | |||
d41451a0ca | |||
23e51f4734 | |||
ff53949145 | |||
6c59a3b37a | |||
7819d36d4e | |||
99a6bbf7dd | |||
077988dd44 | |||
cbc5388a4a | |||
34d3ae9d5b | |||
b5cae50376 | |||
![]() |
e3dd2b1591 | ||
![]() |
6d58f1e87d | ||
![]() |
9f4004261e | ||
21eae869ad | |||
306acb7dda | |||
db2a05999a | |||
b512c2a794 | |||
268670cdee | |||
![]() |
d8df7ce6a4 | ||
26c8d559fe | |||
![]() |
011c8c730f | ||
3d63b9a88f | |||
eeeb1aa658 | |||
f5ab4bc339 | |||
6468cb5f9c | |||
5cbaf56b26 | |||
fc185fb1d2 | |||
809ed38075 | |||
781507d2dd | |||
9b3d415f6a | |||
40e5bc15e9 | |||
41e0085fd3 | |||
e22d4699cb | |||
dbe23c5456 | |||
10d2ee6287 | |||
![]() |
45bebbf5ad | ||
![]() |
5a10c64e8c | ||
![]() |
a428daada0 | ||
883ef2c9ce | |||
69b96e27ee | |||
![]() |
574d6011f4 | ||
![]() |
a47235f5fd | ||
13d31b1604 | |||
3e628eefa9 | |||
![]() |
bf83f097ad | ||
![]() |
226ba44775 | ||
efbe47f9cd | |||
f9e4d8e93a | |||
fe47163a1e | |||
20283bfa0b | |||
dd79f907a7 | |||
![]() |
bdd3fd64e9 | ||
![]() |
c694aedcad | ||
310593def1 | |||
8b8c0d0049 | |||
6cdc954e8c | |||
dc7bbd731a | |||
088c6a17ba | |||
5723aa8c02 | |||
b36e26bbce | |||
b0c125bcd3 | |||
cd472bc7de | |||
021f8d56d0 | |||
9f03718a5b | |||
ee2a718763 | |||
e813ebab71 | |||
0f7dee19ed | |||
1f139beee3 | |||
![]() |
e30bc6f517 | ||
384b7e18f1 | |||
402b0aa59b | |||
![]() |
7e3d2a8baa | ||
![]() |
a76d45cf72 | ||
![]() |
1ff3d5bc9a | ||
![]() |
b9762fed93 | ||
af1e48e8ab | |||
737a3b8a0a | |||
324d057b25 | |||
![]() |
6906a884ee | ||
![]() |
c80b760d4a | ||
4d325693e1 | |||
6c104f62b9 | |||
![]() |
31a21135cf | ||
![]() |
9151f12dad | ||
54102ab36e | |||
1089294439 | |||
7fc632a856 | |||
22df54acb6 | |||
0790976b6c | |||
8c09fa3be2 | |||
9c35907ca2 | |||
930186d3df | |||
21dbfb7828 | |||
![]() |
1634cef2b3 | ||
581c819013 | |||
81eee0f536 | |||
![]() |
d4e9c27e4e | ||
37afa965a4 | |||
![]() |
4e64151787 | ||
594015fb7e | |||
9148ce9f3c | |||
![]() |
8a92277a31 | ||
![]() |
10b24eabba | ||
![]() |
adf355849f | ||
b104057d00 | |||
09bfc37889 | |||
5552e83b53 | |||
e76364adcd | |||
24703c97a1 | |||
737d349dbc | |||
e05800d23b | |||
1abd2f279d | |||
eb473143a8 | |||
1976fd7af1 | |||
08c1afb088 | |||
fc0797142d | |||
1ac6e4c7a2 | |||
c5f2380be7 | |||
e008ca13f1 | |||
768e4e991c | |||
bbc31e8929 | |||
a161d45cfb | |||
f7b1b87ba9 | |||
1c09c8f32f | |||
b97864203e | |||
af2df36248 | |||
7252049cba | |||
13ab43afcf | |||
ae3646cd9f | |||
ef600e8ccf | |||
dfadb45254 | |||
5b10a6bb8e | |||
b4a01e7f4f | |||
8fbf1c4d77 | |||
3f9f82f3c4 | |||
8add4cc900 | |||
3ede515b5b | |||
![]() |
0b27b65f24 | ||
9d8a9cacc3 | |||
f9329997c3 | |||
e33e58bf23 | |||
e991af0934 | |||
cd4309ced0 | |||
0178915ce9 | |||
fd7e9f7974 | |||
d395d81bfc | |||
0b65b889ef | |||
b26da8b467 | |||
b929eef8c5 | |||
26f8095384 | |||
ae6e9401ab | |||
48a6aa3499 | |||
![]() |
0c0bdd83a4 | ||
![]() |
4b365064cf | ||
38155c7d3c | |||
bb1367cdaf | |||
![]() |
0ce76a4274 | ||
![]() |
ca9c1de33e | ||
![]() |
9e3cf0c2e8 | ||
![]() |
c80f9822fd | ||
![]() |
d82bb1f634 | ||
![]() |
1bcf199d2e | ||
![]() |
a41bbfb7f3 | ||
![]() |
1045026ea2 | ||
![]() |
cb490561d3 | ||
![]() |
5bee553b1f | ||
e523cde574 | |||
![]() |
ff4dc7abfa | ||
![]() |
0b473168cd | ||
![]() |
8ff7f14c76 | ||
![]() |
f20cc9e54c | ||
08399aca62 | |||
![]() |
0692fc9665 | ||
6b372e3a22 | |||
![]() |
09af91e096 | ||
![]() |
9e95b5edd9 | ||
d2f4900d1a | |||
351eb4fad1 | |||
316d23f2ba | |||
117d90b3da | |||
![]() |
f2ea319316 | ||
![]() |
6444ba2635 | ||
![]() |
b08483defa | ||
![]() |
525937cc39 | ||
61df9fdb2f | |||
2a16a4ee43 | |||
![]() |
3f7ca93490 | ||
![]() |
260f97b3d9 | ||
![]() |
a38298f4dd | ||
b16fd22018 | |||
da31a82832 | |||
04cf1538b5 | |||
31a025f51e | |||
dde40989f3 | |||
7447950bc3 | |||
9830eeb44b | |||
9c3d202e56 | |||
58a10122d0 | |||
98a1855803 | |||
d4913af846 | |||
8cda364d6f | |||
ac38d5652b | |||
95e7f93fa2 | |||
b320873382 | |||
ce9df09067 | |||
82df7100c8 | |||
![]() |
c973e8d2da | ||
69dbeeca48 | |||
b641d016e1 | |||
ce629c5dd9 | |||
e5bb005369 | |||
5d6177111d | |||
![]() |
6432c8cc00 | ||
03be3102c7 | |||
03544eccb4 | |||
53896d4235 | |||
6bf9c8ac89 | |||
83adc54438 | |||
![]() |
aeb8e81f27 | ||
1158800d1b | |||
97fa285ae1 | |||
d23c57b84c | |||
6c95e97e64 | |||
9b742ff61b | |||
f7eaaf35b4 | |||
e217839fd3 | |||
dbdc346e9f | |||
0170c682fe | |||
e3f99329d8 | |||
ac8348d033 | |||
a54110751a | |||
9e97b00873 | |||
e58359c26f | |||
c7f40caa2c | |||
c5cc9e046d | |||
d0015cba02 | |||
8dbd961a3e | |||
![]() |
cb3daaf355 | ||
89f3837d68 | |||
385fe4f0ce | |||
223aff987a | |||
![]() |
351c409317 | ||
22156d951d | |||
c3e2faaad5 | |||
5ad5bb235b | |||
5908382011 | |||
627566cb9a | |||
da08aa4b96 | |||
75aa866211 | |||
47caf343c0 | |||
a2c469edc2 | |||
6663099810 | |||
c367e23d46 | |||
a0561a05ef | |||
21f3767809 | |||
0b4a9caf51 | |||
0e459ad1a3 | |||
52696a0d3f | |||
520ced4ad5 | |||
f3a7104adb | |||
a1820afa30 | |||
030e99588d | |||
aea17a612d | |||
dc1b45ff1a | |||
e1e85454ea | |||
103f2655ab | |||
ddf99214dc | |||
b1b5ded37f | |||
d85295534b | |||
9f67367f0a | |||
33e456b0ce | |||
47b21dd4c6 | |||
9a22b32e7e | |||
57ac20d5b7 | |||
9e2dca933e | |||
3b71d5c0ae | |||
feb588060a | |||
86747ff180 | |||
6edfa73f5c | |||
![]() |
7f10a889e3 | ||
![]() |
d4e0557cf1 | ||
2e8be8ac6b | |||
8e05a5bf8c | |||
64b4a3185c | |||
57573df0d3 | |||
4935e2449b | |||
7493a2b3c0 | |||
ba551014f8 | |||
13399d471e | |||
![]() |
3ab8895610 | ||
fd089843b3 | |||
eca2f918a7 | |||
fb61711b1a | |||
c231c29afa | |||
fa19940dc6 | |||
92258f3678 | |||
be72d7a9f5 | |||
adb422e500 | |||
75a4c836d6 | |||
a90622ce93 | |||
326516c9d7 | |||
b3690cdecd | |||
![]() |
887fc0ff6d | ||
3e9ade6e31 | |||
b5682a6fdd | |||
60e387f5e3 | |||
85174329d9 | |||
b997914f80 | |||
a928a9c1e1 | |||
d07e2416db | |||
b841d60bf8 | |||
a50b173952 | |||
4e1025376e | |||
bc4aeefe82 | |||
eadfd901ad | |||
fbd28d375a | |||
4443bad30a | |||
997a210b08 | |||
4580ace4c1 | |||
62f2c44ffb | |||
505ff16dbf | |||
318ee2e8c1 | |||
167ab03f36 | |||
cdff659036 | |||
![]() |
f754ce1c5e | ||
6c23a1b8b9 | |||
b99491caf7 | |||
cf6ca226fa | |||
dead79a16a | |||
88b0b22914 | |||
cd596fa1c7 | |||
d6f965b99c | |||
15b253c082 | |||
ba116c8e9c | |||
c64c901535 | |||
e4e1900012 | |||
11abb13483 | |||
fb2f95c91a | |||
bfe3b967fa | |||
436f1e3345 | |||
![]() |
2081dac93b | ||
0330741548 | |||
![]() |
84b18162cf | ||
bce9e80d82 | |||
![]() |
8d04f49d0e | ||
![]() |
9b7b9d6ae9 | ||
![]() |
4c43dddeb7 | ||
9023abbf27 | |||
5ef2f21963 | |||
67bef6bcf6 | |||
d812e0cb64 | |||
9e48cafd6d | |||
fd69ba2255 | |||
c441eb27ea | |||
331f721725 | |||
f14e1da5aa | |||
3c3c52a74b | |||
ac58a7fa19 | |||
![]() |
18cf3e1a38 | ||
![]() |
290e080db4 | ||
01527197aa | |||
b91edd61d0 | |||
64f5afdb89 | |||
![]() |
e5482f986c | ||
ced20b74e5 | |||
e29a6f739d | |||
e4de6e87e1 | |||
8ea09252c8 | |||
![]() |
99cfad6a01 | ||
4cbfaa6f3f | |||
1ad842d432 | |||
a7d5cabd4e | |||
57f937ad5a | |||
![]() |
8a6c689f30 | ||
605695de61 | |||
d84df351d0 | |||
5be2a62ca3 | |||
b6ccba9241 | |||
f286e7e017 | |||
769d189ff1 | |||
610af632a9 | |||
a2d609331b | |||
218b06eb83 | |||
55e6d5428d | |||
f20b8ae5aa | |||
46d6992907 | |||
9e40027110 | |||
23122ca889 | |||
991bda6959 | |||
d4c5e366ea | |||
520afa2962 | |||
e5d8c2a67f | |||
d5c7d22bc2 | |||
08ca32093a | |||
39577403d3 | |||
bc096e1eb8 | |||
b9311b5e5a | |||
2ae39ff6b1 | |||
7b8810b01a | |||
77982e159c | |||
2268f41418 | |||
![]() |
1814241526 | ||
ce8889175a | |||
d2382f782e | |||
82187a58f5 | |||
475d536f72 | |||
a97ec403c2 | |||
21e1282265 | |||
43268c1997 | |||
a1c21e0b50 | |||
094d916c60 | |||
cdaed4d360 | |||
![]() |
418d931490 | ||
051526da62 | |||
2666a222f6 | |||
404e59c842 | |||
1ad04c7d65 | |||
c4890cd354 | |||
5298853e95 | |||
d50d370755 | |||
6f900c383a | |||
26cdc64a7f | |||
14d343a8f9 | |||
ebc695ef2c | |||
20eb1fe3c1 | |||
938ec3a743 | |||
461214508c | |||
811e6c2d32 | |||
254fbcdd7b | |||
ff1b850081 | |||
05ff32bd25 | |||
2e3fda2d95 | |||
831cfcfb3d | |||
c91bdaf55b | |||
2a2ae9c3fa | |||
53e7a4a83c | |||
d6cf28c5e1 | |||
afdd756e56 | |||
78b94902f8 | |||
6d36e033ba | |||
446ed355a5 | |||
666cb5ddd9 | |||
e2d02fee30 | |||
8aa8165e85 | |||
b76dbf5e65 | |||
4a19112277 | |||
1455023e64 | |||
11187e8628 | |||
fd4728c85a | |||
a48d3417b5 | |||
b059a71655 | |||
6d868d9f48 | |||
00edc600b0 | |||
7452af0f86 | |||
a93881d704 | |||
259447300f | |||
86b6006ef8 | |||
196520fe7d | |||
d216313732 | |||
e138cdeeb6 | |||
8d4b31ce03 | |||
65ec429d11 | |||
224ae23443 | |||
4903a83235 | |||
fd119a3723 | |||
cd8cde1a6a | |||
3216831c76 | |||
3df30c34c3 | |||
61b52f6d90 | |||
276e36a59f | |||
af9f6fd57e | |||
d7b2093db3 | |||
43872f59b9 | |||
e0303d0297 | |||
7ce833af5b | |||
b997988323 | |||
3748defefe | |||
702bc5ba26 | |||
92fbcbb4bf | |||
d3e4eecaa5 | |||
af9e99763c | |||
7d55761c5d | |||
4e2c6ad8ee | |||
![]() |
a075c8a0b4 | ||
0a446d7276 | |||
646aa40cf7 | |||
e5a665fe24 | |||
14f6e27f6a | |||
807b1a262f | |||
3160472a66 | |||
bd6bd62753 | |||
d464fb0996 | |||
c937c3af46 | |||
99ca90e808 | |||
720e564882 | |||
b53ce9a1d0 | |||
f12f906dd9 | |||
76a4cf1941 | |||
0421ae056d | |||
d9cd9ff322 | |||
985c121c0b | |||
83d18a2a91 | |||
53fa389802 | |||
8daf02f134 | |||
789fdab825 | |||
618b3480c8 | |||
7eb4c850d3 | |||
d1131227c5 | |||
511dbe56db | |||
554024e08e | |||
67f68295be | |||
65c8937f7e | |||
![]() |
092cbcd1d2 | ||
![]() |
c4f60319d1 | ||
c910beaa21 | |||
0507b3e4c4 | |||
394fa07d41 | |||
38b0141554 | |||
2b66a17e50 | |||
8576efc98a | |||
7bbb2292dc | |||
e068d09a4b | |||
![]() |
77dcf0fbc5 | ||
![]() |
80865bd583 | ||
e041bf7579 | |||
1dbaf0dbcc | |||
![]() |
9533eb4908 | ||
da026249ab | |||
![]() |
5ed5ed59c3 | ||
d5cf90f59f | |||
bb88c7af81 | |||
1b75cd5aa8 | |||
378afc9830 | |||
9c756162ae | |||
e713009e9b | |||
62604c5c20 | |||
b2159b94bc | |||
![]() |
e42e1769b3 | ||
![]() |
82b9e1e312 | ||
b86042f21a | |||
a9163f7d22 | |||
351a9d084f | |||
![]() |
c0c48cdacc | ||
3a1b1100af | |||
ff0221f5d8 | |||
65582e75e3 | |||
![]() |
329879239e | ||
8f1f3a0d46 | |||
3c74071634 | |||
![]() |
d78f51a4c2 | ||
![]() |
070f22c440 | ||
13174df534 | |||
42e4b0955c | |||
143d9373e4 | |||
32c65faeb9 | |||
911544c70c | |||
7924c84c44 | |||
adadfaad88 | |||
acbb84b021 | |||
fb20cbe04c | |||
f874aeef70 | |||
bf7d7bc323 | |||
934b3f3682 | |||
7ba2356a53 | |||
6bd245bb53 | |||
3d243eb710 | |||
6ecab6dd8e | |||
2412e67ef8 | |||
a522469940 | |||
11ae06b0b7 | |||
45d0231a24 | |||
cabd2dceca | |||
b1c6ddb107 | |||
3cbe95f683 | |||
c5338fd162 | |||
7f262acb92 | |||
6559ab2d51 | |||
d5edaac42d | |||
d874b40a55 | |||
752a783fa4 | |||
c1e3041051 | |||
41ec1adb03 | |||
3a9c490531 | |||
![]() |
605263177b | ||
b47c912f4b | |||
d0335796a8 | |||
8db2f72997 | |||
![]() |
5e31e07230 | ||
5fb85ef2c2 | |||
544f6113f8 | |||
1c34a7f4eb | |||
4d5cd638ff | |||
76c4f0ec6c | |||
bd42987399 | |||
e30d94bb3b | |||
3af98b4c04 | |||
6c3d8fbeb3 | |||
2e15618f49 | |||
535298eea5 | |||
![]() |
4df75e536a | ||
![]() |
524ab96245 | ||
![]() |
52328be974 | ||
e2d7efc950 | |||
bd3de93557 | |||
26bb0ee464 | |||
12e1732f72 | |||
665110a414 | |||
14d17cd27a | |||
743165eb48 | |||
![]() |
820709c14d | ||
741c4082d8 | |||
84a283d18c | |||
525673b37b | |||
4f03d3290c | |||
91bbffd379 | |||
6967216485 | |||
c4d6fd3ec0 | |||
72d18c195e | |||
d210755f85 | |||
fbcd51aef8 | |||
1bfe359802 | |||
1e21b8dc1b | |||
0fa887ae35 | |||
3b98b44223 | |||
fe59296361 | |||
c21a5139e1 | |||
![]() |
c1267bb800 | ||
ec2fd74f47 | |||
8bae72d04a | |||
![]() |
9446b6809a | ||
![]() |
356dacea90 | ||
9be6d5ff18 | |||
5f852a4324 | |||
7415b9ffa3 | |||
440d104279 | |||
62703850ad | |||
b708dce34f | |||
efadc8051e | |||
968e01d407 | |||
b21938f3d4 | |||
2bb7a135ae | |||
5a8b5a0377 | |||
1846a78849 | |||
3bd94b9f45 | |||
![]() |
54528079e3 | ||
![]() |
35c18e4871 | ||
dd58390d71 | |||
![]() |
0a26904a75 | ||
![]() |
d5708fdad6 | ||
62a2ed97ba | |||
a63108efb1 | |||
fc4a51e3fa | |||
8f29503b52 | |||
2002167a96 | |||
bfe34789d1 | |||
4b69b6d316 | |||
0371ef16ee | |||
1b9cae9d04 | |||
1de79c8960 | |||
8ce6de3bdd | |||
fe0520e2c8 | |||
7471f09f2b | |||
69e8e34d96 | |||
d1d7217692 | |||
2cb5dffc8d | |||
60dae91db8 | |||
95b224dab2 | |||
47c6047873 | |||
6ab42eb0bd | |||
5de33c3b64 | |||
b18f83bcf4 | |||
dfca1e1460 | |||
1791697d43 | |||
7d443ed86d | |||
d9d7b5b4d0 | |||
923eae25d1 | |||
ae04d0fcb6 | |||
1a01ef4ae9 | |||
a2ebc5268f | |||
35d490b3f1 | |||
31fbf2b74a | |||
acc1f8fbed | |||
0c958b9f8e | |||
0ac2be7030 | |||
a4c6558481 | |||
7458a022aa | |||
![]() |
52ec962516 | ||
4ff4dbc0ab | |||
0e1cf858a0 | |||
7fe7835d13 | |||
69a75b0169 | |||
bdceea9475 | |||
d258865995 | |||
87cacd3893 | |||
f812b05922 | |||
9d50175b6c | |||
87cd56b012 | |||
ff2a74906a | |||
58877d6d08 | |||
05b181fbc5 | |||
df63195d2a | |||
2f6f75613f | |||
2ac8c9b42e | |||
66a3671904 | |||
![]() |
514db9f014 | ||
![]() |
ece7b7dc53 | ||
![]() |
9888e1e3d4 | ||
bd5ae46c19 | |||
1ec5edcc96 | |||
7ea2dedd59 | |||
cc1a64be36 | |||
3b467b35a8 | |||
73c1c92c0e | |||
a76f1a7449 | |||
8d4421b0fc | |||
9f35495a26 | |||
4af42f06c3 | |||
328a47fa2c | |||
9bea39c474 | |||
dd34b7a71c | |||
e369b85e2f | |||
c6d6f39153 | |||
6278adc3ca | |||
![]() |
e0307113a5 | ||
df687837f8 | |||
3340acd46b | |||
96ed2b0ce0 | |||
![]() |
2821da5b70 | ||
841f3e4972 | |||
452028c77c | |||
e2d223461e | |||
d20f5b7de0 | |||
ce3cae81f6 | |||
d464a7c441 | |||
265e5def76 | |||
bcd0d8584f | |||
e1e49fd1a8 | |||
d30a0239a2 | |||
4f4e0ecdcf | |||
729affe7c9 | |||
![]() |
4d3d2d0299 | ||
403f00e558 | |||
def365e252 | |||
f2b57c3532 | |||
a537e7b426 | |||
411836d97c | |||
57141ea30e | |||
99c5c8befc | |||
9aa8d1bc45 | |||
67b1979c91 | |||
751573ce6f | |||
![]() |
a796a84a43 | ||
![]() |
60ce602380 | ||
cb694d6595 | |||
4818b3c97e | |||
1be717d007 | |||
edc10f5529 | |||
af444e913f | |||
272412f9c0 | |||
927a168b07 | |||
bd8cbf5c07 | |||
dd51ec592f | |||
94d8e6fc6c | |||
b97c567c1d | |||
2a78635dea | |||
25c534f20a | |||
af7343ae22 | |||
5eab3b079f | |||
b3c8ee891a | |||
83b1f24140 | |||
b86c6aa6be | |||
f68ef05a56 | |||
aea4ed00d5 | |||
e8641d4474 | |||
2c26a7b71e | |||
53a1b48321 | |||
dd82d70bc5 | |||
8c93178c96 | |||
559bd75766 | |||
![]() |
5cbc7b6ed2 | ||
369872a2c5 | |||
fa6a62fac2 | |||
bd6a9fd734 | |||
5a6534a5bb | |||
884693b42a | |||
b6c0edcb09 | |||
b8710e1468 | |||
40990d52d1 | |||
39be226e93 | |||
a90644ed19 | |||
![]() |
0f8e5f4fb4 | ||
ba7c11aa05 | |||
![]() |
53267d2579 | ||
27de0c40c5 | |||
f6083b7bcd | |||
8f0dc3cef6 | |||
![]() |
3fb11061ba | ||
![]() |
fffb1a4cfb | ||
841c4deed7 | |||
b859fef670 | |||
e0bea34c51 | |||
43ed3079e2 | |||
2de882e8cb | |||
fe73b8c29c | |||
d915e89ec8 | |||
feccadd81b | |||
03a395766a | |||
46739f1e5c | |||
a1a8343281 | |||
d294509dd8 | |||
4dbd61cc64 | |||
1f8762bb8e | |||
0a08d8c892 | |||
0c322c3000 | |||
16e2c0ef3c | |||
60409841a4 | |||
86f435d6c8 | |||
![]() |
b757e8298a | ||
b1f700dad3 | |||
e400f4a53e | |||
36ac979ee0 | |||
7aa82e7ed2 | |||
472e2c5acf | |||
![]() |
2bcb1b208a | ||
2a2eb0c463 | |||
209bc9977c | |||
![]() |
f86eccb1ca | ||
930f999f6e | |||
15b2a64d0a | |||
e17b92f535 | |||
4722fc5dd0 | |||
eb9e9f7f1a | |||
3b06c42616 | |||
edddd2c6f5 | |||
8b2905952e | |||
6397319659 | |||
0de157a320 | |||
2653758adc | |||
b78ddd43a5 | |||
44b691dc65 | |||
f2690673ba | |||
af0e6b31a5 | |||
9019f8ca95 | |||
cb117f283b | |||
a828818d59 | |||
625db1d86e | |||
85e51b0638 | |||
![]() |
0cd1b5ef85 | ||
![]() |
69470e36d6 | ||
445274fc4f | |||
a284d04093 | |||
4ee08e9533 | |||
093b6c9e6e | |||
46b5cdaa4d | |||
665aa6a2a0 | |||
c418ef48cb | |||
d9597ce3ba | |||
a3b61f0639 | |||
e6ad6ff082 | |||
77ba1ed5db | |||
d3919c22b0 | |||
6a2b95e1ca | |||
dc0a9e6535 | |||
b047d79871 | |||
7a4a2ed5f4 | |||
8859aa3828 | |||
ffc26fc5a8 | |||
fc9fa07c0e | |||
1b1d6ce131 | |||
7e8bf9dbd6 | |||
cc8132b0c8 | |||
1dbe26f76c | |||
43703fa4bf | |||
447fc7c4ce | |||
4151f12713 | |||
111e2f5aba | |||
b5a58507f2 | |||
69288737ca | |||
478e59a04e | |||
188ecee642 | |||
![]() |
627141082b | ||
e00c3ab13f | |||
eb880f280d | |||
8fd510f4b8 | |||
7fd2efa507 | |||
dad0c31ceb | |||
8b01a6e0f1 | |||
2dbcb75ed5 | |||
f6ab97c1ae | |||
f1ad2ab85f | |||
8e4066b9d3 | |||
674c3bf894 | |||
cdeaec3b0d | |||
ed957768a0 | |||
7d33d4439f | |||
2a838c71d9 | |||
24d89a1f77 | |||
7dda3cf830 | |||
b1743cda5a | |||
653541ea78 | |||
915c74a33b | |||
89c1f9db37 | |||
9eeca9e7cd | |||
48971da4c8 | |||
4710fa700c | |||
a1aa3a8b75 | |||
![]() |
d5def0bedf | ||
![]() |
723e0a5e01 | ||
![]() |
82ba89b042 | ||
80aae2b6fe | |||
e316636fa8 | |||
f0d53ac109 | |||
aef66a6be0 | |||
![]() |
0b9b8ab2dd | ||
![]() |
63b38848a2 | ||
![]() |
1977440770 | ||
2138fdb785 | |||
![]() |
8b8e04cae6 | ||
afc8a4f9e2 | |||
47759b14ab | |||
4d9562a3ae | |||
18be39ff17 | |||
e72caa513a | |||
![]() |
69655a1103 | ||
49a3eaa3dc | |||
a0ae6d7116 | |||
![]() |
380aacb12a | ||
e9689e1a20 | |||
![]() |
90fcbde62d | ||
![]() |
077ac7b302 | ||
![]() |
87fd59406b | ||
4d0f7c320c | |||
2b726b054e | |||
682bcb2995 | |||
12bce04b2f | |||
f90b480f95 | |||
4e80bd2d6d | |||
4f28dac872 | |||
0085001eb0 | |||
a2d78d7a46 | |||
93ace71bd7 | |||
508e2f0d69 | |||
66d7f01ecc | |||
de101fe9a8 | |||
0b83680d85 | |||
f19f9be1b9 | |||
9912792564 | |||
28639a22bc | |||
535914aa46 | |||
7a98c43f9d | |||
016aca7427 | |||
a3277ae384 | |||
5abf1a4e9d | |||
1cd754ad31 | |||
c1ba58c44d | |||
e74e622776 | |||
6f3f27c0cc | |||
c9efcc5e4a | |||
1d01a1a269 | |||
![]() |
f51f215bc3 | ||
37947ed552 | |||
9b5a32cbfb | |||
21350b73df | |||
4c30a9ee42 | |||
65a1fd975c | |||
109be7ed39 | |||
287197c4e3 | |||
c9eca0c6c9 | |||
d872aeaf51 | |||
9331930345 | |||
f8d9a56aa1 | |||
4ef45ba775 | |||
bbd4b96fe9 | |||
a7f53bc512 | |||
f64548daa6 | |||
c8c7414c3f | |||
dd921238d9 | |||
f89fbf580e | |||
818af9c331 | |||
93dbd81796 | |||
2b1d3318f4 | |||
5b26c36008 | |||
a85f68e9c7 | |||
![]() |
521b981575 | ||
![]() |
c02cce7b75 | ||
f0ac661aa8 | |||
17fb504bcf | |||
4e5d251ccb | |||
4a68ff150f | |||
e27d9facdf | |||
dd6fa94dcc | |||
b6980ade90 | |||
27c559f059 | |||
647255db93 | |||
fc1b35e44c | |||
534f11f71e | |||
f800794b97 | |||
9847ad977a | |||
643c5a24d5 | |||
c5510df268 | |||
c9ffb6fc91 | |||
15f2a51232 | |||
dac5438562 | |||
630c0559f9 | |||
![]() |
c25c3bb6cb | ||
![]() |
a41bbd3053 | ||
![]() |
4fdf68271c | ||
83ebf501cd | |||
97a8cd6883 | |||
f94a460397 | |||
![]() |
13ee9b8ebe | ||
4e95a9069e | |||
1ee43c5aef | |||
bf1e9bc613 | |||
fb6f42dc4f | |||
cf8f6d1dbc | |||
aad46dd175 | |||
6488ce7f33 | |||
60682c37dd | |||
04aa454075 | |||
![]() |
2257e6899a | ||
2e9dd1200f | |||
5050572e89 | |||
b6d35e1fa7 | |||
4e68f48227 | |||
26bf230920 | |||
ce785868a5 | |||
b2974d7ab7 | |||
5aa6a2ec06 | |||
1272ee455e | |||
d3b0977a35 | |||
753edafcb7 | |||
0c13792437 | |||
1556a28108 | |||
8a1b38f071 | |||
216dec7eb1 | |||
65c481e145 | |||
194a33ff00 | |||
![]() |
03b8531cea | ||
216a3a3826 | |||
5f0933f07a | |||
f11298692b | |||
7e380ad4c0 | |||
de22e55291 | |||
![]() |
a25d3d7de2 | ||
35f152358b | |||
7c7d23691f | |||
72921a1e43 | |||
44522a5b98 | |||
8125271ddb | |||
3e36cbb3de | |||
2783d5df61 | |||
a394f4e545 | |||
a1f137767f | |||
222ba0247f | |||
456d145d07 | |||
bc71c2bf08 | |||
f523fb43f9 | |||
5c4113a3e4 | |||
a39ab9cfde | |||
cf9a6b416c | |||
42a91f7ad8 | |||
c54381488b | |||
8c761ff838 | |||
f7cf2f659a | |||
064caae7b2 | |||
81c9e0d295 | |||
af411d918e | |||
![]() |
821fa24876 | ||
![]() |
b4f849b9c6 | ||
392551bd95 | |||
d8d42e1702 | |||
bc566e9393 | |||
3e71006448 | |||
d2fe875f8c | |||
94e14a2c43 | |||
c5072941c3 | |||
![]() |
4d11b2fb91 | ||
![]() |
1458f0136d | ||
![]() |
744718f635 | ||
10a25b655a | |||
![]() |
a3b69c8131 | ||
da8f5d6eac | |||
14a55bc059 | |||
cde18cf3b3 | |||
963aa7e270 | |||
80a6e5beb5 | |||
48997d2e40 | |||
3f29259676 | |||
1e1811357d | |||
6388d0c4a0 | |||
0b749d57ee | |||
89a3b17853 | |||
c013280eec | |||
1abdb0c2ee | |||
2cb45c9938 | |||
e53ab2b9ec | |||
![]() |
754eaf45ff | ||
![]() |
54327bf6f1 | ||
![]() |
dabbe6eb22 | ||
![]() |
74e784b3e5 | ||
![]() |
246a104dbc | ||
1d13950ae5 | |||
![]() |
e0a34e963f | ||
35fde5ff7d | |||
5d2620e9c2 | |||
672e906d49 | |||
![]() |
8905c5c874 | ||
371d3570e0 | |||
5765deecd4 | |||
9d0ac94d52 | |||
b5d527ff6c | |||
132478d4b8 | |||
d5ee031f76 | |||
![]() |
c5c2c3be98 | ||
![]() |
6e8a0047d6 | ||
![]() |
46257e01a7 | ||
![]() |
5ff586610a | ||
![]() |
deb77c0e74 | ||
![]() |
4c3624a7a0 | ||
![]() |
af20ca51a1 | ||
cdcddddd96 | |||
fd4caafc53 | |||
b51874437d | |||
![]() |
01872d7f5d | ||
![]() |
dd23e52817 | ||
f7ce482385 | |||
![]() |
a14d7f3009 | ||
![]() |
57d6983f52 | ||
224d70c978 | |||
![]() |
ca10cacf6c | ||
![]() |
693265e1e9 | ||
4ea6917468 | |||
c6abbb40ad | |||
a92d20a0a4 | |||
0c4d949eff | |||
![]() |
26de2b4f9c | ||
32c2cba4ef | |||
![]() |
225edf4e66 | ||
![]() |
8d8f2e2e33 | ||
![]() |
33d99bdfe6 | ||
![]() |
b574bd6cf7 | ||
![]() |
2cd6a89d07 | ||
789ea7397f | |||
417847c161 | |||
9941bc3041 | |||
625f1a1c30 | |||
05117d71a3 | |||
54a0ff3ab5 | |||
![]() |
91fc0c4f2a | ||
e9268abf4a | |||
117af2356a | |||
46a069822a | |||
827ad4125c | |||
82f842c27f | |||
3541f7c47d | |||
7500f6c9d9 | |||
ab4c921e82 | |||
70ff63e63f | |||
0c6939f5f5 | |||
8327795f8d | |||
![]() |
cccd3eb5a8 | ||
![]() |
6a0292cc19 | ||
![]() |
4811b2d356 | ||
5e92a0faad | |||
c2d0832c6e | |||
7f19c4fdf9 | |||
cd843409d3 | |||
d5dd12e56c | |||
e7fddc0772 | |||
42677fa937 | |||
ca369e6f0c | |||
61ca73ea10 | |||
36d2365ac3 | |||
9cdf4afb76 | |||
f7414b7412 | |||
![]() |
d1a35b7a08 | ||
2a6ec00b9b | |||
![]() |
2a53e0975c | ||
![]() |
fa39ec9e46 | ||
![]() |
196654ad08 | ||
![]() |
69713aa2da | ||
![]() |
ad393e1e75 | ||
![]() |
b557ceb2c1 | ||
![]() |
d59079c5e1 | ||
![]() |
b659cb8dbc | ||
![]() |
9a9a663f40 | ||
![]() |
f929045c2c | ||
3999910b19 | |||
1deab69e0a | |||
741965615d | |||
a4fe823416 | |||
a8dc3f4596 | |||
878938f203 | |||
3996fbc564 | |||
cf5750a85e | |||
![]() |
5e428b3b3f | ||
fcff984338 | |||
9632ca0a13 | |||
2df27995f9 | |||
48db35468f | |||
29b47924dd | |||
4f4c7808e4 | |||
![]() |
325b21c1d5 | ||
4736f19000 | |||
3f0c0ed87d | |||
![]() |
9904d73d9a | ||
![]() |
ae8e845470 | ||
![]() |
7fec7eee20 | ||
![]() |
ee54a6f130 | ||
![]() |
608e2402ef | ||
![]() |
4a10eb38a3 | ||
![]() |
e1e97bbb98 | ||
![]() |
11653f85ff | ||
34dc660a76 | |||
dd350c0b37 | |||
05c727bb00 | |||
6855ba4034 | |||
8e80d2741d | |||
0ddb8d9b13 | |||
3055ae5092 | |||
f23db59e48 | |||
49c2dbc5db | |||
![]() |
58f0af965c | ||
87a7149831 | |||
dc60fdd671 | |||
![]() |
3cecf39069 | ||
![]() |
05cf74622f | ||
945f8e3f93 | |||
![]() |
dfa5b32c8c | ||
625b504b23 | |||
![]() |
ecbedce81e | ||
14d0549295 | |||
02a1f15416 | |||
![]() |
916e631fc9 | ||
78817ae95c | |||
6027550e83 | |||
![]() |
3579350481 | ||
6917de6919 | |||
5c651554e2 | |||
918e6cf4c9 | |||
786c0966ec | |||
6f220c1c55 | |||
71656ac222 | |||
![]() |
d5b75256e0 | ||
![]() |
c565f7b5fd | ||
![]() |
165bdfb672 | ||
![]() |
b5c539f9fa | ||
![]() |
84ed9d9829 | ||
![]() |
69b1b95356 | ||
![]() |
e79f302f16 | ||
![]() |
8d573aa0ec | ||
![]() |
f6e7e46fac | ||
2d03edb458 | |||
7f5441b916 | |||
21e65d7457 | |||
5f16382195 | |||
a54242503e | |||
22cdf44101 | |||
e588106d45 | |||
42aeb608e7 | |||
6a4ec3ca43 | |||
fa62a989b4 | |||
87d08a5dc1 | |||
cc95172667 | |||
edd9d89673 | |||
acbbcdfbb8 | |||
683656681c | |||
06d4aca879 | |||
dc95c31372 | |||
c330f37135 | |||
53d82c3e8d | |||
06215c71c0 | |||
17603b9f01 | |||
5322ff3b48 | |||
2fe7e70e92 | |||
0c43567a5a | |||
4370f8ffbd | |||
3e460b68d9 | |||
611a9b1bda | |||
587a16352a | |||
cf449d377b | |||
f36543c5f5 | |||
54dad5c49f | |||
6371f8ff8a | |||
ecbad54df9 | |||
109192b360 | |||
ba5e2270f9 | |||
33ef28068a | |||
22f59b81d7 | |||
78abbdf264 | |||
5fc9bed8b3 | |||
7a60f889d3 | |||
e636529e33 | |||
99db1b8d95 | |||
9ea71bc674 | |||
1fad269d07 | |||
4cb60b14e0 | |||
a2471d2b37 | |||
c275870673 | |||
00dc0666b3 | |||
74e0f900c5 | |||
0fe7446a30 | |||
187d8f473a | |||
7a552612c3 | |||
25e4dc45e5 | |||
b071ac315c | |||
2a76da9ec2 | |||
a398cdedfa | |||
b613d25354 | |||
0a2a006775 | |||
5c23b863f8 | |||
2dccf5a6e8 | |||
8e586c594f | |||
ae2471b850 | |||
![]() |
6e358a1d06 | ||
09b9e462b9 | |||
c67a8acc72 | |||
33297db9de | |||
![]() |
53d1dbbe5c | ||
90f5e61b72 | |||
1cdc54dc7d | |||
4639664b3c | |||
0f88a3546c | |||
e7981a3e93 | |||
107b585a41 | |||
9d40c3dc32 | |||
1865bcd3cf | |||
1f6d704008 | |||
0fbe35c674 | |||
70a16298ea | |||
![]() |
fc77787f6f | ||
![]() |
49beb714c5 | ||
![]() |
4539c2b173 | ||
![]() |
82d069c232 | ||
![]() |
490a938c8b | ||
![]() |
1997b0f03c | ||
1b4b4dfd0c | |||
fe654a93c7 | |||
e01b1eac84 | |||
![]() |
553b4faac8 | ||
ffc46668c4 | |||
![]() |
ec6b593072 | ||
![]() |
ea89b4a918 | ||
![]() |
6b88f3118f | ||
198e3a35c8 | |||
b859557115 | |||
86e439e311 | |||
edcce96d97 | |||
360cb87007 | |||
e86bd78745 | |||
5a0f397eaa | |||
1731e94d0c | |||
e874f3cdc5 | |||
c462500618 | |||
3caa830c11 | |||
![]() |
5e8c4ae75b | ||
4f1f949877 | |||
cd320dbfba | |||
b7046b42ab | |||
e5c3284467 | |||
3a4c1db14b | |||
79b8242fd1 | |||
![]() |
ae44e24fed | ||
b4f9766ed1 | |||
a3abb020e3 | |||
49ad4215ba | |||
55aadccbde | |||
![]() |
103fbb3afc | ||
b9e82b5bfb | |||
![]() |
853d232928 | ||
![]() |
e8c8db4833 | ||
c5e10394b4 | |||
3ee5ce155c | |||
72473a61b0 | |||
c50ccc8476 | |||
3f9b69287d | |||
ba30b852f3 | |||
b8e3d81f31 | |||
875d63ccb5 | |||
641e586b15 | |||
fd2bffd22e | |||
11e93c5f2b | |||
ad23ee761b | |||
4a423862e9 | |||
15e756c584 | |||
40eedd5df9 | |||
5753a1462f | |||
![]() |
95fa303efd | ||
20c6d5e3cb | |||
d1b21d1278 | |||
82648a8f91 | |||
70a40ff65a | |||
6a4ca1e5c0 | |||
eb9521ae04 | |||
5845d52bf3 | |||
85d543b4ac | |||
396a6d8a86 | |||
![]() |
42ed1f0e3c | ||
47bba7e15f | |||
![]() |
35bd833e02 | ||
bbf32980b0 | |||
80837d06de | |||
333366dbcf | |||
57a2015f56 | |||
31ebbe40a0 | |||
94c919349b | |||
8deddba392 | |||
78c380d3b8 | |||
f1de438bba | |||
26d7d995db | |||
![]() |
9bac74c27b | ||
![]() |
4c7ff8fb1e | ||
344a669c41 | |||
0ec87f1227 | |||
e1bfb89da2 | |||
c5d7602925 | |||
305fec8358 | |||
dea7ef4dd9 | |||
cbd3827d83 | |||
601ce6a89c | |||
![]() |
dbb8222baa | ||
83d5a919e2 | |||
0ca2118851 | |||
ad32b774cb | |||
13a4147c17 | |||
9a66d0ad1b | |||
bde5eb8b63 | |||
dd0de53d29 | |||
b63e9a96df | |||
5d0de39238 | |||
2ebb367b0f | |||
54ed22c843 | |||
e6dda514ba | |||
![]() |
88aa42a6f7 | ||
![]() |
fc485302cc | ||
8cff9c20ff | |||
7f76f6f249 | |||
b23ffded08 | |||
![]() |
eab3e0af1c | ||
7c53260109 | |||
07de832e22 | |||
18b0738303 | |||
04230e80d1 | |||
0b89b31a18 | |||
448ee227be | |||
584288a97c | |||
628ef78e8a | |||
a731c75442 | |||
9bea012b8c | |||
ae69986b70 | |||
5c6baf1ee9 | |||
335ee5ce5a | |||
6dd87f2abb | |||
6b5ad4a4d7 | |||
05dbd65098 | |||
d9b242f5fb | |||
5bdff9ea80 | |||
d35bf3f421 | |||
14e825aa1f | |||
4446acbf17 | |||
![]() |
a070a5befa | ||
addc666999 | |||
bf2c2d43ef | |||
36d0ea3123 | |||
7a259d8422 | |||
4b891b40c2 | |||
25b61662f5 | |||
c3b754f9bd | |||
36bbdf142c | |||
7fc2e333bb | |||
4e3578f470 | |||
06b51c64ad | |||
1925b9b2fa | |||
c61cb0e076 | |||
1e89a261b2 | |||
1d03bc73ce | |||
776a8548f0 | |||
2372e67dd6 | |||
![]() |
1dfb89d229 | ||
1b2b7cfa20 | |||
![]() |
56498757ce | ||
d84c55f0fa | |||
4e031073df | |||
![]() |
4a1feaa555 | ||
9937f28877 | |||
ab09a80d33 | |||
1d469f3780 | |||
0e7c3dfe75 | |||
f915ee8e76 | |||
c77da24116 | |||
ca1c7a0cf7 | |||
![]() |
6f80604509 | ||
9493e3b2d6 | |||
![]() |
e9bcdcdbbd | ||
825150605e | |||
![]() |
f6c09eadf0 | ||
a3d258bfb4 | |||
![]() |
e8d953000a | ||
9047717b3f | |||
a7e7479122 | |||
![]() |
2476faebd7 | ||
![]() |
bb6af17799 | ||
![]() |
d10f54ee75 | ||
622c9ced6c | |||
![]() |
8ced4417f9 | ||
166286e6de | |||
e4f7bf6ccb | |||
586c58902d | |||
0b9cfbf6a8 | |||
![]() |
c5326958a5 | ||
0f759da370 | |||
2382d1c401 | |||
a5f14ad1a2 | |||
a6db95cd42 | |||
![]() |
284398e517 | ||
![]() |
04bc828fb6 | ||
![]() |
6ebf5c18c3 | ||
d3365c5c72 | |||
![]() |
42ad5952ff | ||
f3b94a54bc | |||
386da0cc77 | |||
![]() |
87c08fa681 | ||
075a2175d5 | |||
f64aa4e0af | |||
78c0bc52de | |||
f2da63cb12 | |||
e12f5b699d | |||
![]() |
16ed49b26e | ||
7d63ea4a1c | |||
12680d36f5 | |||
838e0a09c7 | |||
100b2ad775 | |||
1f5cd85976 | |||
5c6a14f4e5 | |||
7901f62a9d | |||
6ba59660fb | |||
85f48216ed | |||
![]() |
cc9d0eff81 | ||
25ee094226 | |||
2980c6ebae | |||
b19c6f8f43 | |||
722226b610 | |||
772dab9df1 | |||
![]() |
c2d7d4764e | ||
![]() |
976e591e93 | ||
![]() |
404a427dfd | ||
![]() |
572bc1364c | ||
6c28d3bac2 | |||
![]() |
c0aabeede8 | ||
940f360479 | |||
799454821e | |||
8f28441487 | |||
![]() |
63b90851ce | ||
0552d5820b | |||
40247ee491 | |||
34bd89a9f6 | |||
e21853abb9 | |||
1b1275f0db | |||
c3034afa58 | |||
09925d52f5 | |||
cade262c47 | |||
c9c933ac81 | |||
634508ca3f | |||
716e712a83 | |||
834cb93f40 | |||
d96b8e168f | |||
![]() |
2aca1d85e6 | ||
![]() |
4b39069908 | ||
![]() |
df3394a386 | ||
9883899d62 | |||
9a7891da90 | |||
19268fbad3 | |||
![]() |
661a316c72 | ||
![]() |
1df115d9a3 | ||
f3058c1b66 | |||
a27b54f6e2 | |||
98af402357 | |||
b06584dbf8 | |||
b2f1b8ab7a | |||
4b046c530d | |||
ac7ff55f11 | |||
6f92604e53 | |||
04bfea0d67 | |||
76c99f361f | |||
5eddb80513 | |||
39f7a81176 | |||
e156abe467 | |||
04e2e4fdc1 | |||
2d81e88865 | |||
6fb874369c | |||
1af547a223 | |||
42c17cb769 | |||
f339d5a8ce | |||
0d54d32dd6 | |||
2fb5a959e9 | |||
52181a26c6 | |||
ddbbcbbbba | |||
a8ed9144a3 | |||
a2a5ae5b54 | |||
21e9db9cf1 | |||
e007552442 | |||
fe1342ab9b | |||
ec54a08d30 | |||
fe28e350e9 | |||
b9d1852c5a | |||
b459d9f46c | |||
aae2cea28d | |||
51e8c167f4 | |||
804f6bf31e | |||
110d68ca1d | |||
df7be04ca6 | |||
30a7e75089 | |||
3525fd605a | |||
3b6ce4123c | |||
ce952fd36e | |||
ab6a3dd6c1 | |||
66d4006f51 | |||
48c4a5a4dd | |||
443b3ca9b9 | |||
a2677100fe | |||
0de69e56b4 | |||
f38f787448 | |||
d82710cc02 | |||
7f67885526 | |||
0307369211 | |||
ecbfa31caa | |||
52038fd8c7 | |||
54b00657ca | |||
1b5b899228 | |||
ddb1d5648d | |||
56c798ee62 | |||
b6bd299359 | |||
![]() |
620724d5e2 | ||
91eb1c2e2a | |||
ad40ae1e06 | |||
d15899cca7 | |||
98c7e75897 | |||
0f8f494d63 | |||
fb2c435d86 | |||
91e0a16f2f | |||
49df5d0980 | |||
013b46d6bd | |||
92a2c49aab | |||
ac2fe8312b | |||
b50a5b92c1 | |||
347d759c62 | |||
96f28f9b50 | |||
![]() |
56064b508b | ||
![]() |
9fc1cfc4f1 | ||
d8681c99c4 | |||
037df2aaa6 | |||
2820ab5a8f | |||
4c1d40d87e | |||
ff1ba0861d | |||
70e7c0829e | |||
d205bc3059 | |||
b27ba26b44 | |||
2fe0125fcd | |||
0053a91165 | |||
631af9f930 | |||
78ea06fea4 | |||
1558f5b660 | |||
6de08f6cd1 | |||
27e2317513 | |||
3598a3d1d5 | |||
45f833c21d | |||
a2e8b7e216 | |||
a6f733310b | |||
ace92854b2 | |||
18ae1504ea | |||
7e7a9d146c | |||
afd3a55e3e | |||
19e6321ac0 | |||
4b65662483 | |||
5b42e07e18 | |||
bcc863993a | |||
1263965f83 | |||
008afa446f | |||
18d49a8283 | |||
031c5bad87 | |||
3c29aad787 | |||
498583844f | |||
9d3813e602 | |||
42bbfe7f0a | |||
060bf1bd28 | |||
da36b447c7 | |||
1fc1fd8372 | |||
069569f820 | |||
be2bc7e0f6 | |||
eb717ee979 | |||
1e6b3ef1a1 | |||
7e02d335c0 | |||
d8f036efd6 | |||
6b34eed217 | |||
b92d76000d | |||
b8f27b2514 | |||
8619e09107 | |||
23d7ae1843 | |||
f1ad3483af | |||
91f04b82a5 | |||
90c4ad7387 | |||
db5ad6a79e | |||
e36af2c257 | |||
dfbc51f764 | |||
4565f3d0c8 | |||
7664d947b3 | |||
4aadf7331e | |||
f537d96286 | |||
adbbcefe57 | |||
8fd4a8ab5d | |||
e7a32365cf | |||
5320a0ad9b | |||
e4e1b0c7d3 | |||
f3d65ad23c | |||
b7f3fb0ef9 | |||
a77e77599d | |||
9893153799 | |||
39259fc8ab | |||
c73e4e99a5 | |||
4214b3c44a | |||
6c65e5a00c | |||
8e99eec026 | |||
11ffbfb36a | |||
6fea42d677 | |||
f27516839f | |||
0ea8430549 | |||
e7f9614f07 | |||
6b21d22c60 | |||
a55c5dbcc4 | |||
3eae585791 | |||
9843921288 | |||
4571fdde0e | |||
58697444bb | |||
32757d488f | |||
396dd82428 | |||
797f1896fa | |||
42d816a3d9 | |||
3d9cc4d3f1 | |||
b3cb7e2652 | |||
0d1f0116fe | |||
eccf5a6f81 | |||
251349c3c2 | |||
b1532493c2 | |||
9186b9ae48 | |||
cfbd605567 | |||
71a57a37b2 | |||
f45fbf4b83 | |||
b90b02a480 | |||
5ae6a3b6b6 | |||
0f927d6eca | |||
cbce7fef16 | |||
c2dc77983d | |||
3b0a5dd158 | |||
97ee7f8609 | |||
48c58bd913 | |||
2cfff95ba3 | |||
eedcc4a6a0 | |||
5864269b2c | |||
46e1d85e61 | |||
c96d4ec644 | |||
a151806698 | |||
10d57f991b | |||
4b99958ca1 | |||
1e5735ab99 | |||
5750549f6a | |||
ed6f86a510 | |||
24d29f2e50 | |||
11af9e9a5b | |||
faec430914 | |||
f85745b17b | |||
b4a721af69 | |||
5aa19be912 | |||
735727e2b8 | |||
ac30a04b27 | |||
181d095f50 | |||
ceb452bc9d | |||
c3863650cc | |||
1f723603c8 | |||
3632c4997f | |||
773efb506a | |||
ba279efbdb | |||
9465d3decf | |||
ecb695ccc8 | |||
cd0ec340c4 | |||
15c8d095e5 | |||
7c57822afa | |||
c92b6f1de6 | |||
d30b942f07 | |||
df2e543d44 | |||
fbed29a246 | |||
987bb50a74 | |||
d474ed9b88 | |||
664f5b8c06 | |||
d8d49befa0 | |||
d47173c8ca | |||
cf6cb3dcaf | |||
bcd12bf64d | |||
29a792a75b | |||
cc468c1974 | |||
82ec9c87a7 | |||
5a783144e2 |
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -1,16 +1,24 @@
|
||||
[submodule "release/scripts/addons"]
|
||||
path = release/scripts/addons
|
||||
url = ../blender-addons.git
|
||||
branch = blender2.8
|
||||
ignore = all
|
||||
branch = master
|
||||
[submodule "release/scripts/addons_contrib"]
|
||||
path = release/scripts/addons_contrib
|
||||
url = ../blender-addons-contrib.git
|
||||
branch = master
|
||||
ignore = all
|
||||
branch = master
|
||||
[submodule "release/datafiles/locale"]
|
||||
path = release/datafiles/locale
|
||||
url = ../blender-translations.git
|
||||
branch = master
|
||||
ignore = all
|
||||
branch = master
|
||||
[submodule "source/tools"]
|
||||
path = source/tools
|
||||
url = ../blender-dev-tools.git
|
||||
branch = master
|
||||
ignore = all
|
||||
branch = master
|
||||
|
101
CMakeLists.txt
101
CMakeLists.txt
@@ -155,6 +155,7 @@ option_defaults_init(
|
||||
_init_BUILDINFO
|
||||
_init_CODEC_FFMPEG
|
||||
_init_CYCLES_OSL
|
||||
_init_CYCLES_OPENSUBDIV
|
||||
_init_IMAGE_OPENEXR
|
||||
_init_INPUT_NDOF
|
||||
_init_JACK
|
||||
@@ -172,6 +173,7 @@ if(UNIX AND NOT APPLE)
|
||||
# disable less important dependencies by default
|
||||
set(_init_CODEC_FFMPEG OFF)
|
||||
set(_init_CYCLES_OSL OFF)
|
||||
set(_init_CYCLES_OPENSUBDIV OFF)
|
||||
set(_init_IMAGE_OPENEXR OFF)
|
||||
set(_init_JACK OFF)
|
||||
set(_init_OPENCOLLADA OFF)
|
||||
@@ -240,6 +242,8 @@ endif()
|
||||
option(WITH_PLAYER "Build Player" OFF)
|
||||
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLORIO})
|
||||
|
||||
option(WITH_CLAY_ENGINE "Enable New Clay engine (Breaks Mac and Intel compatibility)" ON)
|
||||
|
||||
# Compositor
|
||||
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
|
||||
|
||||
@@ -331,7 +335,7 @@ option(WITH_ALEMBIC "Enable Alembic Support" OFF)
|
||||
option(WITH_ALEMBIC_HDF5 "Enable Legacy Alembic Support (not officially supported)" OFF)
|
||||
|
||||
if(APPLE)
|
||||
option(WITH_CODEC_QUICKTIME "Enable Quicktime Support" ON)
|
||||
option(WITH_CODEC_QUICKTIME "Enable Quicktime Support" OFF)
|
||||
endif()
|
||||
|
||||
# 3D format support
|
||||
@@ -341,9 +345,9 @@ option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.or
|
||||
# Sound output
|
||||
option(WITH_SDL "Enable SDL for sound and joystick support" ${_init_SDL})
|
||||
option(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
|
||||
option(WITH_JACK "Enable Jack Support (http://www.jackaudio.org)" ${_init_JACK})
|
||||
option(WITH_JACK "Enable JACK Support (http://www.jackaudio.org)" ${_init_JACK})
|
||||
if(UNIX AND NOT APPLE)
|
||||
option(WITH_JACK_DYNLOAD "Enable runtime dynamic Jack libraries loading" OFF)
|
||||
option(WITH_JACK_DYNLOAD "Enable runtime dynamic JACK libraries loading" OFF)
|
||||
endif()
|
||||
if(UNIX AND NOT APPLE)
|
||||
option(WITH_SDL_DYNLOAD "Enable runtime dynamic SDL libraries loading" OFF)
|
||||
@@ -400,9 +404,9 @@ option(WITH_CYCLES "Enable Cycles Render Engine" ON)
|
||||
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
|
||||
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
|
||||
option(WITH_CYCLES_OSL "Build Cycles with OSL support" ${_init_CYCLES_OSL})
|
||||
option(WITH_CYCLES_OPENSUBDIV "Build Cycles with OpenSubdiv support" ON)
|
||||
option(WITH_CYCLES_OPENSUBDIV "Build Cycles with OpenSubdiv support" ${_init_CYCLES_OPENSUBDIV})
|
||||
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles CUDA binaries" OFF)
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_20 sm_21 sm_30 sm_35 sm_37 sm_50 sm_52 CACHE STRING "CUDA architectures to build binaries for")
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_20 sm_21 sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 CACHE STRING "CUDA architectures to build binaries for")
|
||||
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
|
||||
unset(PLATFORM_DEFAULT)
|
||||
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
|
||||
@@ -443,6 +447,7 @@ option(WITH_BOOST "Enable features depending on boost" ON)
|
||||
|
||||
# Unit testsing
|
||||
option(WITH_GTESTS "Enable GTest unit testing" OFF)
|
||||
option(WITH_OPENGL_TESTS "Enable OpenGL related unit testing (Experimental)" OFF)
|
||||
|
||||
|
||||
# Documentation
|
||||
@@ -469,12 +474,6 @@ mark_as_advanced(
|
||||
WITH_GL_PROFILE_ES20
|
||||
)
|
||||
|
||||
if(WITH_GL_PROFILE_COMPAT)
|
||||
set(WITH_GLU ON)
|
||||
else()
|
||||
set(WITH_GLU OFF)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
option(WITH_GL_ANGLE "Link with the ANGLE library, an OpenGL ES 2.0 implementation based on Direct3D, instead of the system OpenGL library." OFF)
|
||||
mark_as_advanced(WITH_GL_ANGLE)
|
||||
@@ -495,33 +494,40 @@ endif()
|
||||
# We default options to whatever default standard in the current compiler.
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "6.0") AND (NOT WITH_CXX11))
|
||||
set(_c11_init ON)
|
||||
set(_cxx11_init ON)
|
||||
else()
|
||||
set(_c11_init OFF)
|
||||
set(_cxx11_init OFF)
|
||||
endif()
|
||||
set(_cxx11_init ON)
|
||||
|
||||
option(WITH_C11 "Build with C11 standard enabled, for development use only!" ${_c11_init})
|
||||
mark_as_advanced(WITH_C11)
|
||||
option(WITH_CXX11 "Build with C++11 standard enabled, for development use only!" ${_cxx11_init})
|
||||
mark_as_advanced(WITH_CXX11)
|
||||
|
||||
# Compiler toolchain
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
option(WITH_LINKER_GOLD "Use ld.gold linker which is usually faster than ld.bfd" ON)
|
||||
mark_as_advanced(WITH_LINKER_GOLD)
|
||||
endif()
|
||||
|
||||
# Dependency graph
|
||||
option(WITH_LEGACY_DEPSGRAPH "Build Blender with legacy dependency graph" ON)
|
||||
mark_as_advanced(WITH_LEGACY_DEPSGRAPH)
|
||||
|
||||
# Use hardcoded paths or find_package to find externals
|
||||
option(WITH_WINDOWS_FIND_MODULES "Use find_package to locate libraries" OFF)
|
||||
mark_as_advanced(WITH_WINDOWS_FIND_MODULES)
|
||||
if(WIN32)
|
||||
# Use hardcoded paths or find_package to find externals
|
||||
option(WITH_WINDOWS_FIND_MODULES "Use find_package to locate libraries" OFF)
|
||||
mark_as_advanced(WITH_WINDOWS_FIND_MODULES)
|
||||
|
||||
option(WITH_WINDOWS_CODESIGN "Use signtool to sign the final binary." OFF)
|
||||
mark_as_advanced(WITH_WINDOWS_CODESIGN)
|
||||
option(WITH_WINDOWS_CODESIGN "Use signtool to sign the final binary." OFF)
|
||||
mark_as_advanced(WITH_WINDOWS_CODESIGN)
|
||||
|
||||
set(WINDOWS_CODESIGN_PFX CACHE FILEPATH "Path to pfx file to use for codesigning.")
|
||||
mark_as_advanced(WINDOWS_CODESIGN_PFX)
|
||||
set(WINDOWS_CODESIGN_PFX CACHE FILEPATH "Path to pfx file to use for codesigning.")
|
||||
mark_as_advanced(WINDOWS_CODESIGN_PFX)
|
||||
|
||||
set(WINDOWS_CODESIGN_PFX_PASSWORD CACHE STRING "password for pfx file used for codesigning.")
|
||||
mark_as_advanced(WINDOWS_CODESIGN_PFX_PASSWORD)
|
||||
set(WINDOWS_CODESIGN_PFX_PASSWORD CACHE STRING "password for pfx file used for codesigning.")
|
||||
mark_as_advanced(WINDOWS_CODESIGN_PFX_PASSWORD)
|
||||
endif()
|
||||
|
||||
# avoid using again
|
||||
option_defaults_clear()
|
||||
@@ -620,6 +626,12 @@ if(APPLE)
|
||||
# to silence sdk not found warning, just overrides CMAKE_OSX_SYSROOT
|
||||
set(CMAKE_XCODE_ATTRIBUTE_SDKROOT macosx${OSX_SYSTEM})
|
||||
endif()
|
||||
|
||||
# QuickTime framework is no longer available in SDK 10.12+
|
||||
if(WITH_CODEC_QUICKTIME AND ${OSX_SYSTEM} VERSION_GREATER 10.11)
|
||||
set(WITH_CODEC_QUICKTIME OFF)
|
||||
message(STATUS "QuickTime not supported by SDK ${OSX_SYSTEM}, disabling WITH_CODEC_QUICKTIME")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OSX_SYSTEM MATCHES 10.9)
|
||||
@@ -627,9 +639,21 @@ if(APPLE)
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_OSX_SYSROOT})
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
# 10.6 is our min. target, if you use higher sdk, weak linking happens
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.6" CACHE STRING "" FORCE)
|
||||
if(WITH_CXX11)
|
||||
# 10.9 is our min. target, if you use higher sdk, weak linking happens
|
||||
if(CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.9)
|
||||
message(STATUS "Setting deployment target to 10.9, lower versions are incompatible with WITH_CXX11")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
else()
|
||||
if(NOT CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
# 10.6 is our min. target, if you use higher sdk, weak linking happens
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.6" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
|
||||
@@ -697,7 +721,7 @@ if(NOT WITH_BOOST)
|
||||
macro(set_and_warn
|
||||
_setting _val)
|
||||
if(${${_setting}})
|
||||
message(STATUS "'WITH_BOOST' is disabled: forceing 'set(${_setting} ${_val})'")
|
||||
message(STATUS "'WITH_BOOST' is disabled: forcing 'set(${_setting} ${_val})'")
|
||||
endif()
|
||||
set(${_setting} ${_val})
|
||||
endmacro()
|
||||
@@ -717,7 +741,7 @@ elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_AUDASPACE OR WITH_INTERNATIONAL O
|
||||
# Keep enabled
|
||||
else()
|
||||
# New dependency graph needs either Boost or C++11 for function bindings.
|
||||
if(NOT USE_CXX11)
|
||||
if(NOT WITH_CXX11)
|
||||
# Enabled but we don't need it
|
||||
set(WITH_BOOST OFF)
|
||||
endif()
|
||||
@@ -841,7 +865,7 @@ endif()
|
||||
# linux only, not cached
|
||||
set(WITH_BINRELOC OFF)
|
||||
|
||||
# MAXOSX only, set to avoid uninitialized
|
||||
# MACOSX only, set to avoid uninitialized
|
||||
set(EXETYPE "")
|
||||
|
||||
# C/C++ flags
|
||||
@@ -898,7 +922,7 @@ if(WITH_X11)
|
||||
if(WITH_X11_ALPHA)
|
||||
find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH})
|
||||
mark_as_advanced(X11_Xrender_LIB)
|
||||
if (X11_Xrender_LIB)
|
||||
if(X11_Xrender_LIB)
|
||||
list(APPEND PLATFORM_LINKLIBS ${X11_Xrender_LIB})
|
||||
else()
|
||||
set(WITH_X11_ALPHA OFF)
|
||||
@@ -952,11 +976,6 @@ if(WITH_CYCLES)
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_OPENSUBDIV AND NOT WITH_OPENSUBDIV)
|
||||
message(STATUS "WITH_CYCLES_OPENSUBDIV requires WITH_OPENSUBDIV to be ON, turning OFF")
|
||||
set(WITH_CYCLES_OPENSUBDIV OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_INTERNATIONAL)
|
||||
@@ -977,7 +996,7 @@ if(SUPPORT_SSE_BUILD)
|
||||
add_definitions(-D__SSE__ -D__MMX__)
|
||||
endif()
|
||||
if(SUPPORT_SSE2_BUILD)
|
||||
set(PLATFORM_CFLAGS " ${COMPILER_SSE2_FLAG} ${PLATFORM_CFLAGS}")
|
||||
set(PLATFORM_CFLAGS " ${PLATFORM_CFLAGS} ${COMPILER_SSE2_FLAG}")
|
||||
add_definitions(-D__SSE2__)
|
||||
if(NOT SUPPORT_SSE_BUILD) # dont double up
|
||||
add_definitions(-D__MMX__)
|
||||
@@ -1033,11 +1052,6 @@ endif()
|
||||
find_package(OpenGL)
|
||||
blender_include_dirs_sys("${OPENGL_INCLUDE_DIR}")
|
||||
|
||||
if(WITH_GLU)
|
||||
list(APPEND BLENDER_GL_LIBRARIES "${OPENGL_glu_LIBRARY}")
|
||||
list(APPEND GL_DEFINITIONS -DWITH_GLU)
|
||||
endif()
|
||||
|
||||
if(WITH_SYSTEM_GLES)
|
||||
find_package_wrapper(OpenGLES)
|
||||
endif()
|
||||
@@ -1265,9 +1279,7 @@ else()
|
||||
|
||||
endif()
|
||||
|
||||
if(NOT WITH_GLU)
|
||||
list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
|
||||
endif()
|
||||
list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure Bullet
|
||||
@@ -1552,7 +1564,7 @@ if(WITH_CXX11)
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# TODO(sergey): Do we want c++11 or gnu-c++11 here?
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
elseif(MSVC12)
|
||||
elseif(MSVC)
|
||||
# Nothing special is needed, C++11 features are available by default.
|
||||
else()
|
||||
message(FATAL_ERROR "Compiler ${CMAKE_C_COMPILER_ID} is not supported for C++11 build yet")
|
||||
@@ -1775,7 +1787,6 @@ if(FIRST_RUN)
|
||||
|
||||
info_cfg_text("OpenGL:")
|
||||
info_cfg_option(WITH_GLEW_ES)
|
||||
info_cfg_option(WITH_GLU)
|
||||
info_cfg_option(WITH_GL_EGL)
|
||||
info_cfg_option(WITH_GL_PROFILE_COMPAT)
|
||||
info_cfg_option(WITH_GL_PROFILE_CORE)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
|
||||
# -*- mode: gnumakefile; tab-width: 4; indent-tabs-mode: t; -*-
|
||||
# vim: tabstop=4
|
||||
#
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
@@ -113,7 +113,7 @@ CMAKE_CONFIG = cmake $(BUILD_CMAKE_ARGS) \
|
||||
# X11 spesific
|
||||
ifdef DISPLAY
|
||||
CMAKE_CONFIG_TOOL = cmake-gui
|
||||
else
|
||||
else
|
||||
CMAKE_CONFIG_TOOL = ccmake
|
||||
endif
|
||||
|
||||
@@ -127,7 +127,7 @@ all: .FORCE
|
||||
# # if test ! -f $(BUILD_DIR)/CMakeCache.txt ; then \
|
||||
# # $(CMAKE_CONFIG); \
|
||||
# # fi
|
||||
|
||||
|
||||
# # do this always incase of failed initial build, could be smarter here...
|
||||
@$(CMAKE_CONFIG)
|
||||
|
||||
@@ -402,7 +402,7 @@ update: .FORCE
|
||||
svn update ../lib/* ; \
|
||||
fi
|
||||
git pull --rebase
|
||||
git submodule foreach git pull --rebase origin master
|
||||
git submodule update --remote
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
@@ -25,7 +25,8 @@
|
||||
ARGS=$( \
|
||||
getopt \
|
||||
-o s:i:t:h \
|
||||
--long source:,install:,tmp:,info:,threads:,help,show-deps,no-sudo,no-build,no-confirm,with-all,with-opencollada,\
|
||||
--long source:,install:,tmp:,info:,threads:,help,show-deps,no-sudo,no-build,no-confirm,\
|
||||
with-all,with-opencollada,\
|
||||
ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,ver-osd:,ver-openvdb:,\
|
||||
force-all,force-python,force-numpy,force-boost,\
|
||||
force-ocio,force-openexr,force-oiio,force-llvm,force-osl,force-osd,force-openvdb,\
|
||||
@@ -281,8 +282,9 @@ SUDO="sudo"
|
||||
|
||||
NO_BUILD=false
|
||||
NO_CONFIRM=false
|
||||
USE_CXX11=true # Mandatory in blender2.8
|
||||
|
||||
PYTHON_VERSION="3.5.1"
|
||||
PYTHON_VERSION="3.5.2"
|
||||
PYTHON_VERSION_MIN="3.5"
|
||||
PYTHON_FORCE_BUILD=false
|
||||
PYTHON_FORCE_REBUILD=false
|
||||
@@ -315,7 +317,7 @@ OPENEXR_FORCE_REBUILD=false
|
||||
OPENEXR_SKIP=false
|
||||
_with_built_openexr=false
|
||||
|
||||
OIIO_VERSION="1.6.9"
|
||||
OIIO_VERSION="1.7.8"
|
||||
OIIO_VERSION_MIN="1.6.0"
|
||||
OIIO_VERSION_MAX="1.9.0" # UNKNOWN currently # Not supported by current OSL...
|
||||
OIIO_FORCE_BUILD=false
|
||||
@@ -330,14 +332,14 @@ LLVM_FORCE_REBUILD=false
|
||||
LLVM_SKIP=false
|
||||
|
||||
# OSL needs to be compiled for now!
|
||||
OSL_VERSION="1.7.3"
|
||||
OSL_VERSION="1.7.5"
|
||||
OSL_VERSION_MIN=$OSL_VERSION
|
||||
OSL_FORCE_BUILD=false
|
||||
OSL_FORCE_REBUILD=false
|
||||
OSL_SKIP=false
|
||||
|
||||
# OpenSubdiv needs to be compiled for now
|
||||
OSD_VERSION="3.0.5"
|
||||
OSD_VERSION="3.1.1"
|
||||
OSD_VERSION_MIN=$OSD_VERSION
|
||||
OSD_FORCE_BUILD=false
|
||||
OSD_FORCE_REBUILD=false
|
||||
@@ -353,7 +355,7 @@ OPENVDB_FORCE_REBUILD=false
|
||||
OPENVDB_SKIP=false
|
||||
|
||||
# Alembic needs to be compiled for now
|
||||
ALEMBIC_VERSION="1.6.0"
|
||||
ALEMBIC_VERSION="1.7.1"
|
||||
ALEMBIC_VERSION_MIN=$ALEMBIC_VERSION
|
||||
ALEMBIC_FORCE_BUILD=false
|
||||
ALEMBIC_FORCE_REBUILD=false
|
||||
@@ -365,7 +367,7 @@ OPENCOLLADA_FORCE_BUILD=false
|
||||
OPENCOLLADA_FORCE_REBUILD=false
|
||||
OPENCOLLADA_SKIP=false
|
||||
|
||||
FFMPEG_VERSION="2.8.4"
|
||||
FFMPEG_VERSION="3.2.1"
|
||||
FFMPEG_VERSION_MIN="2.8.4"
|
||||
FFMPEG_FORCE_BUILD=false
|
||||
FFMPEG_FORCE_REBUILD=false
|
||||
@@ -703,6 +705,21 @@ if [ "$WITH_ALL" = true -a "$OPENCOLLADA_SKIP" = false ]; then
|
||||
fi
|
||||
|
||||
|
||||
WARNING "****WARNING****"
|
||||
PRINT "If you are experiencing issues building Blender, _*TRY A FRESH, CLEAN BUILD FIRST*_!"
|
||||
PRINT "The same goes for install_deps itself, if you encounter issues, please first erase everything in $SRC and $INST"
|
||||
PRINT "(provided obviously you did not add anything yourself in those dirs!), and run install_deps.sh again!"
|
||||
PRINT "Often, changes in the libs built by this script, or in your distro package, cannot be handled simply, so..."
|
||||
PRINT ""
|
||||
PRINT "You may also try to use the '--build-foo' options to bypass your distribution's packages"
|
||||
PRINT "for some troublesome/buggy libraries..."
|
||||
PRINT ""
|
||||
PRINT ""
|
||||
PRINT "Ran with:"
|
||||
PRINT " install_deps.sh $COMMANDLINE"
|
||||
PRINT ""
|
||||
PRINT ""
|
||||
|
||||
|
||||
# This has to be done here, because user might force some versions...
|
||||
PYTHON_SOURCE=( "https://www.python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tgz" )
|
||||
@@ -766,7 +783,20 @@ OPENCOLLADA_REPO_BRANCH="master"
|
||||
|
||||
FFMPEG_SOURCE=( "http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2" )
|
||||
|
||||
CXXFLAGS_BACK=$CXXFLAGS
|
||||
if [ "$USE_CXX11" = true ]; then
|
||||
WARNING "C++11 is now mandatory for blender2.8, this *should* go smoothly with any very recent distribution.
|
||||
However, if you are experiencing linking errors (also when building Blender itself), please try the following:
|
||||
* Re-run this script with '--build-all --force-all' options.
|
||||
* Ensure your gcc version is at the very least 4.8, if possible you should really rather use gcc-5.1 or above.
|
||||
|
||||
Please note that until the transition to C++11-built libraries if completed in your distribution, situation will
|
||||
remain fuzzy and incompatibilities may happen..."
|
||||
PRINT ""
|
||||
PRINT ""
|
||||
CXXFLAGS="$CXXFLAGS -std=c++11"
|
||||
export CXXFLAGS
|
||||
fi
|
||||
|
||||
#### Show Dependencies ####
|
||||
|
||||
@@ -779,7 +809,7 @@ Those libraries should be available as packages in all recent distributions (opt
|
||||
* libjpeg, libpng, libtiff, [libopenjpeg], [libopenal].
|
||||
* libx11, libxcursor, libxi, libxrandr, libxinerama (and other libx... as needed).
|
||||
* libsqlite3, libbz2, libssl, libfftw3, libxml2, libtinyxml, yasm, libyaml-cpp.
|
||||
* libsdl1.2, libglew, libglewmx.\""
|
||||
* libsdl1.2, libglew, [libglewmx].\""
|
||||
|
||||
DEPS_SPECIFIC_INFO="\"BUILDABLE DEPENDENCIES:
|
||||
|
||||
@@ -953,7 +983,7 @@ prepare_opt() {
|
||||
|
||||
# Check whether the current package needs to be recompiled, based on a dummy file containing a magic number in its name...
|
||||
magic_compile_check() {
|
||||
if [ -f $INST/.$1-magiccheck-$2 ]; then
|
||||
if [ -f $INST/.$1-magiccheck-$2-$USE_CXX11 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
@@ -962,7 +992,7 @@ magic_compile_check() {
|
||||
|
||||
magic_compile_set() {
|
||||
rm -f $INST/.$1-magiccheck-*
|
||||
touch $INST/.$1-magiccheck-$2
|
||||
touch $INST/.$1-magiccheck-$2-$USE_CXX11
|
||||
}
|
||||
|
||||
# Note: should clean nicely in $INST, but not in $SRC, when we switch to a new version of a lib...
|
||||
@@ -1622,6 +1652,10 @@ compile_OIIO() {
|
||||
# fi
|
||||
cmake_d="$cmake_d -D USE_OCIO=OFF"
|
||||
|
||||
if [ "$USE_CXX11" = true ]; then
|
||||
cmake_d="$cmake_d -D OIIO_BUILD_CPP11=ON"
|
||||
fi
|
||||
|
||||
if file /bin/cp | grep -q '32-bit'; then
|
||||
cflags="-fPIC -m32 -march=i686"
|
||||
else
|
||||
@@ -1833,6 +1867,9 @@ compile_OSL() {
|
||||
cmake_d="$cmake_d -D OSL_BUILD_PLUGINS=OFF"
|
||||
cmake_d="$cmake_d -D OSL_BUILD_TESTS=OFF"
|
||||
cmake_d="$cmake_d -D USE_SIMD=sse2"
|
||||
if [ "$USE_CXX11" = true ]; then
|
||||
cmake_d="$cmake_d -D OSL_BUILD_CPP11=1"
|
||||
fi
|
||||
|
||||
#~ cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
|
||||
|
||||
@@ -2191,9 +2228,6 @@ compile_ALEMBIC() {
|
||||
return
|
||||
fi
|
||||
|
||||
compile_HDF5
|
||||
PRINT ""
|
||||
|
||||
# To be changed each time we make edits that would modify the compiled result!
|
||||
alembic_magic=2
|
||||
_init_alembic
|
||||
@@ -2221,6 +2255,12 @@ compile_ALEMBIC() {
|
||||
|
||||
cmake_d="-D CMAKE_INSTALL_PREFIX=$_inst"
|
||||
|
||||
# Without Boost or TR1, Alembic requires C++11.
|
||||
if [ "$USE_CXX11" != true ]; then
|
||||
cmake_d="$cmake_d -D ALEMBIC_LIB_USES_BOOST=ON"
|
||||
cmake_d="$cmake_d -D ALEMBIC_LIB_USES_TR1=OFF"
|
||||
fi
|
||||
|
||||
if [ -d $INST/boost ]; then
|
||||
cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost"
|
||||
cmake_d="$cmake_d -D USE_STATIC_BOOST=ON"
|
||||
@@ -2240,8 +2280,6 @@ compile_ALEMBIC() {
|
||||
cmake_d="$cmake_d -D USE_STATIC_HDF5=OFF"
|
||||
cmake_d="$cmake_d -D ALEMBIC_ILMBASE_LINK_STATIC=OFF"
|
||||
cmake_d="$cmake_d -D ALEMBIC_SHARED_LIBS=OFF"
|
||||
cmake_d="$cmake_d -D ALEMBIC_LIB_USES_BOOST=ON"
|
||||
cmake_d="$cmake_d -D ALEMBIC_LIB_USES_TR1=OFF"
|
||||
INFO "ILMBASE_ROOT=$INST/openexr"
|
||||
fi
|
||||
|
||||
@@ -2435,7 +2473,7 @@ compile_FFmpeg() {
|
||||
--enable-avfilter --disable-vdpau \
|
||||
--disable-bzlib --disable-libgsm --disable-libspeex \
|
||||
--enable-pthreads --enable-zlib --enable-stripping --enable-runtime-cpudetect \
|
||||
--disable-vaapi --disable-libfaac --disable-nonfree --enable-gpl \
|
||||
--disable-vaapi --disable-nonfree --enable-gpl \
|
||||
--disable-postproc --disable-librtmp --disable-libopencore-amrnb \
|
||||
--disable-libopencore-amrwb --disable-libdc1394 --disable-version3 --disable-outdev=sdl \
|
||||
--disable-libxcb \
|
||||
@@ -2562,8 +2600,9 @@ install_DEB() {
|
||||
git libfreetype6-dev libx11-dev flex bison libtbb-dev libxxf86vm-dev \
|
||||
libxcursor-dev libxi-dev wget libsqlite3-dev libxrandr-dev libxinerama-dev \
|
||||
libbz2-dev libncurses5-dev libssl-dev liblzma-dev libreadline-dev $OPENJPEG_DEV \
|
||||
libopenal-dev libglew-dev libglewmx-dev yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV \
|
||||
libopenal-dev libglew-dev yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV \
|
||||
libsdl1.2-dev libfftw3-dev patch bzip2 libxml2-dev libtinyxml-dev libjemalloc-dev"
|
||||
# libglewmx-dev (broken in deb testing currently...)
|
||||
|
||||
OPENJPEG_USE=true
|
||||
VORBIS_USE=true
|
||||
@@ -3997,9 +4036,6 @@ install_OTHER() {
|
||||
fi
|
||||
|
||||
if [ "$_do_compile_llvm" = true ]; then
|
||||
install_packages_DEB libffi-dev
|
||||
# LLVM can't find the debian ffi header dir
|
||||
_FFI_INCLUDE_DIR=`dpkg -L libffi-dev | grep -e ".*/ffi.h" | sed -r 's/(.*)\/ffi.h/\1/'`
|
||||
PRINT ""
|
||||
compile_LLVM
|
||||
have_llvm=true
|
||||
@@ -4018,7 +4054,6 @@ install_OTHER() {
|
||||
|
||||
if [ "$_do_compile_osl" = true ]; then
|
||||
if [ "$have_llvm" = true ]; then
|
||||
install_packages_DEB flex bison libtbb-dev
|
||||
PRINT ""
|
||||
compile_OSL
|
||||
else
|
||||
@@ -4037,7 +4072,6 @@ install_OTHER() {
|
||||
fi
|
||||
|
||||
if [ "$_do_compile_osd" = true ]; then
|
||||
install_packages_DEB flex bison libtbb-dev
|
||||
PRINT ""
|
||||
compile_OSD
|
||||
fi
|
||||
@@ -4054,10 +4088,6 @@ install_OTHER() {
|
||||
fi
|
||||
|
||||
if [ "$_do_compile_collada" = true ]; then
|
||||
install_packages_DEB libpcre3-dev
|
||||
# Find path to libxml shared lib...
|
||||
_XML2_LIB=`dpkg -L libxml2-dev | grep -e ".*/libxml2.so"`
|
||||
# No package
|
||||
PRINT ""
|
||||
compile_OpenCOLLADA
|
||||
fi
|
||||
@@ -4142,16 +4172,6 @@ print_info_ffmpeglink() {
|
||||
}
|
||||
|
||||
print_info() {
|
||||
PRINT ""
|
||||
PRINT ""
|
||||
WARNING "****WARNING****"
|
||||
PRINT "If you are experiencing issues building Blender, _*TRY A FRESH, CLEAN BUILD FIRST*_!"
|
||||
PRINT "The same goes for install_deps itself, if you encounter issues, please first erase everything in $SRC and $INST"
|
||||
PRINT "(provided obviously you did not add anything yourself in those dirs!), and run install_deps.sh again!"
|
||||
PRINT "Often, changes in the libs built by this script, or in your distro package, cannot be handled simply, so..."
|
||||
PRINT ""
|
||||
PRINT "You may also try to use the '--build-foo' options to bypass your distribution's packages"
|
||||
PRINT "for some troublesome/buggy libraries..."
|
||||
PRINT ""
|
||||
PRINT ""
|
||||
PRINT "Ran with:"
|
||||
@@ -4164,6 +4184,12 @@ print_info() {
|
||||
_buildargs="$_buildargs -U *OPENCOLORIO* -U *OPENEXR* -U *OPENIMAGEIO* -U *LLVM* -U *CYCLES*"
|
||||
_buildargs="$_buildargs -U *OPENSUBDIV* -U *OPENVDB* -U *COLLADA* -U *FFMPEG* -U *ALEMBIC*"
|
||||
|
||||
if [ "$USE_CXX11" = true ]; then
|
||||
_1="-D WITH_CXX11=ON"
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
fi
|
||||
|
||||
_1="-D WITH_CODEC_SNDFILE=ON"
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
@@ -4219,7 +4245,7 @@ print_info() {
|
||||
PRINT " $_3"
|
||||
_buildargs="$_buildargs $_1 $_2 $_3"
|
||||
if [ -d $INST/osl ]; then
|
||||
_1="-D CYCLES_OSL=$INST/osl"
|
||||
_1="-D OSL_ROOT_DIR=$INST/osl"
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
fi
|
||||
@@ -4327,3 +4353,6 @@ PRINT ""
|
||||
# Switch back to user language.
|
||||
LANG=LANG_BACK
|
||||
export LANG
|
||||
|
||||
CXXFLAGS=$CXXFLAGS_BACK
|
||||
export CXXFLAGS
|
||||
|
@@ -4,10 +4,10 @@
|
||||
# <pep8 compliant>
|
||||
|
||||
# List of the branches being built automatically overnight
|
||||
NIGHT_SCHEDULE_BRANCHES = [None]
|
||||
NIGHT_SCHEDULE_BRANCHES = [None, "blender2.8"]
|
||||
|
||||
# List of the branches available for force build
|
||||
FORCE_SCHEDULE_BRANCHES = ["master", "gooseberry", "experimental-build"]
|
||||
FORCE_SCHEDULE_BRANCHES = ["master", "blender2.8", "experimental-build"]
|
||||
|
||||
"""
|
||||
Stock Twisted directory lister doesn't provide any information about last file
|
||||
@@ -94,6 +94,7 @@ all_repositories = {
|
||||
r'git://git.blender.org/blender-translations.git': 'blender-translations',
|
||||
r'git://git.blender.org/blender-addons.git': 'blender-addons',
|
||||
r'git://git.blender.org/blender-addons-contrib.git': 'blender-addons-contrib',
|
||||
r'git://git.blender.org/blender-dev-tools.git': 'blender-dev-tools',
|
||||
r'https://svn.blender.org/svnroot/bf-blender/': 'lib svn',
|
||||
}
|
||||
|
||||
@@ -126,8 +127,16 @@ def schedule_force_build(name):
|
||||
project=forcesched.FixedParameter(name="project", default="", hide=True)),
|
||||
# For now, hide other codebases.
|
||||
forcesched.CodebaseParameter(hide=True, codebase="blender-translations"),
|
||||
forcesched.CodebaseParameter(hide=True, codebase="blender-addons"),
|
||||
forcesched.CodebaseParameter(
|
||||
codebase="blender-addons",
|
||||
branch=forcesched.ChoiceStringParameter(
|
||||
name="branch", choices=["master", "blender2.8"], default="master"),
|
||||
repository=forcesched.FixedParameter(name="repository", default="", hide=True),
|
||||
project=forcesched.FixedParameter(name="project", default="", hide=True),
|
||||
revision=forcesched.FixedParameter(name="revision", default="", hide=True),
|
||||
),
|
||||
forcesched.CodebaseParameter(hide=True, codebase="blender-addons-contrib"),
|
||||
forcesched.CodebaseParameter(hide=True, codebase="blender-dev-tools"),
|
||||
forcesched.CodebaseParameter(hide=True, codebase="lib svn")],
|
||||
properties=[]))
|
||||
|
||||
@@ -137,12 +146,17 @@ def schedule_build(name, hour, minute=0):
|
||||
scheduler_name = "nightly " + name
|
||||
if current_branch:
|
||||
scheduler_name += ' ' + current_branch
|
||||
# Use special addons submodule branch when building blender2.8 branch.
|
||||
addons_branch = "master"
|
||||
if current_branch == "blender2.8":
|
||||
addons_branch = "blender2.8"
|
||||
c['schedulers'].append(timed.Nightly(name=scheduler_name,
|
||||
codebases={
|
||||
"blender": {"repository": ""},
|
||||
"blender-translations": {"repository": "", "branch": "master"},
|
||||
"blender-addons": {"repository": "", "branch": "master"},
|
||||
"blender-addons": {"repository": "", "branch": addons_branch},
|
||||
"blender-addons-contrib": {"repository": "", "branch": "master"},
|
||||
"blender-dev-tools": {"repository": "", "branch": "master"},
|
||||
"lib svn": {"repository": "", "branch": "trunk"}},
|
||||
branch=current_branch,
|
||||
builderNames=[name],
|
||||
@@ -222,8 +236,7 @@ def git_step(branch=''):
|
||||
|
||||
|
||||
def git_submodules_update():
|
||||
command = ['git', 'submodule', 'foreach', '--recursive',
|
||||
'git', 'pull', 'origin', 'master']
|
||||
command = ['git', 'submodule', 'update', '--remote']
|
||||
return ShellCommand(name='Submodules Update',
|
||||
command=command,
|
||||
description='updating',
|
||||
@@ -232,7 +245,10 @@ def git_submodules_update():
|
||||
|
||||
|
||||
def lib_svn_step(dir):
|
||||
return SVN(name='lib svn',
|
||||
name = "lib svn"
|
||||
if dir == "darwin":
|
||||
name = "C++11 lib svn"
|
||||
return SVN(name=name,
|
||||
baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir,
|
||||
codebase='lib svn',
|
||||
mode='update',
|
||||
@@ -261,10 +277,14 @@ def generic_builder(id, libdir='', branch='', rsync=False):
|
||||
f = BuildFactory()
|
||||
if libdir != '':
|
||||
f.addStep(lib_svn_step(libdir))
|
||||
# Special trick to make sure we always have all the libs.
|
||||
if libdir.startswith("darwin"):
|
||||
f.addStep(lib_svn_step("darwin"))
|
||||
|
||||
for submodule in ('blender-translations',
|
||||
'blender-addons',
|
||||
'blender-addons-contrib'):
|
||||
'blender-addons-contrib',
|
||||
'blender-dev-tools'):
|
||||
f.addStep(git_submodule_step(submodule))
|
||||
|
||||
f.addStep(git_step(branch))
|
||||
@@ -282,7 +302,7 @@ def generic_builder(id, libdir='', branch='', rsync=False):
|
||||
f.addStep(FileUpload(name='upload',
|
||||
slavesrc='buildbot_upload.zip',
|
||||
masterdest=filename,
|
||||
maxsize=150 * 1024 * 1024,
|
||||
maxsize=180 * 1024 * 1024,
|
||||
workdir='install'))
|
||||
f.addStep(MasterShellCommand(name='unpack',
|
||||
command=['python2.7', unpack_script, filename],
|
||||
@@ -293,13 +313,14 @@ def generic_builder(id, libdir='', branch='', rsync=False):
|
||||
# Builders
|
||||
|
||||
add_builder(c, 'mac_x86_64_10_6_cmake', 'darwin-9.x.universal', generic_builder, hour=5)
|
||||
add_builder(c, 'linux_glibc211_i686_cmake', '', generic_builder, hour=1)
|
||||
add_builder(c, 'linux_glibc211_x86_64_cmake', '', generic_builder, hour=2)
|
||||
# add_builder(c, 'linux_glibc211_i686_cmake', '', generic_builder, hour=1)
|
||||
# add_builder(c, 'linux_glibc211_x86_64_cmake', '', generic_builder, hour=2)
|
||||
add_builder(c, 'linux_glibc219_i686_cmake', '', generic_builder, hour=3)
|
||||
add_builder(c, 'linux_glibc219_x86_64_cmake', '', generic_builder, hour=4)
|
||||
add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=3)
|
||||
add_builder(c, 'win64_cmake_vc2013', 'win64_vc12', generic_builder, hour=4)
|
||||
add_builder(c, 'win64_cmake_vc2015', 'win64_vc14', generic_builder, hour=5)
|
||||
add_builder(c, 'win32_cmake_vc2015', 'windows_vc14', generic_builder, hour=5)
|
||||
add_builder(c, 'win64_cmake_vc2015', 'win64_vc14', generic_builder, hour=6)
|
||||
|
||||
# STATUS TARGETS
|
||||
#
|
||||
|
@@ -67,6 +67,9 @@ def get_platform(filename):
|
||||
|
||||
|
||||
def get_branch(filename):
|
||||
if filename.startswith("blender-2.8"):
|
||||
return "blender2.8"
|
||||
|
||||
tokens = filename.split("-")
|
||||
branch = ""
|
||||
|
||||
|
@@ -72,8 +72,9 @@ if 'cmake' in builder:
|
||||
# Set up OSX architecture
|
||||
if builder.endswith('x86_64_10_6_cmake'):
|
||||
cmake_extra_options.append('-DCMAKE_OSX_ARCHITECTURES:STRING=x86_64')
|
||||
cmake_extra_options.append('-DCUDA_NVCC_EXECUTABLE=/usr/local/cuda-hack/bin/nvcc')
|
||||
cmake_extra_options.append('-DCUDA_NVCC8_EXECUTABLE=/usr/local/cuda8-hack/bin/nvcc')
|
||||
cmake_extra_options.append('-DWITH_CODEC_QUICKTIME=OFF')
|
||||
cmake_extra_options.append('-DCMAKE_OSX_DEPLOYMENT_TARGET=10.6')
|
||||
|
||||
|
||||
elif builder.startswith('win'):
|
||||
if builder.endswith('_vc2015'):
|
||||
@@ -90,8 +91,6 @@ if 'cmake' in builder:
|
||||
elif builder.startswith('win32'):
|
||||
bits = 32
|
||||
cmake_options.extend(['-G', 'Visual Studio 12 2013'])
|
||||
cmake_extra_options.append('-DCUDA_NVCC_EXECUTABLE:FILEPATH=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v7.5/bin/nvcc.exe')
|
||||
cmake_extra_options.append('-DCUDA_NVCC8_EXECUTABLE:FILEPATH=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/bin/nvcc.exe')
|
||||
|
||||
elif builder.startswith('linux'):
|
||||
tokens = builder.split("_")
|
||||
@@ -111,9 +110,6 @@ if 'cmake' in builder:
|
||||
cuda_chroot_name = 'buildbot_' + deb_name + '_x86_64'
|
||||
targets = ['player', 'blender', 'cuda']
|
||||
|
||||
cmake_extra_options.append('-DCUDA_NVCC_EXECUTABLE=/usr/local/cuda-7.5/bin/nvcc')
|
||||
cmake_extra_options.append('-DCUDA_NVCC8_EXECUTABLE=/usr/local/cuda-8.0/bin/nvcc')
|
||||
|
||||
cmake_options.append("-C" + os.path.join(blender_dir, cmake_config_file))
|
||||
|
||||
# Prepare CMake options needed to configure cuda binaries compilation.
|
||||
@@ -182,10 +178,8 @@ if 'cmake' in builder:
|
||||
print('Condifuration FAILED!')
|
||||
sys.exit(retcode)
|
||||
|
||||
if 'win32' in builder:
|
||||
command = ['msbuild', 'INSTALL.vcxproj', '/Property:PlatformToolset=v120_xp', '/p:Configuration=Release']
|
||||
elif 'win64' in builder:
|
||||
command = ['msbuild', 'INSTALL.vcxproj', '/p:Configuration=Release']
|
||||
if 'win32' in builder or 'win64' in builder:
|
||||
command = ['cmake', '--build', '.', '--target', target_name, '--config', 'Release']
|
||||
else:
|
||||
command = target_chroot_prefix + ['make', '-s', '-j2', target_name]
|
||||
|
||||
|
@@ -111,7 +111,8 @@ if builder.find('cmake') != -1:
|
||||
if builder.endswith('vc2015'):
|
||||
platform += "-vc14"
|
||||
builderified_name = 'blender-{}-{}-{}'.format(blender_full_version, git_hash, platform)
|
||||
if branch != '':
|
||||
# NOTE: Blender 2.8 is already respected by blender_full_version.
|
||||
if branch != '' and branch != 'blender2.8':
|
||||
builderified_name = branch + "-" + builderified_name
|
||||
|
||||
os.rename(result_file, "{}.zip".format(builderified_name))
|
||||
@@ -177,7 +178,8 @@ if builder.find('cmake') != -1:
|
||||
blender_hash,
|
||||
blender_glibc,
|
||||
blender_arch)
|
||||
if branch != '':
|
||||
# NOTE: Blender 2.8 is already respected by blender_full_version.
|
||||
if branch != '' and branch != 'blender2.8':
|
||||
package_name = branch + "-" + package_name
|
||||
|
||||
upload_filename = package_name + ".tar.bz2"
|
||||
|
@@ -1,15 +1,15 @@
|
||||
# - Find Jack library
|
||||
# Find the native Jack includes and library
|
||||
# - Find JACK library
|
||||
# Find the native JACK includes and library
|
||||
# This module defines
|
||||
# JACK_INCLUDE_DIRS, where to find jack.h, Set when
|
||||
# JACK_INCLUDE_DIR is found.
|
||||
# JACK_LIBRARIES, libraries to link against to use Jack.
|
||||
# JACK_ROOT_DIR, The base directory to search for Jack.
|
||||
# JACK_LIBRARIES, libraries to link against to use JACK.
|
||||
# JACK_ROOT_DIR, The base directory to search for JACK.
|
||||
# This can also be an environment variable.
|
||||
# JACK_FOUND, If false, do not try to use Jack.
|
||||
# JACK_FOUND, If false, do not try to use JACK.
|
||||
#
|
||||
# also defined, but not for general use are
|
||||
# JACK_LIBRARY, where to find the Jack library.
|
||||
# JACK_LIBRARY, where to find the JACK library.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Blender Foundation.
|
||||
|
@@ -45,7 +45,7 @@ macro(BLENDER_SRC_GTEST_EX NAME SRC EXTRA_LIBS DO_ADD_TEST)
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${TESTS_OUTPUT_DIR}"
|
||||
INCLUDE_DIRECTORIES "${TEST_INC}")
|
||||
if(${DO_ADD_TEST})
|
||||
add_test(${NAME}_test ${TESTS_OUTPUT_DIR}/${NAME}_test)
|
||||
add_test(NAME ${NAME}_test COMMAND ${TESTS_OUTPUT_DIR}/${NAME}_test WORKING_DIRECTORY $<TARGET_FILE_DIR:blender>)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
@@ -27,13 +27,12 @@ if(EXISTS ${SOURCE_DIR}/.git)
|
||||
OUTPUT_VARIABLE MY_WC_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(COMMAND git branch --list master --contains ${MY_WC_HASH}
|
||||
execute_process(COMMAND git branch --list master blender-v* --contains ${MY_WC_HASH}
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
OUTPUT_VARIABLE _git_contains_check
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
STRING(REGEX REPLACE "^[ \t]+" "" _git_contains_check "${_git_contains_check}")
|
||||
if(_git_contains_check STREQUAL "master")
|
||||
if(NOT _git_contains_check STREQUAL "")
|
||||
set(MY_WC_BRANCH "master")
|
||||
else()
|
||||
execute_process(COMMAND git show-ref --tags -d
|
||||
@@ -48,6 +47,22 @@ if(EXISTS ${SOURCE_DIR}/.git)
|
||||
|
||||
if(_git_tag_hashes MATCHES "${_git_head_hash}")
|
||||
set(MY_WC_BRANCH "master")
|
||||
else()
|
||||
execute_process(COMMAND git branch --contains ${MY_WC_HASH}
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
OUTPUT_VARIABLE _git_contains_branches
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REGEX REPLACE "^\\*[ \t]+" "" _git_contains_branches "${_git_contains_branches}")
|
||||
string(REGEX REPLACE "[\r\n]+" ";" _git_contains_branches "${_git_contains_branches}")
|
||||
string(REGEX REPLACE ";[ \t]+" ";" _git_contains_branches "${_git_contains_branches}")
|
||||
foreach(_branch ${_git_contains_branches})
|
||||
if(NOT "${_branch}" MATCHES "\\(HEAD.*")
|
||||
set(MY_WC_BRANCH "${_branch}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
unset(_branch)
|
||||
unset(_git_contains_branches)
|
||||
endif()
|
||||
|
||||
unset(_git_tag_hashes)
|
||||
|
@@ -12,6 +12,7 @@ set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OPENSUBDIV ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS ON CACHE BOOL "" FORCE)
|
||||
|
@@ -16,6 +16,7 @@ set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OSL OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_LLVM OFF CACHE BOOL "" FORCE)
|
||||
@@ -48,6 +49,7 @@ set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENCOLORIO OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENIMAGEIO OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_RAYOPTIMIZATION OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_SDL OFF CACHE BOOL "" FORCE)
|
||||
|
79
build_files/cmake/config/blender_release.cmake
Normal file
79
build_files/cmake/config/blender_release.cmake
Normal file
@@ -0,0 +1,79 @@
|
||||
# Turn everything ON thats expected for an official release builds.
|
||||
#
|
||||
# Example usage:
|
||||
# cmake -C../blender/build_files/cmake/config/blender_release.cmake ../blender
|
||||
#
|
||||
|
||||
set(WITH_ALEMBIC ON CACHE BOOL "" FORCE)
|
||||
set(WITH_BUILDINFO ON CACHE BOOL "" FORCE)
|
||||
set(WITH_BULLET ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OPENSUBDIV ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS ON CACHE BOOL "" FORCE)
|
||||
set(WITH_GAMEENGINE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_GHOST_XDND ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_FRAMESERVER ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE)
|
||||
set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE)
|
||||
set(WITH_INTERNATIONAL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_JACK ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LZMA ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LZO ON CACHE BOOL "" FORCE)
|
||||
set(WITH_MOD_BOOLEAN ON CACHE BOOL "" FORCE)
|
||||
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
|
||||
set(WITH_MOD_REMESH ON CACHE BOOL "" FORCE)
|
||||
set(WITH_MOD_SMOKE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_MOD_OCEANSIM ON CACHE BOOL "" FORCE)
|
||||
set(WITH_AUDASPACE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENAL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENMP ON CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
|
||||
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_RAYOPTIMIZATION ON CACHE BOOL "" FORCE)
|
||||
set(WITH_SDL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_X11_XINPUT ON CACHE BOOL "" FORCE)
|
||||
set(WITH_X11_XF86VMODE ON CACHE BOOL "" FORCE)
|
||||
|
||||
set(WITH_PLAYER ON CACHE BOOL "" FORCE)
|
||||
set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_20;sm_21;sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61 CACHE STRING "" FORCE)
|
||||
|
||||
# platform dependent options
|
||||
if(UNIX AND NOT APPLE)
|
||||
set(WITH_JACK ON CACHE BOOL "" FORCE)
|
||||
set(WITH_DOC_MANPAGE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
|
||||
elseif(WIN32)
|
||||
set(WITH_JACK OFF CACHE BOOL "" FORCE)
|
||||
if(NOT CMAKE_COMPILER_IS_GNUCC)
|
||||
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
|
||||
else()
|
||||
# MinGW exceptions
|
||||
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OSL OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
elseif(APPLE)
|
||||
set(WITH_JACK ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
@@ -415,15 +415,8 @@ function(setup_liblinks
|
||||
if(WITH_OPENCOLORIO)
|
||||
target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_OPENSUBDIV)
|
||||
if(WIN32 AND NOT UNIX)
|
||||
file_list_suffix(OPENSUBDIV_LIBRARIES_DEBUG "${OPENSUBDIV_LIBRARIES}" "_d")
|
||||
target_link_libraries_debug(${target} "${OPENSUBDIV_LIBRARIES_DEBUG}")
|
||||
target_link_libraries_optimized(${target} "${OPENSUBDIV_LIBRARIES}")
|
||||
unset(OPENSUBDIV_LIBRARIES_DEBUG)
|
||||
else()
|
||||
if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
|
||||
target_link_libraries(${target} ${OPENSUBDIV_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_OPENVDB)
|
||||
target_link_libraries(${target} ${OPENVDB_LIBRARIES} ${TBB_LIBRARIES})
|
||||
@@ -518,7 +511,8 @@ function(setup_liblinks
|
||||
target_link_libraries(${target}
|
||||
${BLENDER_GL_LIBRARIES})
|
||||
|
||||
target_link_libraries(${target} ${PLATFORM_LINKLIBS} ${CMAKE_DL_LIBS})
|
||||
#target_link_libraries(${target} ${PLATFORM_LINKLIBS} ${CMAKE_DL_LIBS})
|
||||
target_link_libraries(${target} ${PLATFORM_LINKLIBS})
|
||||
endfunction()
|
||||
|
||||
|
||||
@@ -603,6 +597,8 @@ function(SETUP_BLENDER_SORTED_LIBS)
|
||||
bf_modifiers
|
||||
bf_bmesh
|
||||
bf_gpu
|
||||
bf_draw
|
||||
bf_intern_gawain
|
||||
bf_blenloader
|
||||
bf_blenkernel
|
||||
bf_physics
|
||||
@@ -745,7 +741,7 @@ function(SETUP_BLENDER_SORTED_LIBS)
|
||||
list(APPEND BLENDER_SORTED_LIBS bf_intern_gpudirect)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
|
||||
list(APPEND BLENDER_SORTED_LIBS bf_intern_opensubdiv)
|
||||
endif()
|
||||
|
||||
@@ -1580,24 +1576,24 @@ macro(openmp_delayload
|
||||
endmacro()
|
||||
|
||||
MACRO(WINDOWS_SIGN_TARGET target)
|
||||
if (WITH_WINDOWS_CODESIGN)
|
||||
if (!SIGNTOOL_EXE)
|
||||
if(WITH_WINDOWS_CODESIGN)
|
||||
if(!SIGNTOOL_EXE)
|
||||
error("Codesigning is enabled, but signtool is not found")
|
||||
else()
|
||||
if (WINDOWS_CODESIGN_PFX_PASSWORD)
|
||||
if(WINDOWS_CODESIGN_PFX_PASSWORD)
|
||||
set(CODESIGNPASSWORD /p ${WINDOWS_CODESIGN_PFX_PASSWORD})
|
||||
else()
|
||||
if ($ENV{PFXPASSWORD})
|
||||
if($ENV{PFXPASSWORD})
|
||||
set(CODESIGNPASSWORD /p $ENV{PFXPASSWORD})
|
||||
else()
|
||||
message( FATAL_ERROR "WITH_WINDOWS_CODESIGN is on but WINDOWS_CODESIGN_PFX_PASSWORD not set, and environment variable PFXPASSWORD not found, unable to sign code.")
|
||||
message(FATAL_ERROR "WITH_WINDOWS_CODESIGN is on but WINDOWS_CODESIGN_PFX_PASSWORD not set, and environment variable PFXPASSWORD not found, unable to sign code.")
|
||||
endif()
|
||||
endif()
|
||||
add_custom_command(TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND ${SIGNTOOL_EXE} sign /f ${WINDOWS_CODESIGN_PFX} ${CODESIGNPASSWORD} $<TARGET_FILE:${target}>
|
||||
VERBATIM
|
||||
)
|
||||
POST_BUILD
|
||||
COMMAND ${SIGNTOOL_EXE} sign /f ${WINDOWS_CODESIGN_PFX} ${CODESIGNPASSWORD} $<TARGET_FILE:${target}>
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
ENDMACRO()
|
||||
ENDMACRO()
|
||||
|
@@ -1,5 +1,7 @@
|
||||
set(PROJECT_DESCRIPTION "Blender is a very fast and versatile 3D modeller/renderer.")
|
||||
set(PROJECT_COPYRIGHT "Copyright (C) 2001-2012 Blender Foundation")
|
||||
string(TIMESTAMP CURRENT_YEAR "%Y")
|
||||
|
||||
set(PROJECT_DESCRIPTION "Blender is the free and open source 3D creation suite software.")
|
||||
set(PROJECT_COPYRIGHT "Copyright (C) 2001-${CURRENT_YEAR} Blender Foundation")
|
||||
set(PROJECT_CONTACT "foundation@blender.org")
|
||||
set(PROJECT_VENDOR "Blender Foundation")
|
||||
|
||||
@@ -38,8 +40,8 @@ unset(MY_WC_HASH)
|
||||
# Force Package Name
|
||||
execute_process(COMMAND date "+%Y%m%d" OUTPUT_VARIABLE CPACK_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)
|
||||
if (MSVC)
|
||||
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
if(MSVC)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(PACKAGE_ARCH windows64)
|
||||
else()
|
||||
set(PACKAGE_ARCH windows32)
|
||||
@@ -48,7 +50,7 @@ else(MSVC)
|
||||
set(PACKAGE_ARCH ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
if (CPACK_OVERRIDE_PACKAGENAME)
|
||||
if(CPACK_OVERRIDE_PACKAGENAME)
|
||||
set(CPACK_PACKAGE_FILE_NAME ${CPACK_OVERRIDE_PACKAGENAME}-${PACKAGE_ARCH})
|
||||
else()
|
||||
set(CPACK_PACKAGE_FILE_NAME ${PROJECT_NAME_LOWER}-${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}-git${CPACK_DATE}.${BUILD_REV}-${PACKAGE_ARCH})
|
||||
@@ -97,6 +99,8 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_EXECUTABLES "blender" "blender")
|
||||
set(CPACK_CREATE_DESKTOP_LINKS "blender" "blender")
|
||||
|
||||
include(CPack)
|
||||
|
||||
# Target for build_archive.py script, to automatically pass along
|
||||
@@ -133,4 +137,3 @@ unset(MINOR_VERSION)
|
||||
unset(PATCH_VERSION)
|
||||
|
||||
unset(BUILD_REV)
|
||||
|
||||
|
@@ -23,8 +23,14 @@
|
||||
|
||||
# Libraries configuration for Apple.
|
||||
|
||||
set(MACOSX_DEPLOYMENT_TARGET "10.9")
|
||||
|
||||
if(NOT DEFINED LIBDIR)
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-9.x.universal)
|
||||
if(WITH_CXX11)
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin)
|
||||
else()
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-9.x.universal)
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
||||
endif()
|
||||
@@ -50,15 +56,14 @@ if(WITH_ALEMBIC)
|
||||
set(ALEMBIC_LIBRARIES Alembic)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
|
||||
set(OPENSUBDIV ${LIBDIR}/opensubdiv)
|
||||
set(OPENSUBDIV_LIBPATH ${OPENSUBDIV}/lib)
|
||||
find_library(OSL_LIB_UTIL NAMES osdutil PATHS ${OPENSUBDIV_LIBPATH})
|
||||
find_library(OSL_LIB_CPU NAMES osdCPU PATHS ${OPENSUBDIV_LIBPATH})
|
||||
find_library(OSL_LIB_GPU NAMES osdGPU PATHS ${OPENSUBDIV_LIBPATH})
|
||||
find_library(OSD_LIB_CPU NAMES osdCPU PATHS ${OPENSUBDIV_LIBPATH})
|
||||
find_library(OSD_LIB_GPU NAMES osdGPU PATHS ${OPENSUBDIV_LIBPATH})
|
||||
set(OPENSUBDIV_INCLUDE_DIR ${OPENSUBDIV}/include)
|
||||
set(OPENSUBDIV_INCLUDE_DIRS ${OPENSUBDIV_INCLUDE_DIR})
|
||||
list(APPEND OPENSUBDIV_LIBRARIES ${OSL_LIB_UTIL} ${OSL_LIB_CPU} ${OSL_LIB_GPU})
|
||||
list(APPEND OPENSUBDIV_LIBRARIES ${OSD_LIB_CPU} ${OSD_LIB_GPU})
|
||||
endif()
|
||||
|
||||
if(WITH_JACK)
|
||||
@@ -75,7 +80,7 @@ if(WITH_CODEC_SNDFILE)
|
||||
set(SNDFILE ${LIBDIR}/sndfile)
|
||||
set(SNDFILE_INCLUDE_DIRS ${SNDFILE}/include)
|
||||
set(SNDFILE_LIBRARIES sndfile FLAC ogg vorbis vorbisenc)
|
||||
set(SNDFILE_LIBPATH ${SNDFILE}/lib ${FFMPEG}/lib) # TODO, deprecate
|
||||
set(SNDFILE_LIBPATH ${SNDFILE}/lib ${LIBDIR}/ffmpeg/lib) # TODO, deprecate
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON)
|
||||
@@ -133,7 +138,17 @@ if(WITH_IMAGE_OPENEXR)
|
||||
set(OPENEXR ${LIBDIR}/openexr)
|
||||
set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include)
|
||||
set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR}/include/OpenEXR)
|
||||
set(OPENEXR_LIBRARIES Iex Half IlmImf Imath IlmThread)
|
||||
if(WITH_CXX11)
|
||||
set(OPENEXR_POSTFIX -2_2)
|
||||
else()
|
||||
set(OPENEXR_POSTFIX)
|
||||
endif()
|
||||
set(OPENEXR_LIBRARIES
|
||||
Iex${OPENEXR_POSTFIX}
|
||||
Half
|
||||
IlmImf${OPENEXR_POSTFIX}
|
||||
Imath${OPENEXR_POSTFIX}
|
||||
IlmThread${OPENEXR_POSTFIX})
|
||||
set(OPENEXR_LIBPATH ${OPENEXR}/lib)
|
||||
endif()
|
||||
|
||||
@@ -144,9 +159,22 @@ if(WITH_CODEC_FFMPEG)
|
||||
avcodec avdevice avformat avutil
|
||||
mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg
|
||||
)
|
||||
if(WITH_CXX11)
|
||||
set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} schroedinger orc vpx webp swresample)
|
||||
endif()
|
||||
set(FFMPEG_LIBPATH ${FFMPEG}/lib)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENJPEG OR WITH_CODEC_FFMPEG)
|
||||
# use openjpeg from libdir that is linked into ffmpeg
|
||||
if(WITH_CXX11)
|
||||
set(OPENJPEG ${LIBDIR}/openjpeg)
|
||||
set(WITH_SYSTEM_OPENJPEG ON)
|
||||
set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include)
|
||||
set(OPENJPEG_LIBRARIES ${OPENJPEG}/lib/libopenjpeg.a)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_library(SYSTEMSTUBS_LIBRARY
|
||||
NAMES
|
||||
SystemStubs
|
||||
@@ -224,7 +252,11 @@ if(WITH_SDL)
|
||||
set(SDL_INCLUDE_DIR ${SDL}/include)
|
||||
set(SDL_LIBRARY SDL2)
|
||||
set(SDL_LIBPATH ${SDL}/lib)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -lazy_framework ForceFeedback")
|
||||
if(WITH_CXX11)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework ForceFeedback")
|
||||
else()
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -lazy_framework ForceFeedback")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(PNG "${LIBDIR}/png")
|
||||
@@ -245,22 +277,27 @@ endif()
|
||||
if(WITH_BOOST)
|
||||
set(BOOST ${LIBDIR}/boost)
|
||||
set(BOOST_INCLUDE_DIR ${BOOST}/include)
|
||||
if(WITH_CXX11)
|
||||
set(BOOST_POSTFIX)
|
||||
else()
|
||||
set(BOOST_POSTFIX -mt)
|
||||
endif()
|
||||
set(BOOST_LIBRARIES
|
||||
boost_date_time-mt
|
||||
boost_filesystem-mt
|
||||
boost_regex-mt
|
||||
boost_system-mt
|
||||
boost_thread-mt
|
||||
boost_wave-mt
|
||||
boost_date_time${BOOST_POSTFIX}
|
||||
boost_filesystem${BOOST_POSTFIX}
|
||||
boost_regex${BOOST_POSTFIX}
|
||||
boost_system${BOOST_POSTFIX}
|
||||
boost_thread${BOOST_POSTFIX}
|
||||
boost_wave${BOOST_POSTFIX}
|
||||
)
|
||||
if(WITH_INTERNATIONAL)
|
||||
list(APPEND BOOST_LIBRARIES boost_locale-mt)
|
||||
list(APPEND BOOST_LIBRARIES boost_locale${BOOST_POSTFIX})
|
||||
endif()
|
||||
if(WITH_CYCLES_NETWORK)
|
||||
list(APPEND BOOST_LIBRARIES boost_serialization-mt)
|
||||
list(APPEND BOOST_LIBRARIES boost_serialization${BOOST_POSTFIX})
|
||||
endif()
|
||||
if(WITH_OPENVDB)
|
||||
list(APPEND BOOST_LIBRARIES boost_iostreams-mt)
|
||||
list(APPEND BOOST_LIBRARIES boost_iostreams${BOOST_POSTFIX})
|
||||
endif()
|
||||
set(BOOST_LIBPATH ${BOOST}/lib)
|
||||
set(BOOST_DEFINITIONS)
|
||||
@@ -281,6 +318,9 @@ if(WITH_OPENIMAGEIO)
|
||||
${OPENEXR_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
)
|
||||
if(WITH_CXX11)
|
||||
set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARIES} ${LIBDIR}/ffmpeg/lib/libwebp.a)
|
||||
endif()
|
||||
set(OPENIMAGEIO_LIBPATH
|
||||
${OPENIMAGEIO}/lib
|
||||
${JPEG_LIBPATH}
|
||||
|
@@ -344,7 +344,7 @@ if(WITH_LLVM OR WITH_SDL_DYNLOAD)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
|
||||
find_package_wrapper(OpenSubdiv)
|
||||
|
||||
set(OPENSUBDIV_LIBRARIES ${OPENSUBDIV_LIBRARIES})
|
||||
@@ -352,6 +352,7 @@ if(WITH_OPENSUBDIV)
|
||||
|
||||
if(NOT OPENSUBDIV_FOUND)
|
||||
set(WITH_OPENSUBDIV OFF)
|
||||
set(WITH_CYCLES_OPENSUBDIV OFF)
|
||||
message(STATUS "OpenSubdiv not found")
|
||||
endif()
|
||||
endif()
|
||||
@@ -383,17 +384,18 @@ add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
|
||||
|
||||
# use ld.gold linker if available, could make optional
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version
|
||||
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||
if("${LD_VERSION}" MATCHES "GNU gold")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=gold")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold")
|
||||
else()
|
||||
message(STATUS "GNU gold linker isn't available, using the default system linker.")
|
||||
if(WITH_LINKER_GOLD)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version
|
||||
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||
if("${LD_VERSION}" MATCHES "GNU gold")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=gold")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold")
|
||||
else()
|
||||
message(STATUS "GNU gold linker isn't available, using the default system linker.")
|
||||
endif()
|
||||
unset(LD_VERSION)
|
||||
endif()
|
||||
unset(LD_VERSION)
|
||||
|
||||
# CLang is the same as GCC for now.
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
|
@@ -33,26 +33,28 @@ endmacro()
|
||||
macro(windows_find_package package_name
|
||||
)
|
||||
if(WITH_WINDOWS_FIND_MODULES)
|
||||
find_package( ${package_name})
|
||||
find_package(${package_name})
|
||||
endif(WITH_WINDOWS_FIND_MODULES)
|
||||
endmacro()
|
||||
|
||||
add_definitions(-DWIN32)
|
||||
# Minimum MSVC Version
|
||||
if(MSVC_VERSION EQUAL 1800)
|
||||
set(_min_ver "18.0.31101")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${_min_ver})
|
||||
message(FATAL_ERROR
|
||||
"Visual Studio 2013 (Update 4, ${_min_ver}) required, "
|
||||
"found (${CMAKE_CXX_COMPILER_VERSION})")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
if(MSVC_VERSION EQUAL 1800)
|
||||
set(_min_ver "18.0.31101")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${_min_ver})
|
||||
message(FATAL_ERROR
|
||||
"Visual Studio 2013 (Update 4, ${_min_ver}) required, "
|
||||
"found (${CMAKE_CXX_COMPILER_VERSION})")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(MSVC_VERSION EQUAL 1900)
|
||||
set(_min_ver "19.0.24210")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${_min_ver})
|
||||
message(FATAL_ERROR
|
||||
"Visual Studio 2015 (Update 3, ${_min_ver}) required, "
|
||||
"found (${CMAKE_CXX_COMPILER_VERSION})")
|
||||
if(MSVC_VERSION EQUAL 1900)
|
||||
set(_min_ver "19.0.24210")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${_min_ver})
|
||||
message(FATAL_ERROR
|
||||
"Visual Studio 2015 (Update 3, ${_min_ver}) required, "
|
||||
"found (${CMAKE_CXX_COMPILER_VERSION})")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
unset(_min_ver)
|
||||
@@ -110,7 +112,7 @@ set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221")
|
||||
|
||||
# MSVC only, Mingw doesnt need
|
||||
if(CMAKE_CL_64)
|
||||
set(PLATFORM_LINKFLAGS "/MACHINE:X64 /OPT:NOREF ${PLATFORM_LINKFLAGS}")
|
||||
set(PLATFORM_LINKFLAGS "/MACHINE:X64 ${PLATFORM_LINKFLAGS}")
|
||||
else()
|
||||
set(PLATFORM_LINKFLAGS "/MACHINE:IX86 /LARGEADDRESSAWARE ${PLATFORM_LINKFLAGS}")
|
||||
endif()
|
||||
@@ -127,8 +129,10 @@ if(NOT DEFINED LIBDIR)
|
||||
message(STATUS "32 bit compiler detected.")
|
||||
set(LIBDIR_BASE "windows")
|
||||
endif()
|
||||
|
||||
if(MSVC_VERSION EQUAL 1900)
|
||||
if(MSVC_VERSION EQUAL 1910)
|
||||
message(STATUS "Visual Studio 2017 detected.")
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc14)
|
||||
elseif(MSVC_VERSION EQUAL 1900)
|
||||
message(STATUS "Visual Studio 2015 detected.")
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc14)
|
||||
else()
|
||||
@@ -234,14 +238,14 @@ if(WITH_CODEC_FFMPEG)
|
||||
windows_find_package(FFMPEG)
|
||||
if(NOT FFMPEG_FOUND)
|
||||
warn_hardcoded_paths(ffmpeg)
|
||||
set(FFMPEG_LIBRARY_VERSION 55)
|
||||
set(FFMPEG_LIBRARY_VERSION_AVU 52)
|
||||
set(FFMPEG_LIBRARY_VERSION 57)
|
||||
set(FFMPEG_LIBRARY_VERSION_AVU 55)
|
||||
set(FFMPEG_LIBRARIES
|
||||
${LIBDIR}/ffmpeg/lib/avcodec-${FFMPEG_LIBRARY_VERSION}.lib
|
||||
${LIBDIR}/ffmpeg/lib/avformat-${FFMPEG_LIBRARY_VERSION}.lib
|
||||
${LIBDIR}/ffmpeg/lib/avdevice-${FFMPEG_LIBRARY_VERSION}.lib
|
||||
${LIBDIR}/ffmpeg/lib/avutil-${FFMPEG_LIBRARY_VERSION_AVU}.lib
|
||||
${LIBDIR}/ffmpeg/lib/swscale-2.lib
|
||||
${LIBDIR}/ffmpeg/lib/avcodec.lib
|
||||
${LIBDIR}/ffmpeg/lib/avformat.lib
|
||||
${LIBDIR}/ffmpeg/lib/avdevice.lib
|
||||
${LIBDIR}/ffmpeg/lib/avutil.lib
|
||||
${LIBDIR}/ffmpeg/lib/swscale.lib
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -376,6 +380,7 @@ if(WITH_OPENIMAGEIO)
|
||||
set(OPENCOLORIO_DEFINITIONS "-DOCIO_STATIC_BUILD")
|
||||
set(OPENIMAGEIO_IDIFF "${OPENIMAGEIO}/bin/idiff.exe")
|
||||
add_definitions(-DOIIO_STATIC_BUILD)
|
||||
add_definitions(-DOIIO_NO_SSE=1)
|
||||
endif()
|
||||
|
||||
if(WITH_LLVM)
|
||||
@@ -440,11 +445,21 @@ if(WITH_MOD_CLOTH_ELTOPO)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
set(OPENSUBDIV_INCLUDE_DIR ${LIBDIR}/opensubdiv/include)
|
||||
set(OPENSUBDIV_LIBPATH ${LIBDIR}/opensubdiv/lib)
|
||||
set(OPENSUBDIV_LIBRARIES ${OPENSUBDIV_LIBPATH}/osdCPU.lib ${OPENSUBDIV_LIBPATH}/osdGPU.lib)
|
||||
find_package(OpenSubdiv)
|
||||
if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
|
||||
set(OPENSUBDIV_INCLUDE_DIR ${LIBDIR}/opensubdiv/include)
|
||||
set(OPENSUBDIV_LIBPATH ${LIBDIR}/opensubdiv/lib)
|
||||
set(OPENSUBDIV_LIBRARIES optimized ${OPENSUBDIV_LIBPATH}/osdCPU.lib
|
||||
optimized ${OPENSUBDIV_LIBPATH}/osdGPU.lib
|
||||
debug ${OPENSUBDIV_LIBPATH}/osdCPU_d.lib
|
||||
debug ${OPENSUBDIV_LIBPATH}/osdGPU_d.lib
|
||||
)
|
||||
set(OPENSUBDIV_HAS_OPENMP TRUE)
|
||||
set(OPENSUBDIV_HAS_TBB FALSE)
|
||||
set(OPENSUBDIV_HAS_OPENCL TRUE)
|
||||
set(OPENSUBDIV_HAS_CUDA FALSE)
|
||||
set(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK TRUE)
|
||||
set(OPENSUBDIV_HAS_GLSL_COMPUTE TRUE)
|
||||
windows_find_package(OpenSubdiv)
|
||||
endif()
|
||||
|
||||
if(WITH_SDL)
|
||||
|
@@ -6,10 +6,10 @@
|
||||
BASE_DIR="$PWD"
|
||||
|
||||
blender_srcdir=$(dirname -- $0)/../..
|
||||
blender_version=$(grep "BLENDER_VERSION\s" "$blender_srcdir/source/blender/blenkernel/BKE_blender.h" | awk '{print $3}')
|
||||
blender_version_char=$(grep "BLENDER_VERSION_CHAR\s" "$blender_srcdir/source/blender/blenkernel/BKE_blender.h" | awk '{print $3}')
|
||||
blender_version_cycle=$(grep "BLENDER_VERSION_CYCLE\s" "$blender_srcdir/source/blender/blenkernel/BKE_blender.h" | awk '{print $3}')
|
||||
blender_subversion=$(grep "BLENDER_SUBVERSION\s" "$blender_srcdir/source/blender/blenkernel/BKE_blender.h" | awk '{print $3}')
|
||||
blender_version=$(grep "BLENDER_VERSION\s" "$blender_srcdir/source/blender/blenkernel/BKE_blender_version.h" | awk '{print $3}')
|
||||
blender_version_char=$(grep "BLENDER_VERSION_CHAR\s" "$blender_srcdir/source/blender/blenkernel/BKE_blender_version.h" | awk '{print $3}')
|
||||
blender_version_cycle=$(grep "BLENDER_VERSION_CYCLE\s" "$blender_srcdir/source/blender/blenkernel/BKE_blender_version.h" | awk '{print $3}')
|
||||
blender_subversion=$(grep "BLENDER_SUBVERSION\s" "$blender_srcdir/source/blender/blenkernel/BKE_blender_version.h" | awk '{print $3}')
|
||||
|
||||
if [ "$blender_version_cycle" = "release" ] ; then
|
||||
VERSION=$(expr $blender_version / 100).$(expr $blender_version % 100)$blender_version_char
|
||||
|
@@ -187,7 +187,7 @@ The next table describes the information in the file-header.
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<a href="http://en.wikipedia.org/wiki/Endianness">Endianness</a> addresses the way values are ordered in a sequence of bytes(see the <a href="#example-endianess">example</a> below):
|
||||
<a href="https://en.wikipedia.org/wiki/Endianness">Endianness</a> addresses the way values are ordered in a sequence of bytes(see the <a href="#example-endianess">example</a> below):
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
|
@@ -699,7 +699,7 @@ LAYOUT_FILE =
|
||||
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
|
||||
# the reference definitions. This must be a list of .bib files. The .bib
|
||||
# extension is automatically appended if omitted. This requires the bibtex tool
|
||||
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
|
||||
# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
|
||||
# For LaTeX the style of the bibliography can be controlled using
|
||||
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
|
||||
# search path. See also \cite for info how to create references.
|
||||
@@ -1145,7 +1145,7 @@ HTML_EXTRA_FILES =
|
||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
||||
# will adjust the colors in the style sheet and background images according to
|
||||
# this color. Hue is specified as an angle on a colorwheel, see
|
||||
# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
|
||||
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
|
||||
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
|
||||
# purple, and 360 is red again.
|
||||
# Minimum value: 0, maximum value: 359, default value: 220.
|
||||
@@ -1752,7 +1752,7 @@ LATEX_SOURCE_CODE = NO
|
||||
|
||||
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
|
||||
# bibliography, e.g. plainnat, or ieeetr. See
|
||||
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
|
||||
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
|
||||
# The default value is: plain.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
|
@@ -4,7 +4,7 @@ Persistent Handler Example
|
||||
|
||||
By default handlers are freed when loading new files, in some cases you may
|
||||
wan't the handler stay running across multiple files (when the handler is
|
||||
part of an addon for example).
|
||||
part of an add-on for example).
|
||||
|
||||
For this the :data:`bpy.app.handlers.persistent` decorator needs to be used.
|
||||
"""
|
||||
|
@@ -5,7 +5,7 @@ Intro
|
||||
.. warning::
|
||||
|
||||
Most of this object should only be useful if you actually manipulate i18n stuff from Python.
|
||||
If you are a regular addon, you should only bother about :const:`contexts` member,
|
||||
If you are a regular add-on, you should only bother about :const:`contexts` member,
|
||||
and the :func:`register`/:func:`unregister` functions! The :func:`pgettext` family of functions
|
||||
should only be used in rare, specific cases (like e.g. complex "composited" UI strings...).
|
||||
|
||||
@@ -21,11 +21,11 @@ Intro
|
||||
Then, call ``bpy.app.translations.register(__name__, your_dict)`` in your ``register()`` function, and
|
||||
``bpy.app.translations.unregister(__name__)`` in your ``unregister()`` one.
|
||||
|
||||
The ``Manage UI translations`` addon has several functions to help you collect strings to translate, and
|
||||
The ``Manage UI translations`` add-on has several functions to help you collect strings to translate, and
|
||||
generate the needed python code (the translation dictionary), as well as optional intermediary po files
|
||||
if you want some... See
|
||||
`How to Translate Blender <http://wiki.blender.org/index.php/Dev:Doc/Process/Translate_Blender>`_ and
|
||||
`Using i18n in Blender Code <http://wiki.blender.org/index.php/Dev:Source/Interface/Internationalization>`_
|
||||
`How to Translate Blender <https://wiki.blender.org/index.php/Dev:Doc/Process/Translate_Blender>`_ and
|
||||
`Using i18n in Blender Code <https://wiki.blender.org/index.php/Dev:Source/Interface/Internationalization>`_
|
||||
for more info.
|
||||
|
||||
Module References
|
||||
|
@@ -1,10 +1,10 @@
|
||||
bl_info = {
|
||||
"name": "Example Addon Preferences",
|
||||
"name": "Example Add-on Preferences",
|
||||
"author": "Your Name Here",
|
||||
"version": (1, 0),
|
||||
"blender": (2, 65, 0),
|
||||
"location": "SpaceBar Search -> Addon Preferences Example",
|
||||
"description": "Example Addon",
|
||||
"location": "SpaceBar Search -> Add-on Preferences Example",
|
||||
"description": "Example Add-on",
|
||||
"warning": "",
|
||||
"wiki_url": "",
|
||||
"tracker_url": "",
|
||||
@@ -18,7 +18,7 @@ from bpy.props import StringProperty, IntProperty, BoolProperty
|
||||
|
||||
|
||||
class ExampleAddonPreferences(AddonPreferences):
|
||||
# this must match the addon name, use '__package__'
|
||||
# this must match the add-on name, use '__package__'
|
||||
# when defining this in a submodule of a python package.
|
||||
bl_idname = __name__
|
||||
|
||||
@@ -37,7 +37,7 @@ class ExampleAddonPreferences(AddonPreferences):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.label(text="This is a preferences view for our addon")
|
||||
layout.label(text="This is a preferences view for our add-on")
|
||||
layout.prop(self, "filepath")
|
||||
layout.prop(self, "number")
|
||||
layout.prop(self, "boolean")
|
||||
@@ -46,7 +46,7 @@ class ExampleAddonPreferences(AddonPreferences):
|
||||
class OBJECT_OT_addon_prefs_example(Operator):
|
||||
"""Display example preferences"""
|
||||
bl_idname = "object.addon_prefs_example"
|
||||
bl_label = "Addon Preferences Example"
|
||||
bl_label = "Add-on Preferences Example"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
|
@@ -2,9 +2,9 @@
|
||||
Extending Menus
|
||||
+++++++++++++++
|
||||
|
||||
When creating menus for addons you can't reference menus in Blender's default
|
||||
scripts.
|
||||
Instead, the addon can add menu items to existing menus.
|
||||
When creating menus for add-ons you can't reference menus
|
||||
in Blender's default scripts.
|
||||
Instead, the add-on can add menu items to existing menus.
|
||||
|
||||
The function menu_draw acts like :class:`Menu.draw`.
|
||||
"""
|
||||
|
@@ -13,7 +13,7 @@ be animated, accessed from the user interface and from python.
|
||||
definitions are not, this means whenever you load blender the class needs
|
||||
to be registered too.
|
||||
|
||||
This is best done by creating an addon which loads on startup and registers
|
||||
This is best done by creating an add-on which loads on startup and registers
|
||||
your properties.
|
||||
|
||||
.. note::
|
||||
|
@@ -52,6 +52,7 @@ class OffScreenDraw(bpy.types.Operator):
|
||||
@staticmethod
|
||||
def _update_offscreen(context, offscreen):
|
||||
scene = context.scene
|
||||
render_layer = context.render_layer
|
||||
render = scene.render
|
||||
camera = scene.camera
|
||||
|
||||
@@ -65,6 +66,7 @@ class OffScreenDraw(bpy.types.Operator):
|
||||
|
||||
offscreen.draw_view3d(
|
||||
scene,
|
||||
render_layer,
|
||||
context.space_data,
|
||||
context.region,
|
||||
projection_matrix,
|
||||
|
@@ -49,7 +49,7 @@ vec2d[:] = vec3d[:2]
|
||||
|
||||
|
||||
# Vectors support 'swizzle' operations
|
||||
# See http://en.wikipedia.org/wiki/Swizzling_(computer_graphics)
|
||||
# See https://en.wikipedia.org/wiki/Swizzling_(computer_graphics)
|
||||
vec.xyz = vec.zyx
|
||||
vec.xy = vec4d.zw
|
||||
vec.xyz = vec4d.wzz
|
||||
|
@@ -681,7 +681,7 @@ Image classes
|
||||
|
||||
.. attribute:: zbuff
|
||||
|
||||
Use depth component of render as grey scale color - suitable for texture source.
|
||||
Use depth component of render as grayscale color - suitable for texture source.
|
||||
|
||||
:type: bool
|
||||
|
||||
@@ -817,7 +817,7 @@ Image classes
|
||||
|
||||
.. attribute:: zbuff
|
||||
|
||||
Use depth component of viewport as grey scale color - suitable for texture source.
|
||||
Use depth component of viewport as grayscale color - suitable for texture source.
|
||||
|
||||
:type: bool
|
||||
|
||||
@@ -1260,8 +1260,8 @@ Filter classes
|
||||
|
||||
.. class:: FilterGray
|
||||
|
||||
Filter for gray scale effect.
|
||||
Proportions of R, G and B contributions in the output gray scale are 28:151:77.
|
||||
Filter for grayscale effect.
|
||||
Proportions of R, G and B contributions in the output grayscale are 28:151:77.
|
||||
|
||||
.. attribute:: previous
|
||||
|
||||
|
@@ -405,7 +405,7 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
.. note::
|
||||
|
||||
This attribute is experemental and may be removed (but probably wont be).
|
||||
This attribute is experimental and may be removed (but probably wont be).
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -419,7 +419,7 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
.. note::
|
||||
|
||||
This attribute is experemental and may be removed (but probably wont be).
|
||||
This attribute is experimental and may be removed (but probably wont be).
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -453,7 +453,7 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
.. attribute:: childrenRecursive
|
||||
|
||||
all children of this object including childrens children, (read-only).
|
||||
all children of this object including children's children, (read-only).
|
||||
|
||||
:type: :class:`CListValue` of :class:`KX_GameObject`'s
|
||||
|
||||
@@ -536,7 +536,7 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
.. method:: getAxisVect(vect)
|
||||
|
||||
Returns the axis vector rotates by the objects worldspace orientation.
|
||||
Returns the axis vector rotates by the object's worldspace orientation.
|
||||
This is the equivalent of multiplying the vector by the orientation matrix.
|
||||
|
||||
:arg vect: a vector to align the axis.
|
||||
@@ -596,7 +596,7 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
Gets the game object's linear velocity.
|
||||
|
||||
This method returns the game object's velocity through it's centre of mass, ie no angular velocity component.
|
||||
This method returns the game object's velocity through it's center of mass, ie no angular velocity component.
|
||||
|
||||
:arg local:
|
||||
* False: you get the "global" velocity ie: relative to world orientation.
|
||||
@@ -609,7 +609,7 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
Sets the game object's linear velocity.
|
||||
|
||||
This method sets game object's velocity through it's centre of mass,
|
||||
This method sets game object's velocity through it's center of mass,
|
||||
ie no angular velocity component.
|
||||
|
||||
This requires a dynamic object.
|
||||
@@ -814,7 +814,7 @@ base class --- :class:`SCA_IObject`
|
||||
# do something
|
||||
pass
|
||||
|
||||
The face paremeter determines the orientation of the normal.
|
||||
The face parameter determines the orientation of the normal.
|
||||
|
||||
* 0 => hit normal is always oriented towards the ray origin (as if you casted the ray from outside)
|
||||
* 1 => hit normal is the real face normal (only for mesh object, otherwise face has no effect)
|
||||
@@ -911,7 +911,7 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
.. note::
|
||||
|
||||
The gameObject argument has an advantage that it can convert from a mesh with modifiers applied (such as subsurf).
|
||||
The gameObject argument has an advantage that it can convert from a mesh with modifiers applied (such as the Subdivision Surface modifier).
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -919,7 +919,7 @@ base class --- :class:`SCA_IObject`
|
||||
|
||||
.. warning::
|
||||
|
||||
If the object is a part of a combound object it will fail (parent or child)
|
||||
If the object is a part of a compound object it will fail (parent or child)
|
||||
|
||||
.. warning::
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@ The features exposed closely follow the C API,
|
||||
giving python access to the functions used by blenders own mesh editing tools.
|
||||
|
||||
For an overview of BMesh data types and how they reference each other see:
|
||||
`BMesh Design Document <http://wiki.blender.org/index.php/Dev:2.6/Source/Modeling/BMesh/Design>`_ .
|
||||
`BMesh Design Document <https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design>`_ .
|
||||
|
||||
|
||||
.. note::
|
||||
@@ -31,13 +31,12 @@ For an overview of BMesh data types and how they reference each other see:
|
||||
**Disk** and **Radial** data is not exposed by the python api since this is for internal use only.
|
||||
|
||||
|
||||
.. warning::
|
||||
|
||||
TODO items are...
|
||||
.. warning:: TODO items are...
|
||||
|
||||
* add access to BMesh **walkers**
|
||||
* add custom-data manipulation functions add/remove/rename.
|
||||
|
||||
|
||||
Example Script
|
||||
--------------
|
||||
|
||||
|
@@ -204,7 +204,7 @@ Lets say we want to access the texture of a brush via Python, to adjust its ``co
|
||||
|
||||
- Start in the default scene and enable 'Sculpt' mode from the 3D-View header.
|
||||
- From the toolbar expand the **Texture** panel and add a new texture.
|
||||
*Notice the texture button its self doesn't have very useful links (you can check the tool-tips).*
|
||||
*Notice the texture button its self doesn't have very useful links (you can check the tooltips).*
|
||||
- The contrast setting isn't exposed in the sculpt toolbar, so view the texture in the properties panel...
|
||||
|
||||
- In the properties button select the Texture context.
|
||||
|
@@ -18,7 +18,7 @@ amongst our own scripts and make it easier to use python scripts from other proj
|
||||
|
||||
Using our style guide for your own scripts makes it easier if you eventually want to contribute them to blender.
|
||||
|
||||
This style guide is known as pep8 and can be found `here <http://www.python.org/dev/peps/pep-0008>`_
|
||||
This style guide is known as pep8 and can be found `here <https://www.python.org/dev/peps/pep-0008/>`_
|
||||
|
||||
A brief listing of pep8 criteria.
|
||||
|
||||
@@ -316,7 +316,7 @@ use to join a list of strings (the list may be temporary). In the following exam
|
||||
|
||||
|
||||
Join is fastest on many strings,
|
||||
`string formatting <http://docs.python.org/py3k/library/string.html#string-formatting>`__
|
||||
`string formatting <https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design>`__
|
||||
is quite fast too (better for converting data types). String arithmetic is slowest.
|
||||
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
|
||||
*******
|
||||
Gotchas
|
||||
*******
|
||||
@@ -38,7 +39,6 @@ but some operators are more picky about when they run.
|
||||
In most cases you can figure out what context an operator needs
|
||||
simply be seeing how it's used in Blender and thinking about what it does.
|
||||
|
||||
|
||||
Unfortunately if you're still stuck - the only way to **really** know
|
||||
whats going on is to read the source code for the poll function and see what its checking.
|
||||
|
||||
@@ -82,7 +82,6 @@ it should be reported to the bug tracker.
|
||||
Stale Data
|
||||
==========
|
||||
|
||||
|
||||
No updates after setting values
|
||||
-------------------------------
|
||||
|
||||
@@ -174,8 +173,8 @@ In this situation you can...
|
||||
|
||||
.. _info_gotcha_mesh_faces:
|
||||
|
||||
NGons and Tessellation Faces
|
||||
============================
|
||||
N-Gons and Tessellation Faces
|
||||
=============================
|
||||
|
||||
Since 2.63 NGons are supported, this adds some complexity
|
||||
since in some cases you need to access triangles/quads still (some exporters for example).
|
||||
@@ -509,7 +508,7 @@ Unicode Problems
|
||||
Python supports many different encodings so there is nothing stopping you from
|
||||
writing a script in ``latin1`` or ``iso-8859-15``.
|
||||
|
||||
See `pep-0263 <http://www.python.org/dev/peps/pep-0263/>`_
|
||||
See `pep-0263 <https://www.python.org/dev/peps/pep-0263/>`_
|
||||
|
||||
However this complicates matters for Blender's Python API because ``.blend`` files don't have an explicit encoding.
|
||||
|
||||
@@ -657,7 +656,7 @@ Here are some general hints to avoid running into these problems.
|
||||
.. note::
|
||||
|
||||
To find the line of your script that crashes you can use the ``faulthandler`` module.
|
||||
See `faulthandler docs <http://docs.python.org/dev/library/faulthandler.html>`_.
|
||||
See the `faulthandler docs <https://docs.python.org/dev/library/faulthandler.html>`_.
|
||||
|
||||
While the crash may be in Blenders C/C++ code,
|
||||
this can help a lot to track down the area of the script that causes the crash.
|
||||
|
@@ -19,7 +19,7 @@ This is a typical Python environment so tutorials on how to write Python scripts
|
||||
will work running the scripts in Blender too.
|
||||
Blender provides the :mod:`bpy` module to the Python interpreter.
|
||||
This module can be imported in a script and gives access to Blender data, classes, and functions.
|
||||
Scripts that deal with Blender data will need to import this module.
|
||||
Scripts that deal with Blender data will need to import this module.
|
||||
|
||||
Here is a simple example of moving a vertex of the object named **Cube**:
|
||||
|
||||
@@ -43,8 +43,7 @@ scene manipulation, automation, defining your own toolset and customization.
|
||||
|
||||
On startup Blender scans the ``scripts/startup/`` directory for Python modules and imports them.
|
||||
The exact location of this directory depends on your installation.
|
||||
`See the directory layout docs
|
||||
<https://www.blender.org/manual/getting_started/installing_blender/directorylayout.html>`__
|
||||
See the :ref:`directory layout docs <blender_manual:getting-started_installing-config-directories>`.
|
||||
|
||||
|
||||
Script Loading
|
||||
@@ -77,22 +76,22 @@ To run as modules:
|
||||
- The obvious way, ``import some_module`` command from the text window or interactive console.
|
||||
- Open as a text block and tick "Register" option, this will load with the blend file.
|
||||
- copy into one of the directories ``scripts/startup``, where they will be automatically imported on startup.
|
||||
- define as an addon, enabling the addon will load it as a Python module.
|
||||
- define as an add-on, enabling the add-on will load it as a Python module.
|
||||
|
||||
|
||||
Addons
|
||||
------
|
||||
Add-ons
|
||||
-------
|
||||
|
||||
Some of Blenders functionality is best kept optional,
|
||||
alongside scripts loaded at startup we have addons which are kept in their own directory ``scripts/addons``,
|
||||
alongside scripts loaded at startup we have add-ons which are kept in their own directory ``scripts/addons``,
|
||||
and only load on startup if selected from the user preferences.
|
||||
|
||||
The only difference between addons and built-in Python modules is that addons must contain a ``bl_info``
|
||||
The only difference between add-ons and built-in Python modules is that add-ons must contain a ``bl_info``
|
||||
variable which Blender uses to read metadata such as name, author, category and URL.
|
||||
|
||||
The user preferences addon listing uses **bl_info** to display information about each addon.
|
||||
The User Preferences add-on listing uses **bl_info** to display information about each add-on.
|
||||
|
||||
`See Addons <http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons>`__
|
||||
`See Add-ons <https://wiki.blender.org/index.php/Dev:Py/Scripts/Guidelines/Addons>`__
|
||||
for details on the ``bl_info`` dictionary.
|
||||
|
||||
|
||||
@@ -214,7 +213,7 @@ A simple Blender/Python module can look like this:
|
||||
bpy.utils.register_class(SimpleOperator)
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(SimpleOperator)
|
||||
bpy.utils.unregister_class(SimpleOperator)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
@@ -223,7 +222,7 @@ These functions usually appear at the bottom of the script containing class regi
|
||||
You can also use them for internal purposes setting up data for your own tools but take care
|
||||
since register won't re-run when a new blend file is loaded.
|
||||
|
||||
The register/unregister calls are used so it's possible to toggle addons and reload scripts while Blender runs.
|
||||
The register/unregister calls are used so it's possible to toggle add-ons and reload scripts while Blender runs.
|
||||
If the register calls were placed in the body of the script, registration would be called on import,
|
||||
meaning there would be no distinction between importing a module or loading its classes into Blender.
|
||||
|
||||
@@ -328,7 +327,7 @@ Say you want to store material settings for a custom engine.
|
||||
.. note::
|
||||
|
||||
*The class must be registered before being used in a property, failing to do so will raise an error:*
|
||||
|
||||
|
||||
``ValueError: bpy_struct "Material" registration error: my_custom_props could not register``
|
||||
|
||||
|
||||
@@ -430,4 +429,3 @@ Calling these operators:
|
||||
>>> bpy.ops.object.operator_2()
|
||||
Hello World OBJECT_OT_operator_2
|
||||
{'FINISHED'}
|
||||
|
||||
|
@@ -51,8 +51,7 @@ A quick list of helpful things to know before starting:
|
||||
| ``scripts/startup/bl_operators`` for operators.
|
||||
|
||||
Exact location depends on platform, see:
|
||||
`Configuration and Data Paths
|
||||
<https://www.blender.org/manual/getting_started/installing_blender/directorylayout.html>`__.
|
||||
:ref:`Configuration and Data Paths <blender_manual:getting-started_installing-config-directories>`.
|
||||
|
||||
|
||||
Running Scripts
|
||||
|
@@ -27,7 +27,7 @@ There are 3 main uses for the terminal, these are:
|
||||
|
||||
.. note::
|
||||
|
||||
For Linux and OSX users this means starting the terminal first, then running Blender from within it.
|
||||
For Linux and macOS users this means starting the terminal first, then running Blender from within it.
|
||||
On Windows the terminal can be enabled from the help menu.
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ Advantages include:
|
||||
This is marked advanced because to run Blender as a Python module requires a special build option.
|
||||
|
||||
For instructions on building see
|
||||
`Building Blender as a Python module <http://wiki.blender.org/index.php/User:Ideasman42/BlenderAsPyModule>`_
|
||||
`Building Blender as a Python module <https://wiki.blender.org/index.php/User:Ideasman42/BlenderAsPyModule>`_
|
||||
|
||||
|
||||
Python Safety (Build Option)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
|
||||
Addon Tutorial
|
||||
##############
|
||||
Add-on Tutorial
|
||||
###############
|
||||
|
||||
************
|
||||
Introduction
|
||||
@@ -36,6 +36,7 @@ Suggested reading before starting this tutorial.
|
||||
To best troubleshoot any error message Python prints while writing scripts you run blender with from a terminal,
|
||||
see :ref:`Use The Terminal <use_the_terminal>`.
|
||||
|
||||
|
||||
Documentation Links
|
||||
===================
|
||||
|
||||
@@ -46,51 +47,48 @@ While going through the tutorial you may want to look into our reference documen
|
||||
- :mod:`bpy.context` api reference. -
|
||||
*Handy to have a list of available items your script may operate on.*
|
||||
- :class:`bpy.types.Operator`. -
|
||||
*The following addons define operators, these docs give details and more examples of operators.*
|
||||
*The following add-ons define operators, these docs give details and more examples of operators.*
|
||||
|
||||
|
||||
******
|
||||
Addons
|
||||
******
|
||||
*******
|
||||
Add-ons
|
||||
*******
|
||||
|
||||
What is an Add-on?
|
||||
==================
|
||||
|
||||
What is an Addon?
|
||||
=================
|
||||
|
||||
An addon is simply a Python module with some additional requirements so Blender can display it in a list with useful
|
||||
An add-on is simply a Python module with some additional requirements so Blender can display it in a list with useful
|
||||
information.
|
||||
|
||||
To give an example, here is the simplest possible addon.
|
||||
|
||||
To give an example, here is the simplest possible add-on.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bl_info = {"name": "My Test Addon", "category": "Object"}
|
||||
bl_info = {"name": "My Test Add-on", "category": "Object"}
|
||||
def register():
|
||||
print("Hello World")
|
||||
def unregister():
|
||||
print("Goodbye World")
|
||||
|
||||
|
||||
- ``bl_info`` is a dictionary containing addon meta-data such as the title, version and author to be displayed in the
|
||||
user preferences addon list.
|
||||
- ``register`` is a function which only runs when enabling the addon, this means the module can be loaded without
|
||||
activating the addon.
|
||||
- ``unregister`` is a function to unload anything setup by ``register``, this is called when the addon is disabled.
|
||||
- ``bl_info`` is a dictionary containing add-on metadata such as the title,
|
||||
version and author to be displayed in the user preferences add-on list.
|
||||
- ``register`` is a function which only runs when enabling the add-on,
|
||||
this means the module can be loaded without activating the add-on.
|
||||
- ``unregister`` is a function to unload anything setup by ``register``, this is called when the add-on is disabled.
|
||||
|
||||
|
||||
Notice this add-on does not do anything related to Blender, (the :mod:`bpy` module is not imported for example).
|
||||
|
||||
Notice this addon does not do anything related to Blender, (the :mod:`bpy` module is not imported for example).
|
||||
This is a contrived example of an add-on that serves to illustrate the point
|
||||
that the base requirements of an add-on are simple.
|
||||
|
||||
This is a contrived example of an addon that serves to illustrate the point
|
||||
that the base requirements of an addon are simple.
|
||||
|
||||
An addon will typically register operators, panels, menu items etc, but its worth noting that _any_ script can do this,
|
||||
An add-on will typically register operators, panels, menu items etc, but its worth noting that _any_ script can do this,
|
||||
when executed from the text editor or even the interactive console - there is nothing inherently different about an
|
||||
addon that allows it to integrate with Blender, such functionality is just provided by the :mod:`bpy` module for any
|
||||
add-on that allows it to integrate with Blender, such functionality is just provided by the :mod:`bpy` module for any
|
||||
script to access.
|
||||
|
||||
So an addon is just a way to encapsulate a Python module in a way a user can easily utilize.
|
||||
So an add-on is just a way to encapsulate a Python module in a way a user can easily utilize.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -99,14 +97,14 @@ So an addon is just a way to encapsulate a Python module in a way a user can eas
|
||||
Messages will be printed when enabling and disabling.
|
||||
|
||||
|
||||
Your First Addon
|
||||
================
|
||||
Your First Add-on
|
||||
=================
|
||||
|
||||
The simplest possible addon above was useful as an example but not much else.
|
||||
This next addon is simple but shows how to integrate a script into Blender using an ``Operator``
|
||||
The simplest possible add-on above is useful as an example but not much else.
|
||||
This next add-on is simple but shows how to integrate a script into Blender using an ``Operator``
|
||||
which is the typical way to define a tool accessed from menus, buttons and keyboard shortcuts.
|
||||
|
||||
For the first example we'll make a script that simply moves all objects in a scene.
|
||||
For the first example we will make a script that simply moves all objects in a scene.
|
||||
|
||||
|
||||
Write The Script
|
||||
@@ -123,20 +121,14 @@ Add the following script to the text editor in Blender.
|
||||
obj.location.x += 1.0
|
||||
|
||||
|
||||
.. image:: run_script.png
|
||||
:width: 924px
|
||||
:align: center
|
||||
:height: 574px
|
||||
:alt: Run Script button
|
||||
|
||||
Click the Run Script button, all objects in the active scene are moved by 1.0 Blender unit.
|
||||
Next we'll make this script into an addon.
|
||||
Click the :ref:`Run Script button <blender_manual:editors-text-run-script>`,
|
||||
all objects in the active scene are moved by 1.0 Blender unit.
|
||||
|
||||
|
||||
Write the Addon (Simple)
|
||||
------------------------
|
||||
Write the Add-on (Simple)
|
||||
-------------------------
|
||||
|
||||
This addon takes the body of the script above, and adds them to an operator's ``execute()`` function.
|
||||
This add-on takes the body of the script above, and adds them to an operator's ``execute()`` function.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
@@ -173,7 +165,7 @@ This addon takes the body of the script above, and adds them to an operator's ``
|
||||
|
||||
|
||||
# This allows you to run the script directly from blenders text editor
|
||||
# to test the addon without having to install it.
|
||||
# to test the add-on without having to install it.
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
@@ -206,33 +198,33 @@ Do this by pressing :kbd:`Spacebar` to bring up the operator search dialog and t
|
||||
|
||||
The objects should move as before.
|
||||
|
||||
*Keep this addon open in Blender for the next step - Installing.*
|
||||
*Keep this add-on open in Blender for the next step - Installing.*
|
||||
|
||||
|
||||
Install The Addon
|
||||
-----------------
|
||||
Install The Add-on
|
||||
------------------
|
||||
|
||||
Once you have your addon within in Blender's text editor,
|
||||
Once you have your add-on within in Blender's text editor,
|
||||
you will want to be able to install it so it can be enabled in the user preferences to load on startup.
|
||||
|
||||
Even though the addon above is a test, lets go through the steps anyway so you know how to do it for later.
|
||||
Even though the add-on above is a test, lets go through the steps anyway so you know how to do it for later.
|
||||
|
||||
To install the Blender text as an addon you will first have to save it to disk, take care to obey the naming
|
||||
To install the Blender text as an add-on you will first have to save it to disk, take care to obey the naming
|
||||
restrictions that apply to Python modules and end with a ``.py`` extension.
|
||||
|
||||
Once the file is on disk, you can install it as you would for an addon downloaded online.
|
||||
Once the file is on disk, you can install it as you would for an add-on downloaded online.
|
||||
|
||||
Open the user :menuselection:`File -> User Preferences`,
|
||||
Select the *Addon* section, press *Install Addon...* and select the file.
|
||||
Open the user :menuselection:`File --> User Preferences`,
|
||||
Select the *Add-on* section, press *Install Add-on...* and select the file.
|
||||
|
||||
Now the addon will be listed and you can enable it by pressing the check-box,
|
||||
Now the add-on will be listed and you can enable it by pressing the check-box,
|
||||
if you want it to be enabled on restart, press *Save as Default*.
|
||||
|
||||
.. note::
|
||||
|
||||
The destination of the addon depends on your Blender configuration.
|
||||
When installing an addon the source and destination path are printed in the console.
|
||||
You can also find addon path locations by running this in the Python console.
|
||||
The destination of the add-on depends on your Blender configuration.
|
||||
When installing an add-on the source and destination path are printed in the console.
|
||||
You can also find add-on path locations by running this in the Python console.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -240,20 +232,20 @@ if you want it to be enabled on restart, press *Save as Default*.
|
||||
print(addon_utils.paths())
|
||||
|
||||
More is written on this topic here:
|
||||
`Directory Layout <https://www.blender.org/manual/getting_started/installing_blender/directorylayout.html>`_
|
||||
:ref:`Directory Layout <blender_manual:getting-started_installing-config-directories>`.
|
||||
|
||||
|
||||
Your Second Addon
|
||||
=================
|
||||
Your Second Add-on
|
||||
==================
|
||||
|
||||
For our second addon, we will focus on object instancing - this is - to make linked copies of an object in a
|
||||
For our second add-on, we will focus on object instancing - this is - to make linked copies of an object in a
|
||||
similar way to what you may have seen with the array modifier.
|
||||
|
||||
|
||||
Write The Script
|
||||
----------------
|
||||
|
||||
As before, first we will start with a script, develop it, then convert into an addon.
|
||||
As before, first we will start with a script, develop it, then convert into an add-on.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -324,17 +316,17 @@ allows vectors to be multiplied by numbers and matrices.
|
||||
|
||||
If you are interested in this area, read into :class:`mathutils.Vector` - there are many handy utility functions
|
||||
such as getting the angle between vectors, cross product, dot products
|
||||
as well as more advanced functions in :mod:`mathutils.geometry` such as bezier spline interpolation and
|
||||
as well as more advanced functions in :mod:`mathutils.geometry` such as Bézier Spline interpolation and
|
||||
ray-triangle intersection.
|
||||
|
||||
For now we'll focus on making this script an addon, but its good to know that this 3D math module is available and
|
||||
For now we will focus on making this script an add-on, but its good to know that this 3D math module is available and
|
||||
can help you with more advanced functionality later on.
|
||||
|
||||
|
||||
Write the Addon
|
||||
---------------
|
||||
Write the Add-on
|
||||
----------------
|
||||
|
||||
The first step is to convert the script as-is into an addon.
|
||||
The first step is to convert the script as-is into an add-on.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
@@ -381,7 +373,7 @@ The first step is to convert the script as-is into an addon.
|
||||
register()
|
||||
|
||||
|
||||
Everything here has been covered in the previous steps, you may want to try run the addon still
|
||||
Everything here has been covered in the previous steps, you may want to try run the add-on still
|
||||
and consider what could be done to make it more useful.
|
||||
|
||||
|
||||
@@ -434,7 +426,7 @@ however the link above includes examples of more advanced property usage.
|
||||
Menu Item
|
||||
^^^^^^^^^
|
||||
|
||||
Addons can add to the user interface of existing panels, headers and menus defined in Python.
|
||||
Add-ons can add to the user interface of existing panels, headers and menus defined in Python.
|
||||
|
||||
For this example we'll add to an existing menu.
|
||||
|
||||
@@ -464,7 +456,7 @@ For docs on extending menus see: :doc:`bpy.types.Menu`.
|
||||
Keymap
|
||||
^^^^^^
|
||||
|
||||
In Blender addons have their own key-maps so as not to interfere with Blenders built in key-maps.
|
||||
In Blender, add-ons have their own keymaps so as not to interfere with Blenders built in key-maps.
|
||||
|
||||
In the example below, a new object-mode :class:`bpy.types.KeyMap` is added,
|
||||
then a :class:`bpy.types.KeyMapItem` is added to the key-map which references our newly added operator,
|
||||
@@ -502,7 +494,7 @@ this allows you to have multiple keys accessing the same operator with different
|
||||
|
||||
.. note::
|
||||
|
||||
While :kbd:`Ctrl-Shift-Space` isn't a default Blender key shortcut, its hard to make sure addons won't
|
||||
While :kbd:`Ctrl-Shift-Space` isn't a default Blender key shortcut, its hard to make sure add-ons won't
|
||||
overwrite each others keymaps, At least take care when assigning keys that they don't
|
||||
conflict with important functionality within Blender.
|
||||
|
||||
@@ -606,14 +598,14 @@ After selecting it from the menu, you can choose how many instance of the cube y
|
||||
.. note::
|
||||
|
||||
Directly executing the script multiple times will add the menu each time too.
|
||||
While not useful behavior, theres nothing to worry about since addons won't register them selves multiple
|
||||
While not useful behavior, theres nothing to worry about since add-ons won't register them selves multiple
|
||||
times when enabled through the user preferences.
|
||||
|
||||
|
||||
Conclusions
|
||||
===========
|
||||
|
||||
Addons can encapsulate certain functionality neatly for writing tools to improve your work-flow or for writing utilities
|
||||
Add-ons can encapsulate certain functionality neatly for writing tools to improve your work-flow or for writing utilities
|
||||
for others to use.
|
||||
|
||||
While there are limits to what Python can do within Blender, there is certainly a lot that can be achieved without
|
||||
@@ -636,8 +628,8 @@ Here are some sites you might like to check on after completing this tutorial.
|
||||
*For more background details on Blender/Python integration.*
|
||||
- `How to Think Like a Computer Scientist <http://interactivepython.org/courselib/static/thinkcspy/index.html>`_ -
|
||||
*Great info for those who are still learning Python.*
|
||||
- `Blender Development (Wiki) <http://wiki.blender.org/index.php/Dev:Contents>`_ -
|
||||
- `Blender Development (Wiki) <https://wiki.blender.org/index.php/Dev:Contents>`_ -
|
||||
*Blender Development, general information and helpful links.*
|
||||
- `Blender Artists (Coding Section) <http://blenderartists.org/forum/forumdisplay.php?47-Coding>`_ -
|
||||
- `Blender Artists (Coding Section) <https://blenderartists.org/forum/forumdisplay.php?47-Coding>`_ -
|
||||
*forum where people ask Python development questions*
|
||||
|
||||
|
@@ -27,7 +27,7 @@ output from this tool should be added into "doc/python_api/rst/change_log.rst"
|
||||
blender --background --python doc/python_api/sphinx_changelog_gen.py -- --dump
|
||||
|
||||
# create changelog
|
||||
blender --background --python doc/python_api/sphinx_changelog_gen.py -- \
|
||||
blender --background --factory-startup --python doc/python_api/sphinx_changelog_gen.py -- \
|
||||
--api_from blender_2_63_0.py \
|
||||
--api_to blender_2_64_0.py \
|
||||
--api_out changes.rst
|
||||
@@ -331,7 +331,7 @@ def main():
|
||||
|
||||
# When --help or no args are given, print this help
|
||||
usage_text = "Run blender in background mode with this script: "
|
||||
"blender --background --python %s -- [options]" % os.path.basename(__file__)
|
||||
"blender --background --factory-startup --python %s -- [options]" % os.path.basename(__file__)
|
||||
|
||||
epilog = "Run this before releases"
|
||||
|
||||
|
@@ -26,16 +26,16 @@ API dump in RST files
|
||||
---------------------
|
||||
Run this script from Blender's root path once you have compiled Blender
|
||||
|
||||
./blender.bin --background -noaudio --python doc/python_api/sphinx_doc_gen.py
|
||||
blender --background --factory-startup -noaudio --python doc/python_api/sphinx_doc_gen.py
|
||||
|
||||
This will generate python files in doc/python_api/sphinx-in/
|
||||
providing ./blender.bin is or links to the blender executable
|
||||
providing ./blender is or links to the blender executable
|
||||
|
||||
To choose sphinx-in directory:
|
||||
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --output ../python_api
|
||||
blender --background --factory-startup --python doc/python_api/sphinx_doc_gen.py -- --output ../python_api
|
||||
|
||||
For quick builds:
|
||||
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial bmesh.*
|
||||
blender --background --factory-startup --python doc/python_api/sphinx_doc_gen.py -- --partial bmesh.*
|
||||
|
||||
|
||||
Sphinx: HTML generation
|
||||
@@ -46,8 +46,6 @@ Sphinx: HTML generation
|
||||
cd doc/python_api
|
||||
sphinx-build sphinx-in sphinx-out
|
||||
|
||||
This requires sphinx 1.0.7 to be installed.
|
||||
|
||||
|
||||
Sphinx: PDF generation
|
||||
----------------------
|
||||
@@ -68,7 +66,7 @@ except ImportError:
|
||||
import sys
|
||||
sys.exit()
|
||||
|
||||
import rna_info # Blender module
|
||||
import rna_info # Blender module
|
||||
|
||||
|
||||
def rna_info_BuildRNAInfo_cache():
|
||||
@@ -86,7 +84,7 @@ import shutil
|
||||
import logging
|
||||
|
||||
from platform import platform
|
||||
PLATFORM = platform().split('-')[0].lower() # 'linux', 'darwin', 'windows'
|
||||
PLATFORM = platform().split('-')[0].lower() # 'linux', 'darwin', 'windows'
|
||||
|
||||
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
@@ -208,12 +206,12 @@ BPY_LOGGER.setLevel(logging.DEBUG)
|
||||
"""
|
||||
# for quick rebuilds
|
||||
rm -rf /b/doc/python_api/sphinx-* && \
|
||||
./blender.bin -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py && \
|
||||
./blender -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py && \
|
||||
sphinx-build doc/python_api/sphinx-in doc/python_api/sphinx-out
|
||||
|
||||
or
|
||||
|
||||
./blender.bin -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py -- -f -B
|
||||
./blender -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py -- -f -B
|
||||
"""
|
||||
|
||||
# Switch for quick testing so doc-builds don't take so long
|
||||
@@ -365,7 +363,7 @@ INFO_DOCS = (
|
||||
("info_overview.rst",
|
||||
"Blender/Python API Overview: a more complete explanation of Python integration"),
|
||||
("info_tutorial_addon.rst",
|
||||
"Blender/Python Addon Tutorial: a step by step guide on how to write an addon from scratch"),
|
||||
"Blender/Python Add-on Tutorial: a step by step guide on how to write an add-on from scratch"),
|
||||
("info_api_reference.rst",
|
||||
"Blender/Python API Reference Usage: examples of how to use the API reference docs"),
|
||||
("info_best_practice.rst",
|
||||
@@ -420,7 +418,7 @@ MODULE_GROUPING = {
|
||||
|
||||
blender_version_strings = [str(v) for v in bpy.app.version]
|
||||
|
||||
# converting bytes to strings, due to #30154
|
||||
# converting bytes to strings, due to T30154
|
||||
BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8')
|
||||
BLENDER_DATE = str(bpy.app.build_date, 'utf_8')
|
||||
|
||||
@@ -429,9 +427,9 @@ if BLENDER_REVISION != "Unknown":
|
||||
BLENDER_VERSION_DOTS += " " + BLENDER_REVISION # '2.62.1 SHA1'
|
||||
|
||||
BLENDER_VERSION_PATH = "_".join(blender_version_strings) # '2_62_1'
|
||||
if bpy.app.version_cycle == "release":
|
||||
BLENDER_VERSION_PATH = "%s%s_release" % ("_".join(blender_version_strings[:2]),
|
||||
bpy.app.version_char) # '2_62_release'
|
||||
if bpy.app.version_cycle in {"rc", "release"}:
|
||||
# '2_62a_release'
|
||||
BLENDER_VERSION_PATH = "%s%s_release" % ("_".join(blender_version_strings[:2]), bpy.app.version_char)
|
||||
|
||||
# --------------------------DOWNLOADABLE FILES----------------------------------
|
||||
|
||||
@@ -1026,6 +1024,7 @@ context_type_map = {
|
||||
"brush": ("Brush", False),
|
||||
"camera": ("Camera", False),
|
||||
"cloth": ("ClothModifier", False),
|
||||
"collection": ("LayerCollection", False),
|
||||
"collision": ("CollisionModifier", False),
|
||||
"curve": ("Curve", False),
|
||||
"dynamic_paint": ("DynamicPaintModifier", False),
|
||||
@@ -1057,6 +1056,7 @@ context_type_map = {
|
||||
"particle_system": ("ParticleSystem", False),
|
||||
"particle_system_editable": ("ParticleSystem", False),
|
||||
"pose_bone": ("PoseBone", False),
|
||||
"render_layer": ("SceneLayer", False),
|
||||
"scene": ("Scene", False),
|
||||
"sculpt_object": ("Object", False),
|
||||
"selectable_bases": ("ObjectBase", True),
|
||||
@@ -1567,9 +1567,9 @@ def pyrna2sphinx(basepath):
|
||||
|
||||
# operators
|
||||
def write_ops():
|
||||
API_BASEURL = "http://svn.blender.org/svnroot/bf-blender/trunk/blender/release/scripts"
|
||||
API_BASEURL_ADDON = "http://svn.blender.org/svnroot/bf-extensions/trunk/py/scripts"
|
||||
API_BASEURL_ADDON_CONTRIB = "http://svn.blender.org/svnroot/bf-extensions/contrib/py/scripts"
|
||||
API_BASEURL = "https://developer.blender.org/diffusion/B/browse/master/release/scripts "
|
||||
API_BASEURL_ADDON = "https://developer.blender.org/diffusion/BA"
|
||||
API_BASEURL_ADDON_CONTRIB = "https://developer.blender.org/diffusion/BAC"
|
||||
|
||||
op_modules = {}
|
||||
for op in ops.values():
|
||||
@@ -1634,6 +1634,9 @@ def write_sphinx_conf_py(basepath):
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
fw = file.write
|
||||
|
||||
fw("import sys, os\n\n")
|
||||
fw("extensions = ['sphinx.ext.intersphinx']\n\n")
|
||||
fw("intersphinx_mapping = {'blender_manual': ('https://docs.blender.org/manual/en/dev/', None)}\n\n")
|
||||
fw("project = 'Blender'\n")
|
||||
# fw("master_doc = 'index'\n")
|
||||
fw("copyright = u'Blender Foundation'\n")
|
||||
@@ -1645,16 +1648,21 @@ def write_sphinx_conf_py(basepath):
|
||||
|
||||
if ARGS.sphinx_theme == "blender-org":
|
||||
fw("html_theme_path = ['../']\n")
|
||||
# copied with the theme, exclude else we get an error [#28873]
|
||||
# copied with the theme, exclude else we get an error [T28873]
|
||||
fw("html_favicon = 'favicon.ico'\n") # in <theme>/static/
|
||||
|
||||
# not helpful since the source is generated, adds to upload size.
|
||||
fw("html_copy_source = False\n")
|
||||
fw("html_show_sphinx = False\n")
|
||||
fw("html_split_index = True\n")
|
||||
fw("\n")
|
||||
|
||||
# needed for latex, pdf gen
|
||||
fw("latex_elements = {\n")
|
||||
fw(" 'papersize': 'a4paper',\n")
|
||||
fw("}\n\n")
|
||||
|
||||
fw("latex_documents = [ ('contents', 'contents.tex', 'Blender Index', 'Blender Foundation', 'manual'), ]\n")
|
||||
fw("latex_paper_size = 'a4paper'\n")
|
||||
file.close()
|
||||
|
||||
|
||||
|
@@ -41,9 +41,9 @@ import tempfile
|
||||
import zipfile
|
||||
|
||||
|
||||
DEFAULT_RSYNC_SERVER = "www.blender.org"
|
||||
DEFAULT_RSYNC_SERVER = "docs.blender.org"
|
||||
DEFAULT_RSYNC_ROOT = "/api/"
|
||||
DEFAULT_SYMLINK_ROOT = "/data/www/vhosts/www.blender.org/api"
|
||||
DEFAULT_SYMLINK_ROOT = "/data/www/vhosts/docs.blender.org/api"
|
||||
|
||||
|
||||
def argparse_create():
|
||||
@@ -96,6 +96,11 @@ def main():
|
||||
|
||||
rsync_base = "rsync://%s@%s:%s" % (args.user, args.rsync_server, args.rsync_root)
|
||||
|
||||
blenver = blenver_zip = ""
|
||||
api_name = ""
|
||||
branch = ""
|
||||
is_release = False
|
||||
|
||||
# I) Update local mirror using rsync.
|
||||
rsync_mirror_cmd = ("rsync", "--delete-after", "-avzz", rsync_base, args.mirror_dir)
|
||||
subprocess.run(rsync_mirror_cmd, env=dict(os.environ, RSYNC_PASSWORD=args.password))
|
||||
@@ -108,18 +113,24 @@ def main():
|
||||
subprocess.run(doc_gen_cmd)
|
||||
|
||||
# III) Get Blender version info.
|
||||
blenver = ""
|
||||
getver_file = os.path.join(tmp_dir, "blendver.txt")
|
||||
getver_script = (""
|
||||
"import sys, bpy\n"
|
||||
"with open(sys.argv[-1], 'w') as f:\n"
|
||||
" is_release = bpy.app.version_cycle in {'rc', 'release'}\n"
|
||||
" branch = bpy.app.build_branch.split()[0].decode()\n"
|
||||
" f.write('%d\\n' % is_release)\n"
|
||||
" f.write('%s\\n' % branch)\n"
|
||||
" f.write('%d.%d%s\\n' % (bpy.app.version[0], bpy.app.version[1], bpy.app.version_char)\n"
|
||||
" if is_release else '%s\\n' % branch)\n"
|
||||
" f.write('%d_%d%s_release' % (bpy.app.version[0], bpy.app.version[1], bpy.app.version_char)\n"
|
||||
" if bpy.app.version_cycle in {'rc', 'release'} else '%d_%d_%d' % bpy.app.version)\n")
|
||||
" if is_release else '%d_%d_%d' % bpy.app.version)\n")
|
||||
get_ver_cmd = (args.blender, "--background", "-noaudio", "--factory-startup", "--python-exit-code", "1",
|
||||
"--python-expr", getver_script, "--", getver_file)
|
||||
subprocess.run(get_ver_cmd)
|
||||
with open(getver_file) as f:
|
||||
blenver = f.read()
|
||||
is_release, branch, blenver, blenver_zip = f.read().split("\n")
|
||||
is_release = bool(int(is_release))
|
||||
os.remove(getver_file)
|
||||
|
||||
# IV) Build doc.
|
||||
@@ -131,34 +142,33 @@ def main():
|
||||
os.chdir(curr_dir)
|
||||
|
||||
# V) Cleanup existing matching dir in server mirror (if any), and copy new doc.
|
||||
api_name = "blender_python_api_%s" % blenver
|
||||
api_name = blenver
|
||||
api_dir = os.path.join(args.mirror_dir, api_name)
|
||||
if os.path.exists(api_dir):
|
||||
shutil.rmtree(api_dir)
|
||||
os.rename(os.path.join(tmp_dir, "sphinx-out"), api_dir)
|
||||
|
||||
# VI) Create zip archive.
|
||||
zip_name = "blender_python_reference_%s" % blenver
|
||||
zip_name = "blender_python_reference_%s" % blenver_zip # We can't use 'release' postfix here...
|
||||
zip_path = os.path.join(args.mirror_dir, zip_name)
|
||||
with zipfile.ZipFile(zip_path, 'w') as zf:
|
||||
for de in os.scandir(api_dir):
|
||||
zf.write(de.path, arcname=os.path.join(zip_name, de.name))
|
||||
for dirname, _, filenames in os.walk(api_dir):
|
||||
for filename in filenames:
|
||||
filepath = os.path.join(dirname, filename)
|
||||
zip_filepath = os.path.join(zip_name, os.path.relpath(filepath, api_dir))
|
||||
zf.write(filepath, arcname=zip_filepath)
|
||||
os.rename(zip_path, os.path.join(api_dir, "%s.zip" % zip_name))
|
||||
|
||||
# VII) Create symlinks and html redirects.
|
||||
#~ os.symlink(os.path.join(DEFAULT_SYMLINK_ROOT, api_name, "contents.html"), os.path.join(api_dir, "index.html"))
|
||||
os.symlink("./contents.html", os.path.join(api_dir, "index.html"))
|
||||
if blenver.endswith("release"):
|
||||
symlink = os.path.join(args.mirror_dir, "blender_python_api_current")
|
||||
if is_release:
|
||||
symlink = os.path.join(args.mirror_dir, "current")
|
||||
os.remove(symlink)
|
||||
os.symlink("./%s" % api_name, symlink)
|
||||
with open(os.path.join(args.mirror_dir, "250PythonDoc/index.html"), 'w') as f:
|
||||
f.write("<html><head><title>Redirecting...</title><meta http-equiv=\"REFRESH\""
|
||||
"content=\"0;url=../%s/\"></head><body>Redirecting...</body></html>" % api_name)
|
||||
else:
|
||||
symlink = os.path.join(args.mirror_dir, "blender_python_api_master")
|
||||
os.remove(symlink)
|
||||
os.symlink("./%s" % api_name, symlink)
|
||||
elif branch == "master":
|
||||
with open(os.path.join(args.mirror_dir, "blender_python_api/index.html"), 'w') as f:
|
||||
f.write("<html><head><title>Redirecting...</title><meta http-equiv=\"REFRESH\""
|
||||
"content=\"0;url=../%s/\"></head><body>Redirecting...</body></html>" % api_name)
|
||||
|
@@ -77,7 +77,7 @@ namespace std {
|
||||
void resize(size_type new_size)
|
||||
{ resize(new_size, T()); }
|
||||
|
||||
#if defined(_VECTOR_)
|
||||
#if defined(_VECTOR_) && (_MSC_VER<1910)
|
||||
// workaround MSVC std::vector implementation
|
||||
void resize(size_type new_size, const value_type& x)
|
||||
{
|
||||
@@ -110,7 +110,7 @@ namespace std {
|
||||
vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
|
||||
}
|
||||
#else
|
||||
// either GCC 4.1 or non-GCC
|
||||
// either GCC 4.1, MSVC2017 or non-GCC
|
||||
// default implementation which should always work.
|
||||
void resize(size_type new_size, const value_type& x)
|
||||
{
|
||||
|
5
extern/ceres/CMakeLists.txt
vendored
5
extern/ceres/CMakeLists.txt
vendored
@@ -73,10 +73,12 @@ set(SRC
|
||||
internal/ceres/file.cc
|
||||
internal/ceres/generated/partitioned_matrix_view_d_d_d.cc
|
||||
internal/ceres/generated/schur_eliminator_d_d_d.cc
|
||||
internal/ceres/gradient_checker.cc
|
||||
internal/ceres/gradient_checking_cost_function.cc
|
||||
internal/ceres/gradient_problem.cc
|
||||
internal/ceres/gradient_problem_solver.cc
|
||||
internal/ceres/implicit_schur_complement.cc
|
||||
internal/ceres/is_close.cc
|
||||
internal/ceres/iterative_schur_complement_solver.cc
|
||||
internal/ceres/lapack.cc
|
||||
internal/ceres/levenberg_marquardt_strategy.cc
|
||||
@@ -116,6 +118,7 @@ set(SRC
|
||||
internal/ceres/triplet_sparse_matrix.cc
|
||||
internal/ceres/trust_region_minimizer.cc
|
||||
internal/ceres/trust_region_preprocessor.cc
|
||||
internal/ceres/trust_region_step_evaluator.cc
|
||||
internal/ceres/trust_region_strategy.cc
|
||||
internal/ceres/types.cc
|
||||
internal/ceres/wall_time.cc
|
||||
@@ -204,6 +207,7 @@ set(SRC
|
||||
internal/ceres/householder_vector.h
|
||||
internal/ceres/implicit_schur_complement.h
|
||||
internal/ceres/integral_types.h
|
||||
internal/ceres/is_close.h
|
||||
internal/ceres/iterative_schur_complement_solver.h
|
||||
internal/ceres/lapack.h
|
||||
internal/ceres/levenberg_marquardt_strategy.h
|
||||
@@ -248,6 +252,7 @@ set(SRC
|
||||
internal/ceres/triplet_sparse_matrix.h
|
||||
internal/ceres/trust_region_minimizer.h
|
||||
internal/ceres/trust_region_preprocessor.h
|
||||
internal/ceres/trust_region_step_evaluator.h
|
||||
internal/ceres/trust_region_strategy.h
|
||||
internal/ceres/visibility_based_preconditioner.h
|
||||
internal/ceres/wall_time.h
|
||||
|
1035
extern/ceres/ChangeLog
vendored
1035
extern/ceres/ChangeLog
vendored
File diff suppressed because it is too large
Load Diff
21
extern/ceres/bundle.sh
vendored
21
extern/ceres/bundle.sh
vendored
@@ -173,26 +173,5 @@ if(WITH_OPENMP)
|
||||
)
|
||||
endif()
|
||||
|
||||
TEST_UNORDERED_MAP_SUPPORT()
|
||||
if(HAVE_STD_UNORDERED_MAP_HEADER)
|
||||
if(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
|
||||
add_definitions(-DCERES_STD_UNORDERED_MAP)
|
||||
else()
|
||||
if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
|
||||
add_definitions(-DCERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
|
||||
else()
|
||||
add_definitions(-DCERES_NO_UNORDERED_MAP)
|
||||
message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
|
||||
add_definitions(-DCERES_TR1_UNORDERED_MAP)
|
||||
else()
|
||||
add_definitions(-DCERES_NO_UNORDERED_MAP)
|
||||
message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
blender_add_lib(extern_ceres "\${SRC}" "\${INC}" "\${INC_SYS}")
|
||||
EOF
|
||||
|
5
extern/ceres/files.txt
vendored
5
extern/ceres/files.txt
vendored
@@ -149,6 +149,7 @@ internal/ceres/generated/schur_eliminator_4_4_d.cc
|
||||
internal/ceres/generated/schur_eliminator_d_d_d.cc
|
||||
internal/ceres/generate_eliminator_specialization.py
|
||||
internal/ceres/generate_partitioned_matrix_view_specializations.py
|
||||
internal/ceres/gradient_checker.cc
|
||||
internal/ceres/gradient_checking_cost_function.cc
|
||||
internal/ceres/gradient_checking_cost_function.h
|
||||
internal/ceres/gradient_problem.cc
|
||||
@@ -160,6 +161,8 @@ internal/ceres/householder_vector.h
|
||||
internal/ceres/implicit_schur_complement.cc
|
||||
internal/ceres/implicit_schur_complement.h
|
||||
internal/ceres/integral_types.h
|
||||
internal/ceres/is_close.cc
|
||||
internal/ceres/is_close.h
|
||||
internal/ceres/iterative_schur_complement_solver.cc
|
||||
internal/ceres/iterative_schur_complement_solver.h
|
||||
internal/ceres/lapack.cc
|
||||
@@ -243,6 +246,8 @@ internal/ceres/trust_region_minimizer.cc
|
||||
internal/ceres/trust_region_minimizer.h
|
||||
internal/ceres/trust_region_preprocessor.cc
|
||||
internal/ceres/trust_region_preprocessor.h
|
||||
internal/ceres/trust_region_step_evaluator.cc
|
||||
internal/ceres/trust_region_step_evaluator.h
|
||||
internal/ceres/trust_region_strategy.cc
|
||||
internal/ceres/trust_region_strategy.h
|
||||
internal/ceres/types.cc
|
||||
|
@@ -130,7 +130,8 @@ class CostFunctionToFunctor {
|
||||
const int num_parameter_blocks =
|
||||
(N0 > 0) + (N1 > 0) + (N2 > 0) + (N3 > 0) + (N4 > 0) +
|
||||
(N5 > 0) + (N6 > 0) + (N7 > 0) + (N8 > 0) + (N9 > 0);
|
||||
CHECK_EQ(parameter_block_sizes.size(), num_parameter_blocks);
|
||||
CHECK_EQ(static_cast<int>(parameter_block_sizes.size()),
|
||||
num_parameter_blocks);
|
||||
|
||||
CHECK_EQ(N0, parameter_block_sizes[0]);
|
||||
if (parameter_block_sizes.size() > 1) CHECK_EQ(N1, parameter_block_sizes[1]); // NOLINT
|
||||
|
56
extern/ceres/include/ceres/covariance.h
vendored
56
extern/ceres/include/ceres/covariance.h
vendored
@@ -357,6 +357,28 @@ class CERES_EXPORT Covariance {
|
||||
const double*> >& covariance_blocks,
|
||||
Problem* problem);
|
||||
|
||||
// Compute a part of the covariance matrix.
|
||||
//
|
||||
// The vector parameter_blocks contains the parameter blocks that
|
||||
// are used for computing the covariance matrix. From this vector
|
||||
// all covariance pairs are generated. This allows the covariance
|
||||
// estimation algorithm to only compute and store these blocks.
|
||||
//
|
||||
// parameter_blocks cannot contain duplicates. Bad things will
|
||||
// happen if they do.
|
||||
//
|
||||
// Note that the list of covariance_blocks is only used to determine
|
||||
// what parts of the covariance matrix are computed. The full
|
||||
// Jacobian is used to do the computation, i.e. they do not have an
|
||||
// impact on what part of the Jacobian is used for computation.
|
||||
//
|
||||
// The return value indicates the success or failure of the
|
||||
// covariance computation. Please see the documentation for
|
||||
// Covariance::Options for more on the conditions under which this
|
||||
// function returns false.
|
||||
bool Compute(const std::vector<const double*>& parameter_blocks,
|
||||
Problem* problem);
|
||||
|
||||
// Return the block of the cross-covariance matrix corresponding to
|
||||
// parameter_block1 and parameter_block2.
|
||||
//
|
||||
@@ -394,6 +416,40 @@ class CERES_EXPORT Covariance {
|
||||
const double* parameter_block2,
|
||||
double* covariance_block) const;
|
||||
|
||||
// Return the covariance matrix corresponding to all parameter_blocks.
|
||||
//
|
||||
// Compute must be called before calling GetCovarianceMatrix and all
|
||||
// parameter_blocks must have been present in the vector
|
||||
// parameter_blocks when Compute was called. Otherwise
|
||||
// GetCovarianceMatrix returns false.
|
||||
//
|
||||
// covariance_matrix must point to a memory location that can store
|
||||
// the size of the covariance matrix. The covariance matrix will be
|
||||
// a square matrix whose row and column count is equal to the sum of
|
||||
// the sizes of the individual parameter blocks. The covariance
|
||||
// matrix will be a row-major matrix.
|
||||
bool GetCovarianceMatrix(const std::vector<const double *> ¶meter_blocks,
|
||||
double *covariance_matrix);
|
||||
|
||||
// Return the covariance matrix corresponding to parameter_blocks
|
||||
// in the tangent space if a local parameterization is associated
|
||||
// with one of the parameter blocks else returns the covariance
|
||||
// matrix in the ambient space.
|
||||
//
|
||||
// Compute must be called before calling GetCovarianceMatrix and all
|
||||
// parameter_blocks must have been present in the vector
|
||||
// parameters_blocks when Compute was called. Otherwise
|
||||
// GetCovarianceMatrix returns false.
|
||||
//
|
||||
// covariance_matrix must point to a memory location that can store
|
||||
// the size of the covariance matrix. The covariance matrix will be
|
||||
// a square matrix whose row and column count is equal to the sum of
|
||||
// the sizes of the tangent spaces of the individual parameter
|
||||
// blocks. The covariance matrix will be a row-major matrix.
|
||||
bool GetCovarianceMatrixInTangentSpace(
|
||||
const std::vector<const double*>& parameter_blocks,
|
||||
double* covariance_matrix);
|
||||
|
||||
private:
|
||||
internal::scoped_ptr<internal::CovarianceImpl> impl_;
|
||||
};
|
||||
|
@@ -85,22 +85,6 @@ class DynamicNumericDiffCostFunction : public CostFunction {
|
||||
options_(options) {
|
||||
}
|
||||
|
||||
// Deprecated. New users should avoid using this constructor. Instead, use the
|
||||
// constructor with NumericDiffOptions.
|
||||
DynamicNumericDiffCostFunction(
|
||||
const CostFunctor* functor,
|
||||
Ownership ownership,
|
||||
double relative_step_size)
|
||||
: functor_(functor),
|
||||
ownership_(ownership),
|
||||
options_() {
|
||||
LOG(WARNING) << "This constructor is deprecated and will be removed in "
|
||||
"a future version. Please use the NumericDiffOptions "
|
||||
"constructor instead.";
|
||||
|
||||
options_.relative_step_size = relative_step_size;
|
||||
}
|
||||
|
||||
virtual ~DynamicNumericDiffCostFunction() {
|
||||
if (ownership_ != TAKE_OWNERSHIP) {
|
||||
functor_.release();
|
||||
@@ -138,19 +122,19 @@ class DynamicNumericDiffCostFunction : public CostFunction {
|
||||
std::vector<double> parameters_copy(parameters_size);
|
||||
std::vector<double*> parameters_references_copy(block_sizes.size());
|
||||
parameters_references_copy[0] = ¶meters_copy[0];
|
||||
for (int block = 1; block < block_sizes.size(); ++block) {
|
||||
for (size_t block = 1; block < block_sizes.size(); ++block) {
|
||||
parameters_references_copy[block] = parameters_references_copy[block - 1]
|
||||
+ block_sizes[block - 1];
|
||||
}
|
||||
|
||||
// Copy the parameters into the local temp space.
|
||||
for (int block = 0; block < block_sizes.size(); ++block) {
|
||||
for (size_t block = 0; block < block_sizes.size(); ++block) {
|
||||
memcpy(parameters_references_copy[block],
|
||||
parameters[block],
|
||||
block_sizes[block] * sizeof(*parameters[block]));
|
||||
}
|
||||
|
||||
for (int block = 0; block < block_sizes.size(); ++block) {
|
||||
for (size_t block = 0; block < block_sizes.size(); ++block) {
|
||||
if (jacobians[block] != NULL &&
|
||||
!NumericDiff<CostFunctor, method, DYNAMIC,
|
||||
DYNAMIC, DYNAMIC, DYNAMIC, DYNAMIC, DYNAMIC,
|
||||
|
237
extern/ceres/include/ceres/gradient_checker.h
vendored
237
extern/ceres/include/ceres/gradient_checker.h
vendored
@@ -27,194 +27,121 @@
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
// Copyright 2007 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Author: wjr@google.com (William Rucklidge)
|
||||
//
|
||||
// This file contains a class that exercises a cost function, to make sure
|
||||
// that it is computing reasonable derivatives. It compares the Jacobians
|
||||
// computed by the cost function with those obtained by finite
|
||||
// differences.
|
||||
// Authors: wjr@google.com (William Rucklidge),
|
||||
// keir@google.com (Keir Mierle),
|
||||
// dgossow@google.com (David Gossow)
|
||||
|
||||
#ifndef CERES_PUBLIC_GRADIENT_CHECKER_H_
|
||||
#define CERES_PUBLIC_GRADIENT_CHECKER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "ceres/cost_function.h"
|
||||
#include "ceres/dynamic_numeric_diff_cost_function.h"
|
||||
#include "ceres/internal/eigen.h"
|
||||
#include "ceres/internal/fixed_array.h"
|
||||
#include "ceres/internal/macros.h"
|
||||
#include "ceres/internal/scoped_ptr.h"
|
||||
#include "ceres/numeric_diff_cost_function.h"
|
||||
#include "ceres/local_parameterization.h"
|
||||
#include "glog/logging.h"
|
||||
|
||||
namespace ceres {
|
||||
|
||||
// An object that exercises a cost function, to compare the answers that it
|
||||
// gives with derivatives estimated using finite differencing.
|
||||
// GradientChecker compares the Jacobians returned by a cost function against
|
||||
// derivatives estimated using finite differencing.
|
||||
//
|
||||
// The only likely usage of this is for testing.
|
||||
// The condition enforced is that
|
||||
//
|
||||
// (J_actual(i, j) - J_numeric(i, j))
|
||||
// ------------------------------------ < relative_precision
|
||||
// max(J_actual(i, j), J_numeric(i, j))
|
||||
//
|
||||
// where J_actual(i, j) is the jacobian as computed by the supplied cost
|
||||
// function (by the user) multiplied by the local parameterization Jacobian
|
||||
// and J_numeric is the jacobian as computed by finite differences, multiplied
|
||||
// by the local parameterization Jacobian as well.
|
||||
//
|
||||
// How to use: Fill in an array of pointers to parameter blocks for your
|
||||
// CostFunction, and then call Probe(). Check that the return value is
|
||||
// 'true'. See prober_test.cc for an example.
|
||||
//
|
||||
// This is templated similarly to NumericDiffCostFunction, as it internally
|
||||
// uses that.
|
||||
template <typename CostFunctionToProbe,
|
||||
int M = 0, int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0>
|
||||
// CostFunction, and then call Probe(). Check that the return value is 'true'.
|
||||
class GradientChecker {
|
||||
public:
|
||||
// Here we stash some results from the probe, for later
|
||||
// inspection.
|
||||
struct GradientCheckResults {
|
||||
// Computed cost.
|
||||
Vector cost;
|
||||
// This will not take ownership of the cost function or local
|
||||
// parameterizations.
|
||||
//
|
||||
// function: The cost function to probe.
|
||||
// local_parameterization: A vector of local parameterizations for each
|
||||
// parameter. May be NULL or contain NULL pointers to indicate that the
|
||||
// respective parameter does not have a local parameterization.
|
||||
// options: Options to use for numerical differentiation.
|
||||
GradientChecker(
|
||||
const CostFunction* function,
|
||||
const std::vector<const LocalParameterization*>* local_parameterizations,
|
||||
const NumericDiffOptions& options);
|
||||
|
||||
// The sizes of these matrices are dictated by the cost function's
|
||||
// parameter and residual block sizes. Each vector's length will
|
||||
// term->parameter_block_sizes().size(), and each matrix is the
|
||||
// Jacobian of the residual with respect to the corresponding parameter
|
||||
// block.
|
||||
// Contains results from a call to Probe for later inspection.
|
||||
struct ProbeResults {
|
||||
// The return value of the cost function.
|
||||
bool return_value;
|
||||
|
||||
// Computed residual vector.
|
||||
Vector residuals;
|
||||
|
||||
// The sizes of the Jacobians below are dictated by the cost function's
|
||||
// parameter block size and residual block sizes. If a parameter block
|
||||
// has a local parameterization associated with it, the size of the "local"
|
||||
// Jacobian will be determined by the local parameterization dimension and
|
||||
// residual block size, otherwise it will be identical to the regular
|
||||
// Jacobian.
|
||||
|
||||
// Derivatives as computed by the cost function.
|
||||
std::vector<Matrix> term_jacobians;
|
||||
std::vector<Matrix> jacobians;
|
||||
|
||||
// Derivatives as computed by finite differencing.
|
||||
std::vector<Matrix> finite_difference_jacobians;
|
||||
// Derivatives as computed by the cost function in local space.
|
||||
std::vector<Matrix> local_jacobians;
|
||||
|
||||
// Infinity-norm of term_jacobians - finite_difference_jacobians.
|
||||
double error_jacobians;
|
||||
// Derivatives as computed by nuerical differentiation in local space.
|
||||
std::vector<Matrix> numeric_jacobians;
|
||||
|
||||
// Derivatives as computed by nuerical differentiation in local space.
|
||||
std::vector<Matrix> local_numeric_jacobians;
|
||||
|
||||
// Contains the maximum relative error found in the local Jacobians.
|
||||
double maximum_relative_error;
|
||||
|
||||
// If an error was detected, this will contain a detailed description of
|
||||
// that error.
|
||||
std::string error_log;
|
||||
};
|
||||
|
||||
// Checks the Jacobian computed by a cost function.
|
||||
// Call the cost function, compute alternative Jacobians using finite
|
||||
// differencing and compare results. If local parameterizations are given,
|
||||
// the Jacobians will be multiplied by the local parameterization Jacobians
|
||||
// before performing the check, which effectively means that all errors along
|
||||
// the null space of the local parameterization will be ignored.
|
||||
// Returns false if the Jacobians don't match, the cost function return false,
|
||||
// or if the cost function returns different residual when called with a
|
||||
// Jacobian output argument vs. calling it without. Otherwise returns true.
|
||||
//
|
||||
// probe_point: The parameter values at which to probe.
|
||||
// error_tolerance: A threshold for the infinity-norm difference
|
||||
// between the Jacobians. If the Jacobians differ by more than
|
||||
// this amount, then the probe fails.
|
||||
//
|
||||
// term: The cost function to test. Not retained after this call returns.
|
||||
//
|
||||
// results: On return, the two Jacobians (and other information)
|
||||
// will be stored here. May be NULL.
|
||||
// parameters: The parameter values at which to probe.
|
||||
// relative_precision: A threshold for the relative difference between the
|
||||
// Jacobians. If the Jacobians differ by more than this amount, then the
|
||||
// probe fails.
|
||||
// results: On return, the Jacobians (and other information) will be stored
|
||||
// here. May be NULL.
|
||||
//
|
||||
// Returns true if no problems are detected and the difference between the
|
||||
// Jacobians is less than error_tolerance.
|
||||
static bool Probe(double const* const* probe_point,
|
||||
double error_tolerance,
|
||||
CostFunctionToProbe *term,
|
||||
GradientCheckResults* results) {
|
||||
CHECK_NOTNULL(probe_point);
|
||||
CHECK_NOTNULL(term);
|
||||
LOG(INFO) << "-------------------- Starting Probe() --------------------";
|
||||
|
||||
// We need a GradientCheckeresults, whether or not they supplied one.
|
||||
internal::scoped_ptr<GradientCheckResults> owned_results;
|
||||
if (results == NULL) {
|
||||
owned_results.reset(new GradientCheckResults);
|
||||
results = owned_results.get();
|
||||
}
|
||||
|
||||
// Do a consistency check between the term and the template parameters.
|
||||
CHECK_EQ(M, term->num_residuals());
|
||||
const int num_residuals = M;
|
||||
const std::vector<int32>& block_sizes = term->parameter_block_sizes();
|
||||
const int num_blocks = block_sizes.size();
|
||||
|
||||
CHECK_LE(num_blocks, 5) << "Unable to test functions that take more "
|
||||
<< "than 5 parameter blocks";
|
||||
if (N0) {
|
||||
CHECK_EQ(N0, block_sizes[0]);
|
||||
CHECK_GE(num_blocks, 1);
|
||||
} else {
|
||||
CHECK_LT(num_blocks, 1);
|
||||
}
|
||||
if (N1) {
|
||||
CHECK_EQ(N1, block_sizes[1]);
|
||||
CHECK_GE(num_blocks, 2);
|
||||
} else {
|
||||
CHECK_LT(num_blocks, 2);
|
||||
}
|
||||
if (N2) {
|
||||
CHECK_EQ(N2, block_sizes[2]);
|
||||
CHECK_GE(num_blocks, 3);
|
||||
} else {
|
||||
CHECK_LT(num_blocks, 3);
|
||||
}
|
||||
if (N3) {
|
||||
CHECK_EQ(N3, block_sizes[3]);
|
||||
CHECK_GE(num_blocks, 4);
|
||||
} else {
|
||||
CHECK_LT(num_blocks, 4);
|
||||
}
|
||||
if (N4) {
|
||||
CHECK_EQ(N4, block_sizes[4]);
|
||||
CHECK_GE(num_blocks, 5);
|
||||
} else {
|
||||
CHECK_LT(num_blocks, 5);
|
||||
}
|
||||
|
||||
results->term_jacobians.clear();
|
||||
results->term_jacobians.resize(num_blocks);
|
||||
results->finite_difference_jacobians.clear();
|
||||
results->finite_difference_jacobians.resize(num_blocks);
|
||||
|
||||
internal::FixedArray<double*> term_jacobian_pointers(num_blocks);
|
||||
internal::FixedArray<double*>
|
||||
finite_difference_jacobian_pointers(num_blocks);
|
||||
for (int i = 0; i < num_blocks; i++) {
|
||||
results->term_jacobians[i].resize(num_residuals, block_sizes[i]);
|
||||
term_jacobian_pointers[i] = results->term_jacobians[i].data();
|
||||
results->finite_difference_jacobians[i].resize(
|
||||
num_residuals, block_sizes[i]);
|
||||
finite_difference_jacobian_pointers[i] =
|
||||
results->finite_difference_jacobians[i].data();
|
||||
}
|
||||
results->cost.resize(num_residuals, 1);
|
||||
|
||||
CHECK(term->Evaluate(probe_point, results->cost.data(),
|
||||
term_jacobian_pointers.get()));
|
||||
NumericDiffCostFunction<CostFunctionToProbe, CENTRAL, M, N0, N1, N2, N3, N4>
|
||||
numeric_term(term, DO_NOT_TAKE_OWNERSHIP);
|
||||
CHECK(numeric_term.Evaluate(probe_point, results->cost.data(),
|
||||
finite_difference_jacobian_pointers.get()));
|
||||
|
||||
results->error_jacobians = 0;
|
||||
for (int i = 0; i < num_blocks; i++) {
|
||||
Matrix jacobian_difference = results->term_jacobians[i] -
|
||||
results->finite_difference_jacobians[i];
|
||||
results->error_jacobians =
|
||||
std::max(results->error_jacobians,
|
||||
jacobian_difference.lpNorm<Eigen::Infinity>());
|
||||
}
|
||||
|
||||
LOG(INFO) << "========== term-computed derivatives ==========";
|
||||
for (int i = 0; i < num_blocks; i++) {
|
||||
LOG(INFO) << "term_computed block " << i;
|
||||
LOG(INFO) << "\n" << results->term_jacobians[i];
|
||||
}
|
||||
|
||||
LOG(INFO) << "========== finite-difference derivatives ==========";
|
||||
for (int i = 0; i < num_blocks; i++) {
|
||||
LOG(INFO) << "finite_difference block " << i;
|
||||
LOG(INFO) << "\n" << results->finite_difference_jacobians[i];
|
||||
}
|
||||
|
||||
LOG(INFO) << "========== difference ==========";
|
||||
for (int i = 0; i < num_blocks; i++) {
|
||||
LOG(INFO) << "difference block " << i;
|
||||
LOG(INFO) << (results->term_jacobians[i] -
|
||||
results->finite_difference_jacobians[i]);
|
||||
}
|
||||
|
||||
LOG(INFO) << "||difference|| = " << results->error_jacobians;
|
||||
|
||||
return results->error_jacobians < error_tolerance;
|
||||
}
|
||||
bool Probe(double const* const* parameters,
|
||||
double relative_precision,
|
||||
ProbeResults* results) const;
|
||||
|
||||
private:
|
||||
CERES_DISALLOW_IMPLICIT_CONSTRUCTORS(GradientChecker);
|
||||
|
||||
std::vector<const LocalParameterization*> local_parameterizations_;
|
||||
const CostFunction* function_;
|
||||
internal::scoped_ptr<CostFunction> finite_diff_cost_function_;
|
||||
};
|
||||
|
||||
} // namespace ceres
|
||||
|
22
extern/ceres/include/ceres/internal/port.h
vendored
22
extern/ceres/include/ceres/internal/port.h
vendored
@@ -33,9 +33,8 @@
|
||||
|
||||
// This file needs to compile as c code.
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <cstddef>
|
||||
#include "ceres/internal/config.h"
|
||||
|
||||
#if defined(CERES_TR1_MEMORY_HEADER)
|
||||
#include <tr1/memory>
|
||||
#else
|
||||
@@ -50,6 +49,25 @@ using std::tr1::shared_ptr;
|
||||
using std::shared_ptr;
|
||||
#endif
|
||||
|
||||
// We allocate some Eigen objects on the stack and other places they
|
||||
// might not be aligned to 16-byte boundaries. If we have C++11, we
|
||||
// can specify their alignment anyway, and thus can safely enable
|
||||
// vectorization on those matrices; in C++99, we are out of luck. Figure out
|
||||
// what case we're in and write macros that do the right thing.
|
||||
#ifdef CERES_USE_CXX11
|
||||
namespace port_constants {
|
||||
static constexpr size_t kMaxAlignBytes =
|
||||
// Work around a GCC 4.8 bug
|
||||
// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56019) where
|
||||
// std::max_align_t is misplaced.
|
||||
#if defined (__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8
|
||||
alignof(::max_align_t);
|
||||
#else
|
||||
alignof(std::max_align_t);
|
||||
#endif
|
||||
} // namespace port_constants
|
||||
#endif
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
#endif // __cplusplus
|
||||
|
@@ -69,7 +69,7 @@ struct CERES_EXPORT IterationSummary {
|
||||
// Step was numerically valid, i.e., all values are finite and the
|
||||
// step reduces the value of the linearized model.
|
||||
//
|
||||
// Note: step_is_valid is false when iteration = 0.
|
||||
// Note: step_is_valid is always true when iteration = 0.
|
||||
bool step_is_valid;
|
||||
|
||||
// Step did not reduce the value of the objective function
|
||||
@@ -77,7 +77,7 @@ struct CERES_EXPORT IterationSummary {
|
||||
// acceptance criterion used by the non-monotonic trust region
|
||||
// algorithm.
|
||||
//
|
||||
// Note: step_is_nonmonotonic is false when iteration = 0;
|
||||
// Note: step_is_nonmonotonic is always false when iteration = 0;
|
||||
bool step_is_nonmonotonic;
|
||||
|
||||
// Whether or not the minimizer accepted this step or not. If the
|
||||
@@ -89,7 +89,7 @@ struct CERES_EXPORT IterationSummary {
|
||||
// relative decrease is not sufficient, the algorithm may accept the
|
||||
// step and the step is declared successful.
|
||||
//
|
||||
// Note: step_is_successful is false when iteration = 0.
|
||||
// Note: step_is_successful is always true when iteration = 0.
|
||||
bool step_is_successful;
|
||||
|
||||
// Value of the objective function.
|
||||
|
106
extern/ceres/include/ceres/jet.h
vendored
106
extern/ceres/include/ceres/jet.h
vendored
@@ -164,6 +164,7 @@
|
||||
|
||||
#include "Eigen/Core"
|
||||
#include "ceres/fpclassify.h"
|
||||
#include "ceres/internal/port.h"
|
||||
|
||||
namespace ceres {
|
||||
|
||||
@@ -227,21 +228,23 @@ struct Jet {
|
||||
T a;
|
||||
|
||||
// The infinitesimal part.
|
||||
//
|
||||
// Note the Eigen::DontAlign bit is needed here because this object
|
||||
// gets allocated on the stack and as part of other arrays and
|
||||
// structs. Forcing the right alignment there is the source of much
|
||||
// pain and suffering. Even if that works, passing Jets around to
|
||||
// functions by value has problems because the C++ ABI does not
|
||||
// guarantee alignment for function arguments.
|
||||
//
|
||||
// Setting the DontAlign bit prevents Eigen from using SSE for the
|
||||
// various operations on Jets. This is a small performance penalty
|
||||
// since the AutoDiff code will still expose much of the code as
|
||||
// statically sized loops to the compiler. But given the subtle
|
||||
// issues that arise due to alignment, especially when dealing with
|
||||
// multiple platforms, it seems to be a trade off worth making.
|
||||
|
||||
// We allocate Jets on the stack and other places they
|
||||
// might not be aligned to 16-byte boundaries. If we have C++11, we
|
||||
// can specify their alignment anyway, and thus can safely enable
|
||||
// vectorization on those matrices; in C++99, we are out of luck. Figure out
|
||||
// what case we're in and do the right thing.
|
||||
#ifndef CERES_USE_CXX11
|
||||
// fall back to safe version:
|
||||
Eigen::Matrix<T, N, 1, Eigen::DontAlign> v;
|
||||
#else
|
||||
static constexpr bool kShouldAlignMatrix =
|
||||
16 <= ::ceres::port_constants::kMaxAlignBytes;
|
||||
static constexpr int kAlignHint = kShouldAlignMatrix ?
|
||||
Eigen::AutoAlign : Eigen::DontAlign;
|
||||
static constexpr size_t kAlignment = kShouldAlignMatrix ? 16 : 1;
|
||||
alignas(kAlignment) Eigen::Matrix<T, N, 1, kAlignHint> v;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Unary +
|
||||
@@ -388,6 +391,8 @@ inline double atan (double x) { return std::atan(x); }
|
||||
inline double sinh (double x) { return std::sinh(x); }
|
||||
inline double cosh (double x) { return std::cosh(x); }
|
||||
inline double tanh (double x) { return std::tanh(x); }
|
||||
inline double floor (double x) { return std::floor(x); }
|
||||
inline double ceil (double x) { return std::ceil(x); }
|
||||
inline double pow (double x, double y) { return std::pow(x, y); }
|
||||
inline double atan2(double y, double x) { return std::atan2(y, x); }
|
||||
|
||||
@@ -482,10 +487,51 @@ Jet<T, N> tanh(const Jet<T, N>& f) {
|
||||
return Jet<T, N>(tanh_a, tmp * f.v);
|
||||
}
|
||||
|
||||
// The floor function should be used with extreme care as this operation will
|
||||
// result in a zero derivative which provides no information to the solver.
|
||||
//
|
||||
// floor(a + h) ~= floor(a) + 0
|
||||
template <typename T, int N> inline
|
||||
Jet<T, N> floor(const Jet<T, N>& f) {
|
||||
return Jet<T, N>(floor(f.a));
|
||||
}
|
||||
|
||||
// The ceil function should be used with extreme care as this operation will
|
||||
// result in a zero derivative which provides no information to the solver.
|
||||
//
|
||||
// ceil(a + h) ~= ceil(a) + 0
|
||||
template <typename T, int N> inline
|
||||
Jet<T, N> ceil(const Jet<T, N>& f) {
|
||||
return Jet<T, N>(ceil(f.a));
|
||||
}
|
||||
|
||||
// Bessel functions of the first kind with integer order equal to 0, 1, n.
|
||||
inline double BesselJ0(double x) { return j0(x); }
|
||||
inline double BesselJ1(double x) { return j1(x); }
|
||||
inline double BesselJn(int n, double x) { return jn(n, x); }
|
||||
//
|
||||
// Microsoft has deprecated the j[0,1,n]() POSIX Bessel functions in favour of
|
||||
// _j[0,1,n](). Where available on MSVC, use _j[0,1,n]() to avoid deprecated
|
||||
// function errors in client code (the specific warning is suppressed when
|
||||
// Ceres itself is built).
|
||||
inline double BesselJ0(double x) {
|
||||
#if defined(_MSC_VER) && defined(_j0)
|
||||
return _j0(x);
|
||||
#else
|
||||
return j0(x);
|
||||
#endif
|
||||
}
|
||||
inline double BesselJ1(double x) {
|
||||
#if defined(_MSC_VER) && defined(_j1)
|
||||
return _j1(x);
|
||||
#else
|
||||
return j1(x);
|
||||
#endif
|
||||
}
|
||||
inline double BesselJn(int n, double x) {
|
||||
#if defined(_MSC_VER) && defined(_jn)
|
||||
return _jn(n, x);
|
||||
#else
|
||||
return jn(n, x);
|
||||
#endif
|
||||
}
|
||||
|
||||
// For the formulae of the derivatives of the Bessel functions see the book:
|
||||
// Olver, Lozier, Boisvert, Clark, NIST Handbook of Mathematical Functions,
|
||||
@@ -743,7 +789,15 @@ template<typename T, int N> inline Jet<T, N> ei_pow (const Jet<T, N>& x,
|
||||
// strange compile errors.
|
||||
template <typename T, int N>
|
||||
inline std::ostream &operator<<(std::ostream &s, const Jet<T, N>& z) {
|
||||
return s << "[" << z.a << " ; " << z.v.transpose() << "]";
|
||||
s << "[" << z.a << " ; ";
|
||||
for (int i = 0; i < N; ++i) {
|
||||
s << z.v[i];
|
||||
if (i != N - 1) {
|
||||
s << ", ";
|
||||
}
|
||||
}
|
||||
s << "]";
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace ceres
|
||||
@@ -757,6 +811,7 @@ struct NumTraits<ceres::Jet<T, N> > {
|
||||
typedef ceres::Jet<T, N> Real;
|
||||
typedef ceres::Jet<T, N> NonInteger;
|
||||
typedef ceres::Jet<T, N> Nested;
|
||||
typedef ceres::Jet<T, N> Literal;
|
||||
|
||||
static typename ceres::Jet<T, N> dummy_precision() {
|
||||
return ceres::Jet<T, N>(1e-12);
|
||||
@@ -777,6 +832,21 @@ struct NumTraits<ceres::Jet<T, N> > {
|
||||
HasFloatingPoint = 1,
|
||||
RequireInitialization = 1
|
||||
};
|
||||
|
||||
template<bool Vectorized>
|
||||
struct Div {
|
||||
enum {
|
||||
#if defined(EIGEN_VECTORIZE_AVX)
|
||||
AVX = true,
|
||||
#else
|
||||
AVX = false,
|
||||
#endif
|
||||
|
||||
// Assuming that for Jets, division is as expensive as
|
||||
// multiplication.
|
||||
Cost = 3
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace Eigen
|
||||
|
@@ -211,6 +211,28 @@ class CERES_EXPORT QuaternionParameterization : public LocalParameterization {
|
||||
virtual int LocalSize() const { return 3; }
|
||||
};
|
||||
|
||||
// Implements the quaternion local parameterization for Eigen's representation
|
||||
// of the quaternion. Eigen uses a different internal memory layout for the
|
||||
// elements of the quaternion than what is commonly used. Specifically, Eigen
|
||||
// stores the elements in memory as [x, y, z, w] where the real part is last
|
||||
// whereas it is typically stored first. Note, when creating an Eigen quaternion
|
||||
// through the constructor the elements are accepted in w, x, y, z order. Since
|
||||
// Ceres operates on parameter blocks which are raw double pointers this
|
||||
// difference is important and requires a different parameterization.
|
||||
//
|
||||
// Plus(x, delta) = [sin(|delta|) delta / |delta|, cos(|delta|)] * x
|
||||
// with * being the quaternion multiplication operator.
|
||||
class EigenQuaternionParameterization : public ceres::LocalParameterization {
|
||||
public:
|
||||
virtual ~EigenQuaternionParameterization() {}
|
||||
virtual bool Plus(const double* x,
|
||||
const double* delta,
|
||||
double* x_plus_delta) const;
|
||||
virtual bool ComputeJacobian(const double* x,
|
||||
double* jacobian) const;
|
||||
virtual int GlobalSize() const { return 4; }
|
||||
virtual int LocalSize() const { return 3; }
|
||||
};
|
||||
|
||||
// This provides a parameterization for homogeneous vectors which are commonly
|
||||
// used in Structure for Motion problems. One example where they are used is
|
||||
|
@@ -206,29 +206,6 @@ class NumericDiffCostFunction
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated. New users should avoid using this constructor. Instead, use the
|
||||
// constructor with NumericDiffOptions.
|
||||
NumericDiffCostFunction(CostFunctor* functor,
|
||||
Ownership ownership,
|
||||
int num_residuals,
|
||||
const double relative_step_size)
|
||||
:functor_(functor),
|
||||
ownership_(ownership),
|
||||
options_() {
|
||||
LOG(WARNING) << "This constructor is deprecated and will be removed in "
|
||||
"a future version. Please use the NumericDiffOptions "
|
||||
"constructor instead.";
|
||||
|
||||
if (kNumResiduals == DYNAMIC) {
|
||||
SizedCostFunction<kNumResiduals,
|
||||
N0, N1, N2, N3, N4,
|
||||
N5, N6, N7, N8, N9>
|
||||
::set_num_residuals(num_residuals);
|
||||
}
|
||||
|
||||
options_.relative_step_size = relative_step_size;
|
||||
}
|
||||
|
||||
~NumericDiffCostFunction() {
|
||||
if (ownership_ != TAKE_OWNERSHIP) {
|
||||
functor_.release();
|
||||
|
7
extern/ceres/include/ceres/problem.h
vendored
7
extern/ceres/include/ceres/problem.h
vendored
@@ -309,6 +309,9 @@ class CERES_EXPORT Problem {
|
||||
// Allow the indicated parameter block to vary during optimization.
|
||||
void SetParameterBlockVariable(double* values);
|
||||
|
||||
// Returns true if a parameter block is set constant, and false otherwise.
|
||||
bool IsParameterBlockConstant(double* values) const;
|
||||
|
||||
// Set the local parameterization for one of the parameter blocks.
|
||||
// The local_parameterization is owned by the Problem by default. It
|
||||
// is acceptable to set the same parameterization for multiple
|
||||
@@ -461,6 +464,10 @@ class CERES_EXPORT Problem {
|
||||
// parameter block has a local parameterization, then it contributes
|
||||
// "LocalSize" entries to the gradient vector (and the number of
|
||||
// columns in the jacobian).
|
||||
//
|
||||
// Note 3: This function cannot be called while the problem is being
|
||||
// solved, for example it cannot be called from an IterationCallback
|
||||
// at the end of an iteration during a solve.
|
||||
bool Evaluate(const EvaluateOptions& options,
|
||||
double* cost,
|
||||
std::vector<double>* residuals,
|
||||
|
3
extern/ceres/include/ceres/rotation.h
vendored
3
extern/ceres/include/ceres/rotation.h
vendored
@@ -48,7 +48,6 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include "glog/logging.h"
|
||||
|
||||
namespace ceres {
|
||||
|
||||
@@ -418,7 +417,6 @@ template <typename T>
|
||||
inline void EulerAnglesToRotationMatrix(const T* euler,
|
||||
const int row_stride_parameter,
|
||||
T* R) {
|
||||
CHECK_EQ(row_stride_parameter, 3);
|
||||
EulerAnglesToRotationMatrix(euler, RowMajorAdapter3x3(R));
|
||||
}
|
||||
|
||||
@@ -496,7 +494,6 @@ void QuaternionToRotation(const T q[4],
|
||||
QuaternionToScaledRotation(q, R);
|
||||
|
||||
T normalizer = q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3];
|
||||
CHECK_NE(normalizer, T(0));
|
||||
normalizer = T(1) / normalizer;
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
|
31
extern/ceres/include/ceres/solver.h
vendored
31
extern/ceres/include/ceres/solver.h
vendored
@@ -134,7 +134,7 @@ class CERES_EXPORT Solver {
|
||||
trust_region_problem_dump_format_type = TEXTFILE;
|
||||
check_gradients = false;
|
||||
gradient_check_relative_precision = 1e-8;
|
||||
numeric_derivative_relative_step_size = 1e-6;
|
||||
gradient_check_numeric_derivative_relative_step_size = 1e-6;
|
||||
update_state_every_iteration = false;
|
||||
}
|
||||
|
||||
@@ -701,12 +701,22 @@ class CERES_EXPORT Solver {
|
||||
// this number, then the jacobian for that cost term is dumped.
|
||||
double gradient_check_relative_precision;
|
||||
|
||||
// Relative shift used for taking numeric derivatives. For finite
|
||||
// differencing, each dimension is evaluated at slightly shifted
|
||||
// values; for the case of central difference, this is what gets
|
||||
// evaluated:
|
||||
// WARNING: This option only applies to the to the numeric
|
||||
// differentiation used for checking the user provided derivatives
|
||||
// when when Solver::Options::check_gradients is true. If you are
|
||||
// using NumericDiffCostFunction and are interested in changing
|
||||
// the step size for numeric differentiation in your cost
|
||||
// function, please have a look at
|
||||
// include/ceres/numeric_diff_options.h.
|
||||
//
|
||||
// delta = numeric_derivative_relative_step_size;
|
||||
// Relative shift used for taking numeric derivatives when
|
||||
// Solver::Options::check_gradients is true.
|
||||
//
|
||||
// For finite differencing, each dimension is evaluated at
|
||||
// slightly shifted values; for the case of central difference,
|
||||
// this is what gets evaluated:
|
||||
//
|
||||
// delta = gradient_check_numeric_derivative_relative_step_size;
|
||||
// f_initial = f(x)
|
||||
// f_forward = f((1 + delta) * x)
|
||||
// f_backward = f((1 - delta) * x)
|
||||
@@ -723,7 +733,7 @@ class CERES_EXPORT Solver {
|
||||
// theory a good choice is sqrt(eps) * x, which for doubles means
|
||||
// about 1e-8 * x. However, I have found this number too
|
||||
// optimistic. This number should be exposed for users to change.
|
||||
double numeric_derivative_relative_step_size;
|
||||
double gradient_check_numeric_derivative_relative_step_size;
|
||||
|
||||
// If true, the user's parameter blocks are updated at the end of
|
||||
// every Minimizer iteration, otherwise they are updated when the
|
||||
@@ -801,6 +811,13 @@ class CERES_EXPORT Solver {
|
||||
// Number of times inner iterations were performed.
|
||||
int num_inner_iteration_steps;
|
||||
|
||||
// Total number of iterations inside the line search algorithm
|
||||
// across all invocations. We call these iterations "steps" to
|
||||
// distinguish them from the outer iterations of the line search
|
||||
// and trust region minimizer algorithms which call the line
|
||||
// search algorithm as a subroutine.
|
||||
int num_line_search_steps;
|
||||
|
||||
// All times reported below are wall times.
|
||||
|
||||
// When the user calls Solve, before the actual optimization
|
||||
|
2
extern/ceres/include/ceres/version.h
vendored
2
extern/ceres/include/ceres/version.h
vendored
@@ -32,7 +32,7 @@
|
||||
#define CERES_PUBLIC_VERSION_H_
|
||||
|
||||
#define CERES_VERSION_MAJOR 1
|
||||
#define CERES_VERSION_MINOR 11
|
||||
#define CERES_VERSION_MINOR 12
|
||||
#define CERES_VERSION_REVISION 0
|
||||
|
||||
// Classic CPP stringifcation; the extra level of indirection allows the
|
||||
|
@@ -46,6 +46,7 @@ namespace internal {
|
||||
using std::make_pair;
|
||||
using std::pair;
|
||||
using std::vector;
|
||||
using std::adjacent_find;
|
||||
|
||||
void CompressedRowJacobianWriter::PopulateJacobianRowAndColumnBlockVectors(
|
||||
const Program* program, CompressedRowSparseMatrix* jacobian) {
|
||||
@@ -140,12 +141,21 @@ SparseMatrix* CompressedRowJacobianWriter::CreateJacobian() const {
|
||||
|
||||
// Sort the parameters by their position in the state vector.
|
||||
sort(parameter_indices.begin(), parameter_indices.end());
|
||||
CHECK(unique(parameter_indices.begin(), parameter_indices.end()) ==
|
||||
parameter_indices.end())
|
||||
<< "Ceres internal error: "
|
||||
<< "Duplicate parameter blocks detected in a cost function. "
|
||||
<< "This should never happen. Please report this to "
|
||||
<< "the Ceres developers.";
|
||||
if (adjacent_find(parameter_indices.begin(), parameter_indices.end()) !=
|
||||
parameter_indices.end()) {
|
||||
std::string parameter_block_description;
|
||||
for (int j = 0; j < num_parameter_blocks; ++j) {
|
||||
ParameterBlock* parameter_block = residual_block->parameter_blocks()[j];
|
||||
parameter_block_description +=
|
||||
parameter_block->ToString() + "\n";
|
||||
}
|
||||
LOG(FATAL) << "Ceres internal error: "
|
||||
<< "Duplicate parameter blocks detected in a cost function. "
|
||||
<< "This should never happen. Please report this to "
|
||||
<< "the Ceres developers.\n"
|
||||
<< "Residual Block: " << residual_block->ToString() << "\n"
|
||||
<< "Parameter Blocks: " << parameter_block_description;
|
||||
}
|
||||
|
||||
// Update the row indices.
|
||||
const int num_residuals = residual_block->NumResiduals();
|
||||
|
23
extern/ceres/internal/ceres/covariance.cc
vendored
23
extern/ceres/internal/ceres/covariance.cc
vendored
@@ -38,6 +38,7 @@
|
||||
|
||||
namespace ceres {
|
||||
|
||||
using std::make_pair;
|
||||
using std::pair;
|
||||
using std::vector;
|
||||
|
||||
@@ -54,6 +55,12 @@ bool Covariance::Compute(
|
||||
return impl_->Compute(covariance_blocks, problem->problem_impl_.get());
|
||||
}
|
||||
|
||||
bool Covariance::Compute(
|
||||
const vector<const double*>& parameter_blocks,
|
||||
Problem* problem) {
|
||||
return impl_->Compute(parameter_blocks, problem->problem_impl_.get());
|
||||
}
|
||||
|
||||
bool Covariance::GetCovarianceBlock(const double* parameter_block1,
|
||||
const double* parameter_block2,
|
||||
double* covariance_block) const {
|
||||
@@ -73,4 +80,20 @@ bool Covariance::GetCovarianceBlockInTangentSpace(
|
||||
covariance_block);
|
||||
}
|
||||
|
||||
bool Covariance::GetCovarianceMatrix(
|
||||
const vector<const double*>& parameter_blocks,
|
||||
double* covariance_matrix) {
|
||||
return impl_->GetCovarianceMatrixInTangentOrAmbientSpace(parameter_blocks,
|
||||
true, // ambient
|
||||
covariance_matrix);
|
||||
}
|
||||
|
||||
bool Covariance::GetCovarianceMatrixInTangentSpace(
|
||||
const std::vector<const double *>& parameter_blocks,
|
||||
double *covariance_matrix) {
|
||||
return impl_->GetCovarianceMatrixInTangentOrAmbientSpace(parameter_blocks,
|
||||
false, // tangent
|
||||
covariance_matrix);
|
||||
}
|
||||
|
||||
} // namespace ceres
|
||||
|
172
extern/ceres/internal/ceres/covariance_impl.cc
vendored
172
extern/ceres/internal/ceres/covariance_impl.cc
vendored
@@ -36,6 +36,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -43,6 +45,7 @@
|
||||
#include "Eigen/SparseQR"
|
||||
#include "Eigen/SVD"
|
||||
|
||||
#include "ceres/collections_port.h"
|
||||
#include "ceres/compressed_col_sparse_matrix_utils.h"
|
||||
#include "ceres/compressed_row_sparse_matrix.h"
|
||||
#include "ceres/covariance.h"
|
||||
@@ -51,6 +54,7 @@
|
||||
#include "ceres/map_util.h"
|
||||
#include "ceres/parameter_block.h"
|
||||
#include "ceres/problem_impl.h"
|
||||
#include "ceres/residual_block.h"
|
||||
#include "ceres/suitesparse.h"
|
||||
#include "ceres/wall_time.h"
|
||||
#include "glog/logging.h"
|
||||
@@ -61,6 +65,7 @@ namespace internal {
|
||||
using std::make_pair;
|
||||
using std::map;
|
||||
using std::pair;
|
||||
using std::sort;
|
||||
using std::swap;
|
||||
using std::vector;
|
||||
|
||||
@@ -86,8 +91,38 @@ CovarianceImpl::CovarianceImpl(const Covariance::Options& options)
|
||||
CovarianceImpl::~CovarianceImpl() {
|
||||
}
|
||||
|
||||
template <typename T> void CheckForDuplicates(vector<T> blocks) {
|
||||
sort(blocks.begin(), blocks.end());
|
||||
typename vector<T>::iterator it =
|
||||
std::adjacent_find(blocks.begin(), blocks.end());
|
||||
if (it != blocks.end()) {
|
||||
// In case there are duplicates, we search for their location.
|
||||
map<T, vector<int> > blocks_map;
|
||||
for (int i = 0; i < blocks.size(); ++i) {
|
||||
blocks_map[blocks[i]].push_back(i);
|
||||
}
|
||||
|
||||
std::ostringstream duplicates;
|
||||
while (it != blocks.end()) {
|
||||
duplicates << "(";
|
||||
for (int i = 0; i < blocks_map[*it].size() - 1; ++i) {
|
||||
duplicates << blocks_map[*it][i] << ", ";
|
||||
}
|
||||
duplicates << blocks_map[*it].back() << ")";
|
||||
it = std::adjacent_find(it + 1, blocks.end());
|
||||
if (it < blocks.end()) {
|
||||
duplicates << " and ";
|
||||
}
|
||||
}
|
||||
|
||||
LOG(FATAL) << "Covariance::Compute called with duplicate blocks at "
|
||||
<< "indices " << duplicates.str();
|
||||
}
|
||||
}
|
||||
|
||||
bool CovarianceImpl::Compute(const CovarianceBlocks& covariance_blocks,
|
||||
ProblemImpl* problem) {
|
||||
CheckForDuplicates<pair<const double*, const double*> >(covariance_blocks);
|
||||
problem_ = problem;
|
||||
parameter_block_to_row_index_.clear();
|
||||
covariance_matrix_.reset(NULL);
|
||||
@@ -97,6 +132,20 @@ bool CovarianceImpl::Compute(const CovarianceBlocks& covariance_blocks,
|
||||
return is_valid_;
|
||||
}
|
||||
|
||||
bool CovarianceImpl::Compute(const vector<const double*>& parameter_blocks,
|
||||
ProblemImpl* problem) {
|
||||
CheckForDuplicates<const double*>(parameter_blocks);
|
||||
CovarianceBlocks covariance_blocks;
|
||||
for (int i = 0; i < parameter_blocks.size(); ++i) {
|
||||
for (int j = i; j < parameter_blocks.size(); ++j) {
|
||||
covariance_blocks.push_back(make_pair(parameter_blocks[i],
|
||||
parameter_blocks[j]));
|
||||
}
|
||||
}
|
||||
|
||||
return Compute(covariance_blocks, problem);
|
||||
}
|
||||
|
||||
bool CovarianceImpl::GetCovarianceBlockInTangentOrAmbientSpace(
|
||||
const double* original_parameter_block1,
|
||||
const double* original_parameter_block2,
|
||||
@@ -120,9 +169,17 @@ bool CovarianceImpl::GetCovarianceBlockInTangentOrAmbientSpace(
|
||||
ParameterBlock* block2 =
|
||||
FindOrDie(parameter_map,
|
||||
const_cast<double*>(original_parameter_block2));
|
||||
|
||||
const int block1_size = block1->Size();
|
||||
const int block2_size = block2->Size();
|
||||
MatrixRef(covariance_block, block1_size, block2_size).setZero();
|
||||
const int block1_local_size = block1->LocalSize();
|
||||
const int block2_local_size = block2->LocalSize();
|
||||
if (!lift_covariance_to_ambient_space) {
|
||||
MatrixRef(covariance_block, block1_local_size, block2_local_size)
|
||||
.setZero();
|
||||
} else {
|
||||
MatrixRef(covariance_block, block1_size, block2_size).setZero();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -240,6 +297,94 @@ bool CovarianceImpl::GetCovarianceBlockInTangentOrAmbientSpace(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CovarianceImpl::GetCovarianceMatrixInTangentOrAmbientSpace(
|
||||
const vector<const double*>& parameters,
|
||||
bool lift_covariance_to_ambient_space,
|
||||
double* covariance_matrix) const {
|
||||
CHECK(is_computed_)
|
||||
<< "Covariance::GetCovarianceMatrix called before Covariance::Compute";
|
||||
CHECK(is_valid_)
|
||||
<< "Covariance::GetCovarianceMatrix called when Covariance::Compute "
|
||||
<< "returned false.";
|
||||
|
||||
const ProblemImpl::ParameterMap& parameter_map = problem_->parameter_map();
|
||||
// For OpenMP compatibility we need to define these vectors in advance
|
||||
const int num_parameters = parameters.size();
|
||||
vector<int> parameter_sizes;
|
||||
vector<int> cum_parameter_size;
|
||||
parameter_sizes.reserve(num_parameters);
|
||||
cum_parameter_size.resize(num_parameters + 1);
|
||||
cum_parameter_size[0] = 0;
|
||||
for (int i = 0; i < num_parameters; ++i) {
|
||||
ParameterBlock* block =
|
||||
FindOrDie(parameter_map, const_cast<double*>(parameters[i]));
|
||||
if (lift_covariance_to_ambient_space) {
|
||||
parameter_sizes.push_back(block->Size());
|
||||
} else {
|
||||
parameter_sizes.push_back(block->LocalSize());
|
||||
}
|
||||
}
|
||||
std::partial_sum(parameter_sizes.begin(), parameter_sizes.end(),
|
||||
cum_parameter_size.begin() + 1);
|
||||
const int max_covariance_block_size =
|
||||
*std::max_element(parameter_sizes.begin(), parameter_sizes.end());
|
||||
const int covariance_size = cum_parameter_size.back();
|
||||
|
||||
// Assemble the blocks in the covariance matrix.
|
||||
MatrixRef covariance(covariance_matrix, covariance_size, covariance_size);
|
||||
const int num_threads = options_.num_threads;
|
||||
scoped_array<double> workspace(
|
||||
new double[num_threads * max_covariance_block_size *
|
||||
max_covariance_block_size]);
|
||||
|
||||
bool success = true;
|
||||
|
||||
// The collapse() directive is only supported in OpenMP 3.0 and higher. OpenMP
|
||||
// 3.0 was released in May 2008 (hence the version number).
|
||||
#if _OPENMP >= 200805
|
||||
# pragma omp parallel for num_threads(num_threads) schedule(dynamic) collapse(2)
|
||||
#else
|
||||
# pragma omp parallel for num_threads(num_threads) schedule(dynamic)
|
||||
#endif
|
||||
for (int i = 0; i < num_parameters; ++i) {
|
||||
for (int j = 0; j < num_parameters; ++j) {
|
||||
// The second loop can't start from j = i for compatibility with OpenMP
|
||||
// collapse command. The conditional serves as a workaround
|
||||
if (j >= i) {
|
||||
int covariance_row_idx = cum_parameter_size[i];
|
||||
int covariance_col_idx = cum_parameter_size[j];
|
||||
int size_i = parameter_sizes[i];
|
||||
int size_j = parameter_sizes[j];
|
||||
#ifdef CERES_USE_OPENMP
|
||||
int thread_id = omp_get_thread_num();
|
||||
#else
|
||||
int thread_id = 0;
|
||||
#endif
|
||||
double* covariance_block =
|
||||
workspace.get() +
|
||||
thread_id * max_covariance_block_size * max_covariance_block_size;
|
||||
if (!GetCovarianceBlockInTangentOrAmbientSpace(
|
||||
parameters[i], parameters[j], lift_covariance_to_ambient_space,
|
||||
covariance_block)) {
|
||||
success = false;
|
||||
}
|
||||
|
||||
covariance.block(covariance_row_idx, covariance_col_idx,
|
||||
size_i, size_j) =
|
||||
MatrixRef(covariance_block, size_i, size_j);
|
||||
|
||||
if (i != j) {
|
||||
covariance.block(covariance_col_idx, covariance_row_idx,
|
||||
size_j, size_i) =
|
||||
MatrixRef(covariance_block, size_i, size_j).transpose();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
// Determine the sparsity pattern of the covariance matrix based on
|
||||
// the block pairs requested by the user.
|
||||
bool CovarianceImpl::ComputeCovarianceSparsity(
|
||||
@@ -252,18 +397,28 @@ bool CovarianceImpl::ComputeCovarianceSparsity(
|
||||
vector<double*> all_parameter_blocks;
|
||||
problem->GetParameterBlocks(&all_parameter_blocks);
|
||||
const ProblemImpl::ParameterMap& parameter_map = problem->parameter_map();
|
||||
HashSet<ParameterBlock*> parameter_blocks_in_use;
|
||||
vector<ResidualBlock*> residual_blocks;
|
||||
problem->GetResidualBlocks(&residual_blocks);
|
||||
|
||||
for (int i = 0; i < residual_blocks.size(); ++i) {
|
||||
ResidualBlock* residual_block = residual_blocks[i];
|
||||
parameter_blocks_in_use.insert(residual_block->parameter_blocks(),
|
||||
residual_block->parameter_blocks() +
|
||||
residual_block->NumParameterBlocks());
|
||||
}
|
||||
|
||||
constant_parameter_blocks_.clear();
|
||||
vector<double*>& active_parameter_blocks =
|
||||
evaluate_options_.parameter_blocks;
|
||||
active_parameter_blocks.clear();
|
||||
for (int i = 0; i < all_parameter_blocks.size(); ++i) {
|
||||
double* parameter_block = all_parameter_blocks[i];
|
||||
|
||||
ParameterBlock* block = FindOrDie(parameter_map, parameter_block);
|
||||
if (block->IsConstant()) {
|
||||
constant_parameter_blocks_.insert(parameter_block);
|
||||
} else {
|
||||
if (!block->IsConstant() && (parameter_blocks_in_use.count(block) > 0)) {
|
||||
active_parameter_blocks.push_back(parameter_block);
|
||||
} else {
|
||||
constant_parameter_blocks_.insert(parameter_block);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,8 +541,8 @@ bool CovarianceImpl::ComputeCovarianceValues() {
|
||||
switch (options_.algorithm_type) {
|
||||
case DENSE_SVD:
|
||||
return ComputeCovarianceValuesUsingDenseSVD();
|
||||
#ifndef CERES_NO_SUITESPARSE
|
||||
case SUITE_SPARSE_QR:
|
||||
#ifndef CERES_NO_SUITESPARSE
|
||||
return ComputeCovarianceValuesUsingSuiteSparseQR();
|
||||
#else
|
||||
LOG(ERROR) << "SuiteSparse is required to use the "
|
||||
@@ -624,7 +779,10 @@ bool CovarianceImpl::ComputeCovarianceValuesUsingDenseSVD() {
|
||||
if (automatic_truncation) {
|
||||
break;
|
||||
} else {
|
||||
LOG(ERROR) << "Cholesky factorization of J'J is not reliable. "
|
||||
LOG(ERROR) << "Error: Covariance matrix is near rank deficient "
|
||||
<< "and the user did not specify a non-zero"
|
||||
<< "Covariance::Options::null_space_rank "
|
||||
<< "to enable the computation of a Pseudo-Inverse. "
|
||||
<< "Reciprocal condition number: "
|
||||
<< singular_value_ratio * singular_value_ratio << " "
|
||||
<< "min_reciprocal_condition_number: "
|
||||
|
@@ -55,12 +55,21 @@ class CovarianceImpl {
|
||||
const double*> >& covariance_blocks,
|
||||
ProblemImpl* problem);
|
||||
|
||||
bool Compute(
|
||||
const std::vector<const double*>& parameter_blocks,
|
||||
ProblemImpl* problem);
|
||||
|
||||
bool GetCovarianceBlockInTangentOrAmbientSpace(
|
||||
const double* parameter_block1,
|
||||
const double* parameter_block2,
|
||||
bool lift_covariance_to_ambient_space,
|
||||
double* covariance_block) const;
|
||||
|
||||
bool GetCovarianceMatrixInTangentOrAmbientSpace(
|
||||
const std::vector<const double*>& parameters,
|
||||
bool lift_covariance_to_ambient_space,
|
||||
double *covariance_matrix) const;
|
||||
|
||||
bool ComputeCovarianceSparsity(
|
||||
const std::vector<std::pair<const double*,
|
||||
const double*> >& covariance_blocks,
|
||||
|
276
extern/ceres/internal/ceres/gradient_checker.cc
vendored
Normal file
276
extern/ceres/internal/ceres/gradient_checker.cc
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// http://ceres-solver.org/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: wjr@google.com (William Rucklidge),
|
||||
// keir@google.com (Keir Mierle),
|
||||
// dgossow@google.com (David Gossow)
|
||||
|
||||
#include "ceres/gradient_checker.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ceres/is_close.h"
|
||||
#include "ceres/stringprintf.h"
|
||||
#include "ceres/types.h"
|
||||
|
||||
namespace ceres {
|
||||
|
||||
using internal::IsClose;
|
||||
using internal::StringAppendF;
|
||||
using internal::StringPrintf;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
namespace {
|
||||
// Evaluate the cost function and transform the returned Jacobians to
|
||||
// the local space of the respective local parameterizations.
|
||||
bool EvaluateCostFunction(
|
||||
const ceres::CostFunction* function,
|
||||
double const* const * parameters,
|
||||
const std::vector<const ceres::LocalParameterization*>&
|
||||
local_parameterizations,
|
||||
Vector* residuals,
|
||||
std::vector<Matrix>* jacobians,
|
||||
std::vector<Matrix>* local_jacobians) {
|
||||
CHECK_NOTNULL(residuals);
|
||||
CHECK_NOTNULL(jacobians);
|
||||
CHECK_NOTNULL(local_jacobians);
|
||||
|
||||
const vector<int32>& block_sizes = function->parameter_block_sizes();
|
||||
const int num_parameter_blocks = block_sizes.size();
|
||||
|
||||
// Allocate Jacobian matrices in local space.
|
||||
local_jacobians->resize(num_parameter_blocks);
|
||||
vector<double*> local_jacobian_data(num_parameter_blocks);
|
||||
for (int i = 0; i < num_parameter_blocks; ++i) {
|
||||
int block_size = block_sizes.at(i);
|
||||
if (local_parameterizations.at(i) != NULL) {
|
||||
block_size = local_parameterizations.at(i)->LocalSize();
|
||||
}
|
||||
local_jacobians->at(i).resize(function->num_residuals(), block_size);
|
||||
local_jacobians->at(i).setZero();
|
||||
local_jacobian_data.at(i) = local_jacobians->at(i).data();
|
||||
}
|
||||
|
||||
// Allocate Jacobian matrices in global space.
|
||||
jacobians->resize(num_parameter_blocks);
|
||||
vector<double*> jacobian_data(num_parameter_blocks);
|
||||
for (int i = 0; i < num_parameter_blocks; ++i) {
|
||||
jacobians->at(i).resize(function->num_residuals(), block_sizes.at(i));
|
||||
jacobians->at(i).setZero();
|
||||
jacobian_data.at(i) = jacobians->at(i).data();
|
||||
}
|
||||
|
||||
// Compute residuals & jacobians.
|
||||
CHECK_NE(0, function->num_residuals());
|
||||
residuals->resize(function->num_residuals());
|
||||
residuals->setZero();
|
||||
if (!function->Evaluate(parameters, residuals->data(),
|
||||
jacobian_data.data())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert Jacobians from global to local space.
|
||||
for (size_t i = 0; i < local_jacobians->size(); ++i) {
|
||||
if (local_parameterizations.at(i) == NULL) {
|
||||
local_jacobians->at(i) = jacobians->at(i);
|
||||
} else {
|
||||
int global_size = local_parameterizations.at(i)->GlobalSize();
|
||||
int local_size = local_parameterizations.at(i)->LocalSize();
|
||||
CHECK_EQ(jacobians->at(i).cols(), global_size);
|
||||
Matrix global_J_local(global_size, local_size);
|
||||
local_parameterizations.at(i)->ComputeJacobian(
|
||||
parameters[i], global_J_local.data());
|
||||
local_jacobians->at(i) = jacobians->at(i) * global_J_local;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
GradientChecker::GradientChecker(
|
||||
const CostFunction* function,
|
||||
const vector<const LocalParameterization*>* local_parameterizations,
|
||||
const NumericDiffOptions& options) :
|
||||
function_(function) {
|
||||
CHECK_NOTNULL(function);
|
||||
if (local_parameterizations != NULL) {
|
||||
local_parameterizations_ = *local_parameterizations;
|
||||
} else {
|
||||
local_parameterizations_.resize(function->parameter_block_sizes().size(),
|
||||
NULL);
|
||||
}
|
||||
DynamicNumericDiffCostFunction<CostFunction, CENTRAL>*
|
||||
finite_diff_cost_function =
|
||||
new DynamicNumericDiffCostFunction<CostFunction, CENTRAL>(
|
||||
function, DO_NOT_TAKE_OWNERSHIP, options);
|
||||
finite_diff_cost_function_.reset(finite_diff_cost_function);
|
||||
|
||||
const vector<int32>& parameter_block_sizes =
|
||||
function->parameter_block_sizes();
|
||||
const int num_parameter_blocks = parameter_block_sizes.size();
|
||||
for (int i = 0; i < num_parameter_blocks; ++i) {
|
||||
finite_diff_cost_function->AddParameterBlock(parameter_block_sizes[i]);
|
||||
}
|
||||
finite_diff_cost_function->SetNumResiduals(function->num_residuals());
|
||||
}
|
||||
|
||||
bool GradientChecker::Probe(double const* const * parameters,
|
||||
double relative_precision,
|
||||
ProbeResults* results_param) const {
|
||||
int num_residuals = function_->num_residuals();
|
||||
|
||||
// Make sure that we have a place to store results, no matter if the user has
|
||||
// provided an output argument.
|
||||
ProbeResults* results;
|
||||
ProbeResults results_local;
|
||||
if (results_param != NULL) {
|
||||
results = results_param;
|
||||
results->residuals.resize(0);
|
||||
results->jacobians.clear();
|
||||
results->numeric_jacobians.clear();
|
||||
results->local_jacobians.clear();
|
||||
results->local_numeric_jacobians.clear();
|
||||
results->error_log.clear();
|
||||
} else {
|
||||
results = &results_local;
|
||||
}
|
||||
results->maximum_relative_error = 0.0;
|
||||
results->return_value = true;
|
||||
|
||||
// Evaluate the derivative using the user supplied code.
|
||||
vector<Matrix>& jacobians = results->jacobians;
|
||||
vector<Matrix>& local_jacobians = results->local_jacobians;
|
||||
if (!EvaluateCostFunction(function_, parameters, local_parameterizations_,
|
||||
&results->residuals, &jacobians, &local_jacobians)) {
|
||||
results->error_log = "Function evaluation with Jacobians failed.";
|
||||
results->return_value = false;
|
||||
}
|
||||
|
||||
// Evaluate the derivative using numeric derivatives.
|
||||
vector<Matrix>& numeric_jacobians = results->numeric_jacobians;
|
||||
vector<Matrix>& local_numeric_jacobians = results->local_numeric_jacobians;
|
||||
Vector finite_diff_residuals;
|
||||
if (!EvaluateCostFunction(finite_diff_cost_function_.get(), parameters,
|
||||
local_parameterizations_, &finite_diff_residuals,
|
||||
&numeric_jacobians, &local_numeric_jacobians)) {
|
||||
results->error_log += "\nFunction evaluation with numerical "
|
||||
"differentiation failed.";
|
||||
results->return_value = false;
|
||||
}
|
||||
|
||||
if (!results->return_value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_residuals; ++i) {
|
||||
if (!IsClose(
|
||||
results->residuals[i],
|
||||
finite_diff_residuals[i],
|
||||
relative_precision,
|
||||
NULL,
|
||||
NULL)) {
|
||||
results->error_log = "Function evaluation with and without Jacobians "
|
||||
"resulted in different residuals.";
|
||||
LOG(INFO) << results->residuals.transpose();
|
||||
LOG(INFO) << finite_diff_residuals.transpose();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// See if any elements have relative error larger than the threshold.
|
||||
int num_bad_jacobian_components = 0;
|
||||
double& worst_relative_error = results->maximum_relative_error;
|
||||
worst_relative_error = 0;
|
||||
|
||||
// Accumulate the error message for all the jacobians, since it won't get
|
||||
// output if there are no bad jacobian components.
|
||||
string error_log;
|
||||
for (int k = 0; k < function_->parameter_block_sizes().size(); k++) {
|
||||
StringAppendF(&error_log,
|
||||
"========== "
|
||||
"Jacobian for " "block %d: (%ld by %ld)) "
|
||||
"==========\n",
|
||||
k,
|
||||
static_cast<long>(local_jacobians[k].rows()),
|
||||
static_cast<long>(local_jacobians[k].cols()));
|
||||
// The funny spacing creates appropriately aligned column headers.
|
||||
error_log +=
|
||||
" block row col user dx/dy num diff dx/dy "
|
||||
"abs error relative error parameter residual\n";
|
||||
|
||||
for (int i = 0; i < local_jacobians[k].rows(); i++) {
|
||||
for (int j = 0; j < local_jacobians[k].cols(); j++) {
|
||||
double term_jacobian = local_jacobians[k](i, j);
|
||||
double finite_jacobian = local_numeric_jacobians[k](i, j);
|
||||
double relative_error, absolute_error;
|
||||
bool bad_jacobian_entry =
|
||||
!IsClose(term_jacobian,
|
||||
finite_jacobian,
|
||||
relative_precision,
|
||||
&relative_error,
|
||||
&absolute_error);
|
||||
worst_relative_error = std::max(worst_relative_error, relative_error);
|
||||
|
||||
StringAppendF(&error_log,
|
||||
"%6d %4d %4d %17g %17g %17g %17g %17g %17g",
|
||||
k, i, j,
|
||||
term_jacobian, finite_jacobian,
|
||||
absolute_error, relative_error,
|
||||
parameters[k][j],
|
||||
results->residuals[i]);
|
||||
|
||||
if (bad_jacobian_entry) {
|
||||
num_bad_jacobian_components++;
|
||||
StringAppendF(
|
||||
&error_log,
|
||||
" ------ (%d,%d,%d) Relative error worse than %g",
|
||||
k, i, j, relative_precision);
|
||||
}
|
||||
error_log += "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Since there were some bad errors, dump comprehensive debug info.
|
||||
if (num_bad_jacobian_components) {
|
||||
string header = StringPrintf("\nDetected %d bad Jacobian component(s). "
|
||||
"Worst relative error was %g.\n",
|
||||
num_bad_jacobian_components,
|
||||
worst_relative_error);
|
||||
results->error_log = header + "\n" + error_log;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ceres
|
@@ -26,7 +26,8 @@
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: keir@google.com (Keir Mierle)
|
||||
// Authors: keir@google.com (Keir Mierle),
|
||||
// dgossow@google.com (David Gossow)
|
||||
|
||||
#include "ceres/gradient_checking_cost_function.h"
|
||||
|
||||
@@ -36,7 +37,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ceres/cost_function.h"
|
||||
#include "ceres/gradient_checker.h"
|
||||
#include "ceres/internal/eigen.h"
|
||||
#include "ceres/internal/scoped_ptr.h"
|
||||
#include "ceres/parameter_block.h"
|
||||
@@ -59,55 +60,25 @@ using std::vector;
|
||||
|
||||
namespace {
|
||||
|
||||
// True if x and y have an absolute relative difference less than
|
||||
// relative_precision and false otherwise. Stores the relative and absolute
|
||||
// difference in relative/absolute_error if non-NULL.
|
||||
bool IsClose(double x, double y, double relative_precision,
|
||||
double *relative_error,
|
||||
double *absolute_error) {
|
||||
double local_absolute_error;
|
||||
double local_relative_error;
|
||||
if (!absolute_error) {
|
||||
absolute_error = &local_absolute_error;
|
||||
}
|
||||
if (!relative_error) {
|
||||
relative_error = &local_relative_error;
|
||||
}
|
||||
*absolute_error = abs(x - y);
|
||||
*relative_error = *absolute_error / max(abs(x), abs(y));
|
||||
if (x == 0 || y == 0) {
|
||||
// If x or y is exactly zero, then relative difference doesn't have any
|
||||
// meaning. Take the absolute difference instead.
|
||||
*relative_error = *absolute_error;
|
||||
}
|
||||
return abs(*relative_error) < abs(relative_precision);
|
||||
}
|
||||
|
||||
class GradientCheckingCostFunction : public CostFunction {
|
||||
public:
|
||||
GradientCheckingCostFunction(const CostFunction* function,
|
||||
const NumericDiffOptions& options,
|
||||
double relative_precision,
|
||||
const string& extra_info)
|
||||
GradientCheckingCostFunction(
|
||||
const CostFunction* function,
|
||||
const std::vector<const LocalParameterization*>* local_parameterizations,
|
||||
const NumericDiffOptions& options,
|
||||
double relative_precision,
|
||||
const string& extra_info,
|
||||
GradientCheckingIterationCallback* callback)
|
||||
: function_(function),
|
||||
gradient_checker_(function, local_parameterizations, options),
|
||||
relative_precision_(relative_precision),
|
||||
extra_info_(extra_info) {
|
||||
DynamicNumericDiffCostFunction<CostFunction, CENTRAL>*
|
||||
finite_diff_cost_function =
|
||||
new DynamicNumericDiffCostFunction<CostFunction, CENTRAL>(
|
||||
function,
|
||||
DO_NOT_TAKE_OWNERSHIP,
|
||||
options);
|
||||
|
||||
extra_info_(extra_info),
|
||||
callback_(callback) {
|
||||
CHECK_NOTNULL(callback_);
|
||||
const vector<int32>& parameter_block_sizes =
|
||||
function->parameter_block_sizes();
|
||||
for (int i = 0; i < parameter_block_sizes.size(); ++i) {
|
||||
finite_diff_cost_function->AddParameterBlock(parameter_block_sizes[i]);
|
||||
}
|
||||
*mutable_parameter_block_sizes() = parameter_block_sizes;
|
||||
set_num_residuals(function->num_residuals());
|
||||
finite_diff_cost_function->SetNumResiduals(num_residuals());
|
||||
finite_diff_cost_function_.reset(finite_diff_cost_function);
|
||||
}
|
||||
|
||||
virtual ~GradientCheckingCostFunction() { }
|
||||
@@ -120,133 +91,92 @@ class GradientCheckingCostFunction : public CostFunction {
|
||||
return function_->Evaluate(parameters, residuals, NULL);
|
||||
}
|
||||
|
||||
int num_residuals = function_->num_residuals();
|
||||
GradientChecker::ProbeResults results;
|
||||
bool okay = gradient_checker_.Probe(parameters,
|
||||
relative_precision_,
|
||||
&results);
|
||||
|
||||
// Make space for the jacobians of the two methods.
|
||||
const vector<int32>& block_sizes = function_->parameter_block_sizes();
|
||||
vector<Matrix> term_jacobians(block_sizes.size());
|
||||
vector<Matrix> finite_difference_jacobians(block_sizes.size());
|
||||
vector<double*> term_jacobian_pointers(block_sizes.size());
|
||||
vector<double*> finite_difference_jacobian_pointers(block_sizes.size());
|
||||
for (int i = 0; i < block_sizes.size(); i++) {
|
||||
term_jacobians[i].resize(num_residuals, block_sizes[i]);
|
||||
term_jacobian_pointers[i] = term_jacobians[i].data();
|
||||
finite_difference_jacobians[i].resize(num_residuals, block_sizes[i]);
|
||||
finite_difference_jacobian_pointers[i] =
|
||||
finite_difference_jacobians[i].data();
|
||||
}
|
||||
|
||||
// Evaluate the derivative using the user supplied code.
|
||||
if (!function_->Evaluate(parameters,
|
||||
residuals,
|
||||
&term_jacobian_pointers[0])) {
|
||||
LOG(WARNING) << "Function evaluation failed.";
|
||||
// If the cost function returned false, there's nothing we can say about
|
||||
// the gradients.
|
||||
if (results.return_value == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Evaluate the derivative using numeric derivatives.
|
||||
finite_diff_cost_function_->Evaluate(
|
||||
parameters,
|
||||
residuals,
|
||||
&finite_difference_jacobian_pointers[0]);
|
||||
// Copy the residuals.
|
||||
const int num_residuals = function_->num_residuals();
|
||||
MatrixRef(residuals, num_residuals, 1) = results.residuals;
|
||||
|
||||
// See if any elements have relative error larger than the threshold.
|
||||
int num_bad_jacobian_components = 0;
|
||||
double worst_relative_error = 0;
|
||||
|
||||
// Accumulate the error message for all the jacobians, since it won't get
|
||||
// output if there are no bad jacobian components.
|
||||
string m;
|
||||
// Copy the original jacobian blocks into the jacobians array.
|
||||
const vector<int32>& block_sizes = function_->parameter_block_sizes();
|
||||
for (int k = 0; k < block_sizes.size(); k++) {
|
||||
// Copy the original jacobian blocks into the jacobians array.
|
||||
if (jacobians[k] != NULL) {
|
||||
MatrixRef(jacobians[k],
|
||||
term_jacobians[k].rows(),
|
||||
term_jacobians[k].cols()) = term_jacobians[k];
|
||||
}
|
||||
|
||||
StringAppendF(&m,
|
||||
"========== "
|
||||
"Jacobian for " "block %d: (%ld by %ld)) "
|
||||
"==========\n",
|
||||
k,
|
||||
static_cast<long>(term_jacobians[k].rows()),
|
||||
static_cast<long>(term_jacobians[k].cols()));
|
||||
// The funny spacing creates appropriately aligned column headers.
|
||||
m += " block row col user dx/dy num diff dx/dy "
|
||||
"abs error relative error parameter residual\n";
|
||||
|
||||
for (int i = 0; i < term_jacobians[k].rows(); i++) {
|
||||
for (int j = 0; j < term_jacobians[k].cols(); j++) {
|
||||
double term_jacobian = term_jacobians[k](i, j);
|
||||
double finite_jacobian = finite_difference_jacobians[k](i, j);
|
||||
double relative_error, absolute_error;
|
||||
bool bad_jacobian_entry =
|
||||
!IsClose(term_jacobian,
|
||||
finite_jacobian,
|
||||
relative_precision_,
|
||||
&relative_error,
|
||||
&absolute_error);
|
||||
worst_relative_error = max(worst_relative_error, relative_error);
|
||||
|
||||
StringAppendF(&m, "%6d %4d %4d %17g %17g %17g %17g %17g %17g",
|
||||
k, i, j,
|
||||
term_jacobian, finite_jacobian,
|
||||
absolute_error, relative_error,
|
||||
parameters[k][j],
|
||||
residuals[i]);
|
||||
|
||||
if (bad_jacobian_entry) {
|
||||
num_bad_jacobian_components++;
|
||||
StringAppendF(
|
||||
&m, " ------ (%d,%d,%d) Relative error worse than %g",
|
||||
k, i, j, relative_precision_);
|
||||
}
|
||||
m += "\n";
|
||||
}
|
||||
results.jacobians[k].rows(),
|
||||
results.jacobians[k].cols()) = results.jacobians[k];
|
||||
}
|
||||
}
|
||||
|
||||
// Since there were some bad errors, dump comprehensive debug info.
|
||||
if (num_bad_jacobian_components) {
|
||||
string header = StringPrintf("Detected %d bad jacobian component(s). "
|
||||
"Worst relative error was %g.\n",
|
||||
num_bad_jacobian_components,
|
||||
worst_relative_error);
|
||||
if (!extra_info_.empty()) {
|
||||
header += "Extra info for this residual: " + extra_info_ + "\n";
|
||||
}
|
||||
LOG(WARNING) << "\n" << header << m;
|
||||
if (!okay) {
|
||||
std::string error_log = "Gradient Error detected!\nExtra info for "
|
||||
"this residual: " + extra_info_ + "\n" + results.error_log;
|
||||
callback_->SetGradientErrorDetected(error_log);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const CostFunction* function_;
|
||||
internal::scoped_ptr<CostFunction> finite_diff_cost_function_;
|
||||
GradientChecker gradient_checker_;
|
||||
double relative_precision_;
|
||||
string extra_info_;
|
||||
GradientCheckingIterationCallback* callback_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
CostFunction *CreateGradientCheckingCostFunction(
|
||||
const CostFunction *cost_function,
|
||||
GradientCheckingIterationCallback::GradientCheckingIterationCallback()
|
||||
: gradient_error_detected_(false) {
|
||||
}
|
||||
|
||||
CallbackReturnType GradientCheckingIterationCallback::operator()(
|
||||
const IterationSummary& summary) {
|
||||
if (gradient_error_detected_) {
|
||||
LOG(ERROR)<< "Gradient error detected. Terminating solver.";
|
||||
return SOLVER_ABORT;
|
||||
}
|
||||
return SOLVER_CONTINUE;
|
||||
}
|
||||
void GradientCheckingIterationCallback::SetGradientErrorDetected(
|
||||
std::string& error_log) {
|
||||
mutex_.Lock();
|
||||
gradient_error_detected_ = true;
|
||||
error_log_ += "\n" + error_log;
|
||||
mutex_.Unlock();
|
||||
}
|
||||
|
||||
CostFunction* CreateGradientCheckingCostFunction(
|
||||
const CostFunction* cost_function,
|
||||
const std::vector<const LocalParameterization*>* local_parameterizations,
|
||||
double relative_step_size,
|
||||
double relative_precision,
|
||||
const string& extra_info) {
|
||||
const std::string& extra_info,
|
||||
GradientCheckingIterationCallback* callback) {
|
||||
NumericDiffOptions numeric_diff_options;
|
||||
numeric_diff_options.relative_step_size = relative_step_size;
|
||||
|
||||
return new GradientCheckingCostFunction(cost_function,
|
||||
local_parameterizations,
|
||||
numeric_diff_options,
|
||||
relative_precision,
|
||||
extra_info);
|
||||
relative_precision, extra_info,
|
||||
callback);
|
||||
}
|
||||
|
||||
ProblemImpl* CreateGradientCheckingProblemImpl(ProblemImpl* problem_impl,
|
||||
double relative_step_size,
|
||||
double relative_precision) {
|
||||
ProblemImpl* CreateGradientCheckingProblemImpl(
|
||||
ProblemImpl* problem_impl,
|
||||
double relative_step_size,
|
||||
double relative_precision,
|
||||
GradientCheckingIterationCallback* callback) {
|
||||
CHECK_NOTNULL(callback);
|
||||
// We create new CostFunctions by wrapping the original CostFunction
|
||||
// in a gradient checking CostFunction. So its okay for the
|
||||
// ProblemImpl to take ownership of it and destroy it. The
|
||||
@@ -260,6 +190,9 @@ ProblemImpl* CreateGradientCheckingProblemImpl(ProblemImpl* problem_impl,
|
||||
gradient_checking_problem_options.local_parameterization_ownership =
|
||||
DO_NOT_TAKE_OWNERSHIP;
|
||||
|
||||
NumericDiffOptions numeric_diff_options;
|
||||
numeric_diff_options.relative_step_size = relative_step_size;
|
||||
|
||||
ProblemImpl* gradient_checking_problem_impl = new ProblemImpl(
|
||||
gradient_checking_problem_options);
|
||||
|
||||
@@ -294,19 +227,26 @@ ProblemImpl* CreateGradientCheckingProblemImpl(ProblemImpl* problem_impl,
|
||||
string extra_info = StringPrintf(
|
||||
"Residual block id %d; depends on parameters [", i);
|
||||
vector<double*> parameter_blocks;
|
||||
vector<const LocalParameterization*> local_parameterizations;
|
||||
parameter_blocks.reserve(residual_block->NumParameterBlocks());
|
||||
local_parameterizations.reserve(residual_block->NumParameterBlocks());
|
||||
for (int j = 0; j < residual_block->NumParameterBlocks(); ++j) {
|
||||
ParameterBlock* parameter_block = residual_block->parameter_blocks()[j];
|
||||
parameter_blocks.push_back(parameter_block->mutable_user_state());
|
||||
StringAppendF(&extra_info, "%p", parameter_block->mutable_user_state());
|
||||
extra_info += (j < residual_block->NumParameterBlocks() - 1) ? ", " : "]";
|
||||
local_parameterizations.push_back(problem_impl->GetParameterization(
|
||||
parameter_block->mutable_user_state()));
|
||||
}
|
||||
|
||||
// Wrap the original CostFunction in a GradientCheckingCostFunction.
|
||||
CostFunction* gradient_checking_cost_function =
|
||||
CreateGradientCheckingCostFunction(residual_block->cost_function(),
|
||||
relative_step_size,
|
||||
relative_precision,
|
||||
extra_info);
|
||||
new GradientCheckingCostFunction(residual_block->cost_function(),
|
||||
&local_parameterizations,
|
||||
numeric_diff_options,
|
||||
relative_precision,
|
||||
extra_info,
|
||||
callback);
|
||||
|
||||
// The const_cast is necessary because
|
||||
// ProblemImpl::AddResidualBlock can potentially take ownership of
|
||||
|
@@ -26,7 +26,8 @@
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: keir@google.com (Keir Mierle)
|
||||
// Authors: keir@google.com (Keir Mierle),
|
||||
// dgossow@google.com (David Gossow)
|
||||
|
||||
#ifndef CERES_INTERNAL_GRADIENT_CHECKING_COST_FUNCTION_H_
|
||||
#define CERES_INTERNAL_GRADIENT_CHECKING_COST_FUNCTION_H_
|
||||
@@ -34,50 +35,76 @@
|
||||
#include <string>
|
||||
|
||||
#include "ceres/cost_function.h"
|
||||
#include "ceres/iteration_callback.h"
|
||||
#include "ceres/local_parameterization.h"
|
||||
#include "ceres/mutex.h"
|
||||
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
class ProblemImpl;
|
||||
|
||||
// Creates a CostFunction that checks the jacobians that cost_function computes
|
||||
// with finite differences. Bad results are logged; required precision is
|
||||
// controlled by relative_precision and the numeric differentiation step size is
|
||||
// controlled with relative_step_size. See solver.h for a better explanation of
|
||||
// relative_step_size. Caller owns result.
|
||||
//
|
||||
// The condition enforced is that
|
||||
//
|
||||
// (J_actual(i, j) - J_numeric(i, j))
|
||||
// ------------------------------------ < relative_precision
|
||||
// max(J_actual(i, j), J_numeric(i, j))
|
||||
//
|
||||
// where J_actual(i, j) is the jacobian as computed by the supplied cost
|
||||
// function (by the user) and J_numeric is the jacobian as computed by finite
|
||||
// differences.
|
||||
//
|
||||
// Note: This is quite inefficient and is intended only for debugging.
|
||||
// Callback that collects information about gradient checking errors, and
|
||||
// will abort the solve as soon as an error occurs.
|
||||
class GradientCheckingIterationCallback : public IterationCallback {
|
||||
public:
|
||||
GradientCheckingIterationCallback();
|
||||
|
||||
// Will return SOLVER_CONTINUE until a gradient error has been detected,
|
||||
// then return SOLVER_ABORT.
|
||||
virtual CallbackReturnType operator()(const IterationSummary& summary);
|
||||
|
||||
// Notify this that a gradient error has occurred (thread safe).
|
||||
void SetGradientErrorDetected(std::string& error_log);
|
||||
|
||||
// Retrieve error status (not thread safe).
|
||||
bool gradient_error_detected() const { return gradient_error_detected_; }
|
||||
const std::string& error_log() const { return error_log_; }
|
||||
private:
|
||||
bool gradient_error_detected_;
|
||||
std::string error_log_;
|
||||
// Mutex protecting member variables.
|
||||
ceres::internal::Mutex mutex_;
|
||||
};
|
||||
|
||||
// Creates a CostFunction that checks the Jacobians that cost_function computes
|
||||
// with finite differences. This API is only intended for unit tests that intend
|
||||
// to check the functionality of the GradientCheckingCostFunction
|
||||
// implementation directly.
|
||||
CostFunction* CreateGradientCheckingCostFunction(
|
||||
const CostFunction* cost_function,
|
||||
const std::vector<const LocalParameterization*>* local_parameterizations,
|
||||
double relative_step_size,
|
||||
double relative_precision,
|
||||
const std::string& extra_info);
|
||||
const std::string& extra_info,
|
||||
GradientCheckingIterationCallback* callback);
|
||||
|
||||
// Create a new ProblemImpl object from the input problem_impl, where
|
||||
// each CostFunctions in problem_impl are wrapped inside a
|
||||
// GradientCheckingCostFunctions. This gives us a ProblemImpl object
|
||||
// which checks its derivatives against estimates from numeric
|
||||
// differentiation everytime a ResidualBlock is evaluated.
|
||||
// Create a new ProblemImpl object from the input problem_impl, where all
|
||||
// cost functions are wrapped so that each time their Evaluate method is called,
|
||||
// an additional check is performed that compares the Jacobians computed by
|
||||
// the original cost function with alternative Jacobians computed using
|
||||
// numerical differentiation. If local parameterizations are given for any
|
||||
// parameters, the Jacobians will be compared in the local space instead of the
|
||||
// ambient space. For details on the gradient checking procedure, see the
|
||||
// documentation of the GradientChecker class. If an error is detected in any
|
||||
// iteration, the respective cost function will notify the
|
||||
// GradientCheckingIterationCallback.
|
||||
//
|
||||
// The caller owns the returned ProblemImpl object.
|
||||
//
|
||||
// Note: This is quite inefficient and is intended only for debugging.
|
||||
//
|
||||
// relative_step_size and relative_precision are parameters to control
|
||||
// the numeric differentiation and the relative tolerance between the
|
||||
// jacobian computed by the CostFunctions in problem_impl and
|
||||
// jacobians obtained by numerically differentiating them. For more
|
||||
// details see the documentation for
|
||||
// CreateGradientCheckingCostFunction above.
|
||||
ProblemImpl* CreateGradientCheckingProblemImpl(ProblemImpl* problem_impl,
|
||||
double relative_step_size,
|
||||
double relative_precision);
|
||||
// jacobians obtained by numerically differentiating them. See the
|
||||
// documentation of 'numeric_derivative_relative_step_size' in solver.h for a
|
||||
// better explanation.
|
||||
ProblemImpl* CreateGradientCheckingProblemImpl(
|
||||
ProblemImpl* problem_impl,
|
||||
double relative_step_size,
|
||||
double relative_precision,
|
||||
GradientCheckingIterationCallback* callback);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ceres
|
||||
|
@@ -84,6 +84,12 @@ Solver::Options GradientProblemSolverOptionsToSolverOptions(
|
||||
|
||||
} // namespace
|
||||
|
||||
bool GradientProblemSolver::Options::IsValid(std::string* error) const {
|
||||
const Solver::Options solver_options =
|
||||
GradientProblemSolverOptionsToSolverOptions(*this);
|
||||
return solver_options.IsValid(error);
|
||||
}
|
||||
|
||||
GradientProblemSolver::~GradientProblemSolver() {
|
||||
}
|
||||
|
||||
@@ -99,8 +105,6 @@ void GradientProblemSolver::Solve(const GradientProblemSolver::Options& options,
|
||||
using internal::SetSummaryFinalCost;
|
||||
|
||||
double start_time = WallTimeInSeconds();
|
||||
Solver::Options solver_options =
|
||||
GradientProblemSolverOptionsToSolverOptions(options);
|
||||
|
||||
*CHECK_NOTNULL(summary) = Summary();
|
||||
summary->num_parameters = problem.NumParameters();
|
||||
@@ -112,14 +116,16 @@ void GradientProblemSolver::Solve(const GradientProblemSolver::Options& options,
|
||||
summary->nonlinear_conjugate_gradient_type = options.nonlinear_conjugate_gradient_type; // NOLINT
|
||||
|
||||
// Check validity
|
||||
if (!solver_options.IsValid(&summary->message)) {
|
||||
if (!options.IsValid(&summary->message)) {
|
||||
LOG(ERROR) << "Terminating: " << summary->message;
|
||||
return;
|
||||
}
|
||||
|
||||
// Assuming that the parameter blocks in the program have been
|
||||
Minimizer::Options minimizer_options;
|
||||
minimizer_options = Minimizer::Options(solver_options);
|
||||
// TODO(sameeragarwal): This is a bit convoluted, we should be able
|
||||
// to convert to minimizer options directly, but this will do for
|
||||
// now.
|
||||
Minimizer::Options minimizer_options =
|
||||
Minimizer::Options(GradientProblemSolverOptionsToSolverOptions(options));
|
||||
minimizer_options.evaluator.reset(new GradientProblemEvaluator(problem));
|
||||
|
||||
scoped_ptr<IterationCallback> logging_callback;
|
||||
|
59
extern/ceres/internal/ceres/is_close.cc
vendored
Normal file
59
extern/ceres/internal/ceres/is_close.cc
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// http://ceres-solver.org/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: keir@google.com (Keir Mierle), dgossow@google.com (David Gossow)
|
||||
|
||||
#include "ceres/is_close.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
bool IsClose(double x, double y, double relative_precision,
|
||||
double *relative_error,
|
||||
double *absolute_error) {
|
||||
double local_absolute_error;
|
||||
double local_relative_error;
|
||||
if (!absolute_error) {
|
||||
absolute_error = &local_absolute_error;
|
||||
}
|
||||
if (!relative_error) {
|
||||
relative_error = &local_relative_error;
|
||||
}
|
||||
*absolute_error = std::fabs(x - y);
|
||||
*relative_error = *absolute_error / std::max(std::fabs(x), std::fabs(y));
|
||||
if (x == 0 || y == 0) {
|
||||
// If x or y is exactly zero, then relative difference doesn't have any
|
||||
// meaning. Take the absolute difference instead.
|
||||
*relative_error = *absolute_error;
|
||||
}
|
||||
return *relative_error < std::fabs(relative_precision);
|
||||
}
|
||||
} // namespace internal
|
||||
} // namespace ceres
|
51
extern/ceres/internal/ceres/is_close.h
vendored
Normal file
51
extern/ceres/internal/ceres/is_close.h
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// http://ceres-solver.org/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: keir@google.com (Keir Mierle), dgossow@google.com (David Gossow)
|
||||
//
|
||||
// Utility routine for comparing two values.
|
||||
|
||||
#ifndef CERES_INTERNAL_IS_CLOSE_H_
|
||||
#define CERES_INTERNAL_IS_CLOSE_H_
|
||||
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
// Returns true if x and y have a relative (unsigned) difference less than
|
||||
// relative_precision and false otherwise. Stores the relative and absolute
|
||||
// difference in relative/absolute_error if non-NULL. If one of the two values
|
||||
// is exactly zero, the absolute difference will be compared, and relative_error
|
||||
// will be set to the absolute difference.
|
||||
bool IsClose(double x,
|
||||
double y,
|
||||
double relative_precision,
|
||||
double *relative_error,
|
||||
double *absolute_error);
|
||||
} // namespace internal
|
||||
} // namespace ceres
|
||||
|
||||
#endif // CERES_INTERNAL_IS_CLOSE_H_
|
@@ -191,6 +191,7 @@ void LineSearchMinimizer::Minimize(const Minimizer::Options& options,
|
||||
options.line_search_sufficient_curvature_decrease;
|
||||
line_search_options.max_step_expansion =
|
||||
options.max_line_search_step_expansion;
|
||||
line_search_options.is_silent = options.is_silent;
|
||||
line_search_options.function = &line_search_function;
|
||||
|
||||
scoped_ptr<LineSearch>
|
||||
@@ -341,10 +342,12 @@ void LineSearchMinimizer::Minimize(const Minimizer::Options& options,
|
||||
"as the step was valid when it was selected by the line search.";
|
||||
LOG_IF(WARNING, is_not_silent) << "Terminating: " << summary->message;
|
||||
break;
|
||||
} else if (!Evaluate(evaluator,
|
||||
x_plus_delta,
|
||||
¤t_state,
|
||||
&summary->message)) {
|
||||
}
|
||||
|
||||
if (!Evaluate(evaluator,
|
||||
x_plus_delta,
|
||||
¤t_state,
|
||||
&summary->message)) {
|
||||
summary->termination_type = FAILURE;
|
||||
summary->message =
|
||||
"Step failed to evaluate. This should not happen as the step was "
|
||||
@@ -352,15 +355,17 @@ void LineSearchMinimizer::Minimize(const Minimizer::Options& options,
|
||||
summary->message;
|
||||
LOG_IF(WARNING, is_not_silent) << "Terminating: " << summary->message;
|
||||
break;
|
||||
} else {
|
||||
x = x_plus_delta;
|
||||
}
|
||||
|
||||
// Compute the norm of the step in the ambient space.
|
||||
iteration_summary.step_norm = (x_plus_delta - x).norm();
|
||||
x = x_plus_delta;
|
||||
|
||||
iteration_summary.gradient_max_norm = current_state.gradient_max_norm;
|
||||
iteration_summary.gradient_norm = sqrt(current_state.gradient_squared_norm);
|
||||
iteration_summary.cost_change = previous_state.cost - current_state.cost;
|
||||
iteration_summary.cost = current_state.cost + summary->fixed_cost;
|
||||
iteration_summary.step_norm = delta.norm();
|
||||
|
||||
iteration_summary.step_is_valid = true;
|
||||
iteration_summary.step_is_successful = true;
|
||||
iteration_summary.step_size = current_state.step_size;
|
||||
@@ -376,6 +381,13 @@ void LineSearchMinimizer::Minimize(const Minimizer::Options& options,
|
||||
WallTimeInSeconds() - start_time
|
||||
+ summary->preprocessor_time_in_seconds;
|
||||
|
||||
// Iterations inside the line search algorithm are considered
|
||||
// 'steps' in the broader context, to distinguish these inner
|
||||
// iterations from from the outer iterations of the line search
|
||||
// minimizer. The number of line search steps is the total number
|
||||
// of inner line search iterations (or steps) across the entire
|
||||
// minimization.
|
||||
summary->num_line_search_steps += line_search_summary.num_iterations;
|
||||
summary->line_search_cost_evaluation_time_in_seconds +=
|
||||
line_search_summary.cost_evaluation_time_in_seconds;
|
||||
summary->line_search_gradient_evaluation_time_in_seconds +=
|
||||
|
@@ -30,6 +30,8 @@
|
||||
|
||||
#include "ceres/local_parameterization.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "Eigen/Geometry"
|
||||
#include "ceres/householder_vector.h"
|
||||
#include "ceres/internal/eigen.h"
|
||||
#include "ceres/internal/fixed_array.h"
|
||||
@@ -87,28 +89,17 @@ bool IdentityParameterization::MultiplyByJacobian(const double* x,
|
||||
}
|
||||
|
||||
SubsetParameterization::SubsetParameterization(
|
||||
int size,
|
||||
const vector<int>& constant_parameters)
|
||||
: local_size_(size - constant_parameters.size()),
|
||||
constancy_mask_(size, 0) {
|
||||
CHECK_GT(constant_parameters.size(), 0)
|
||||
<< "The set of constant parameters should contain at least "
|
||||
<< "one element. If you do not wish to hold any parameters "
|
||||
<< "constant, then do not use a SubsetParameterization";
|
||||
|
||||
int size, const vector<int>& constant_parameters)
|
||||
: local_size_(size - constant_parameters.size()), constancy_mask_(size, 0) {
|
||||
vector<int> constant = constant_parameters;
|
||||
sort(constant.begin(), constant.end());
|
||||
CHECK(unique(constant.begin(), constant.end()) == constant.end())
|
||||
std::sort(constant.begin(), constant.end());
|
||||
CHECK_GE(constant.front(), 0)
|
||||
<< "Indices indicating constant parameter must be greater than zero.";
|
||||
CHECK_LT(constant.back(), size)
|
||||
<< "Indices indicating constant parameter must be less than the size "
|
||||
<< "of the parameter block.";
|
||||
CHECK(std::adjacent_find(constant.begin(), constant.end()) == constant.end())
|
||||
<< "The set of constant parameters cannot contain duplicates";
|
||||
CHECK_LT(constant_parameters.size(), size)
|
||||
<< "Number of parameters held constant should be less "
|
||||
<< "than the size of the parameter block. If you wish "
|
||||
<< "to hold the entire parameter block constant, then a "
|
||||
<< "efficient way is to directly mark it as constant "
|
||||
<< "instead of using a LocalParameterization to do so.";
|
||||
CHECK_GE(*min_element(constant.begin(), constant.end()), 0);
|
||||
CHECK_LT(*max_element(constant.begin(), constant.end()), size);
|
||||
|
||||
for (int i = 0; i < constant_parameters.size(); ++i) {
|
||||
constancy_mask_[constant_parameters[i]] = 1;
|
||||
}
|
||||
@@ -129,6 +120,10 @@ bool SubsetParameterization::Plus(const double* x,
|
||||
|
||||
bool SubsetParameterization::ComputeJacobian(const double* x,
|
||||
double* jacobian) const {
|
||||
if (local_size_ == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MatrixRef m(jacobian, constancy_mask_.size(), local_size_);
|
||||
m.setZero();
|
||||
for (int i = 0, j = 0; i < constancy_mask_.size(); ++i) {
|
||||
@@ -143,6 +138,10 @@ bool SubsetParameterization::MultiplyByJacobian(const double* x,
|
||||
const int num_rows,
|
||||
const double* global_matrix,
|
||||
double* local_matrix) const {
|
||||
if (local_size_ == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int row = 0; row < num_rows; ++row) {
|
||||
for (int col = 0, j = 0; col < constancy_mask_.size(); ++col) {
|
||||
if (!constancy_mask_[col]) {
|
||||
@@ -184,6 +183,39 @@ bool QuaternionParameterization::ComputeJacobian(const double* x,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EigenQuaternionParameterization::Plus(const double* x_ptr,
|
||||
const double* delta,
|
||||
double* x_plus_delta_ptr) const {
|
||||
Eigen::Map<Eigen::Quaterniond> x_plus_delta(x_plus_delta_ptr);
|
||||
Eigen::Map<const Eigen::Quaterniond> x(x_ptr);
|
||||
|
||||
const double norm_delta =
|
||||
sqrt(delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2]);
|
||||
if (norm_delta > 0.0) {
|
||||
const double sin_delta_by_delta = sin(norm_delta) / norm_delta;
|
||||
|
||||
// Note, in the constructor w is first.
|
||||
Eigen::Quaterniond delta_q(cos(norm_delta),
|
||||
sin_delta_by_delta * delta[0],
|
||||
sin_delta_by_delta * delta[1],
|
||||
sin_delta_by_delta * delta[2]);
|
||||
x_plus_delta = delta_q * x;
|
||||
} else {
|
||||
x_plus_delta = x;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EigenQuaternionParameterization::ComputeJacobian(const double* x,
|
||||
double* jacobian) const {
|
||||
jacobian[0] = x[3]; jacobian[1] = x[2]; jacobian[2] = -x[1]; // NOLINT
|
||||
jacobian[3] = -x[2]; jacobian[4] = x[3]; jacobian[5] = x[0]; // NOLINT
|
||||
jacobian[6] = x[1]; jacobian[7] = -x[0]; jacobian[8] = x[3]; // NOLINT
|
||||
jacobian[9] = -x[0]; jacobian[10] = -x[1]; jacobian[11] = -x[2]; // NOLINT
|
||||
return true;
|
||||
}
|
||||
|
||||
HomogeneousVectorParameterization::HomogeneousVectorParameterization(int size)
|
||||
: size_(size) {
|
||||
CHECK_GT(size_, 1) << "The size of the homogeneous vector needs to be "
|
||||
@@ -332,9 +364,9 @@ bool ProductParameterization::ComputeJacobian(const double* x,
|
||||
if (!param->ComputeJacobian(x + x_cursor, buffer.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
jacobian.block(x_cursor, delta_cursor, global_size, local_size)
|
||||
= MatrixRef(buffer.get(), global_size, local_size);
|
||||
|
||||
delta_cursor += local_size;
|
||||
x_cursor += global_size;
|
||||
}
|
||||
|
2
extern/ceres/internal/ceres/map_util.h
vendored
2
extern/ceres/internal/ceres/map_util.h
vendored
@@ -67,7 +67,7 @@ FindOrDie(const Collection& collection,
|
||||
// If the key is present in the map then the value associated with that
|
||||
// key is returned, otherwise the value passed as a default is returned.
|
||||
template <class Collection>
|
||||
const typename Collection::value_type::second_type&
|
||||
const typename Collection::value_type::second_type
|
||||
FindWithDefault(const Collection& collection,
|
||||
const typename Collection::value_type::first_type& key,
|
||||
const typename Collection::value_type::second_type& value) {
|
||||
|
37
extern/ceres/internal/ceres/parameter_block.h
vendored
37
extern/ceres/internal/ceres/parameter_block.h
vendored
@@ -161,25 +161,34 @@ class ParameterBlock {
|
||||
// does not take ownership of the parameterization.
|
||||
void SetParameterization(LocalParameterization* new_parameterization) {
|
||||
CHECK(new_parameterization != NULL) << "NULL parameterization invalid.";
|
||||
// Nothing to do if the new parameterization is the same as the
|
||||
// old parameterization.
|
||||
if (new_parameterization == local_parameterization_) {
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK(local_parameterization_ == NULL)
|
||||
<< "Can't re-set the local parameterization; it leads to "
|
||||
<< "ambiguous ownership. Current local parameterization is: "
|
||||
<< local_parameterization_;
|
||||
|
||||
CHECK(new_parameterization->GlobalSize() == size_)
|
||||
<< "Invalid parameterization for parameter block. The parameter block "
|
||||
<< "has size " << size_ << " while the parameterization has a global "
|
||||
<< "size of " << new_parameterization->GlobalSize() << ". Did you "
|
||||
<< "accidentally use the wrong parameter block or parameterization?";
|
||||
if (new_parameterization != local_parameterization_) {
|
||||
CHECK(local_parameterization_ == NULL)
|
||||
<< "Can't re-set the local parameterization; it leads to "
|
||||
<< "ambiguous ownership.";
|
||||
local_parameterization_ = new_parameterization;
|
||||
local_parameterization_jacobian_.reset(
|
||||
new double[local_parameterization_->GlobalSize() *
|
||||
local_parameterization_->LocalSize()]);
|
||||
CHECK(UpdateLocalParameterizationJacobian())
|
||||
<< "Local parameterization Jacobian computation failed for x: "
|
||||
<< ConstVectorRef(state_, Size()).transpose();
|
||||
} else {
|
||||
// Ignore the case that the parameterizations match.
|
||||
}
|
||||
|
||||
CHECK_GT(new_parameterization->LocalSize(), 0)
|
||||
<< "Invalid parameterization. Parameterizations must have a positive "
|
||||
<< "dimensional tangent space.";
|
||||
|
||||
local_parameterization_ = new_parameterization;
|
||||
local_parameterization_jacobian_.reset(
|
||||
new double[local_parameterization_->GlobalSize() *
|
||||
local_parameterization_->LocalSize()]);
|
||||
CHECK(UpdateLocalParameterizationJacobian())
|
||||
<< "Local parameterization Jacobian computation failed for x: "
|
||||
<< ConstVectorRef(state_, Size()).transpose();
|
||||
}
|
||||
|
||||
void SetUpperBound(int index, double upper_bound) {
|
||||
|
4
extern/ceres/internal/ceres/problem.cc
vendored
4
extern/ceres/internal/ceres/problem.cc
vendored
@@ -174,6 +174,10 @@ void Problem::SetParameterBlockVariable(double* values) {
|
||||
problem_impl_->SetParameterBlockVariable(values);
|
||||
}
|
||||
|
||||
bool Problem::IsParameterBlockConstant(double* values) const {
|
||||
return problem_impl_->IsParameterBlockConstant(values);
|
||||
}
|
||||
|
||||
void Problem::SetParameterization(
|
||||
double* values,
|
||||
LocalParameterization* local_parameterization) {
|
||||
|
19
extern/ceres/internal/ceres/problem_impl.cc
vendored
19
extern/ceres/internal/ceres/problem_impl.cc
vendored
@@ -249,10 +249,11 @@ ResidualBlock* ProblemImpl::AddResidualBlock(
|
||||
// Check for duplicate parameter blocks.
|
||||
vector<double*> sorted_parameter_blocks(parameter_blocks);
|
||||
sort(sorted_parameter_blocks.begin(), sorted_parameter_blocks.end());
|
||||
vector<double*>::const_iterator duplicate_items =
|
||||
unique(sorted_parameter_blocks.begin(),
|
||||
sorted_parameter_blocks.end());
|
||||
if (duplicate_items != sorted_parameter_blocks.end()) {
|
||||
const bool has_duplicate_items =
|
||||
(std::adjacent_find(sorted_parameter_blocks.begin(),
|
||||
sorted_parameter_blocks.end())
|
||||
!= sorted_parameter_blocks.end());
|
||||
if (has_duplicate_items) {
|
||||
string blocks;
|
||||
for (int i = 0; i < parameter_blocks.size(); ++i) {
|
||||
blocks += StringPrintf(" %p ", parameter_blocks[i]);
|
||||
@@ -572,6 +573,16 @@ void ProblemImpl::SetParameterBlockConstant(double* values) {
|
||||
parameter_block->SetConstant();
|
||||
}
|
||||
|
||||
bool ProblemImpl::IsParameterBlockConstant(double* values) const {
|
||||
const ParameterBlock* parameter_block =
|
||||
FindWithDefault(parameter_block_map_, values, NULL);
|
||||
CHECK(parameter_block != NULL)
|
||||
<< "Parameter block not found: " << values << ". You must add the "
|
||||
<< "parameter block to the problem before it can be queried.";
|
||||
|
||||
return parameter_block->IsConstant();
|
||||
}
|
||||
|
||||
void ProblemImpl::SetParameterBlockVariable(double* values) {
|
||||
ParameterBlock* parameter_block =
|
||||
FindWithDefault(parameter_block_map_, values, NULL);
|
||||
|
2
extern/ceres/internal/ceres/problem_impl.h
vendored
2
extern/ceres/internal/ceres/problem_impl.h
vendored
@@ -128,6 +128,8 @@ class ProblemImpl {
|
||||
|
||||
void SetParameterBlockConstant(double* values);
|
||||
void SetParameterBlockVariable(double* values);
|
||||
bool IsParameterBlockConstant(double* values) const;
|
||||
|
||||
void SetParameterization(double* values,
|
||||
LocalParameterization* local_parameterization);
|
||||
const LocalParameterization* GetParameterization(double* values) const;
|
||||
|
@@ -142,6 +142,11 @@ void OrderingForSparseNormalCholeskyUsingSuiteSparse(
|
||||
ordering);
|
||||
}
|
||||
|
||||
VLOG(2) << "Block ordering stats: "
|
||||
<< " flops: " << ss.mutable_cc()->fl
|
||||
<< " lnz : " << ss.mutable_cc()->lnz
|
||||
<< " anz : " << ss.mutable_cc()->anz;
|
||||
|
||||
ss.Free(block_jacobian_transpose);
|
||||
#endif // CERES_NO_SUITESPARSE
|
||||
}
|
||||
|
2
extern/ceres/internal/ceres/residual_block.h
vendored
2
extern/ceres/internal/ceres/residual_block.h
vendored
@@ -127,7 +127,7 @@ class ResidualBlock {
|
||||
int index() const { return index_; }
|
||||
void set_index(int index) { index_ = index; }
|
||||
|
||||
std::string ToString() {
|
||||
std::string ToString() const {
|
||||
return StringPrintf("{residual block; index=%d}", index_);
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "ceres/block_random_access_dense_matrix.h"
|
||||
@@ -563,6 +564,12 @@ SparseSchurComplementSolver::SolveReducedLinearSystemUsingEigen(
|
||||
// worse than the one computed using the block version of the
|
||||
// algorithm.
|
||||
simplicial_ldlt_->analyzePattern(eigen_lhs);
|
||||
if (VLOG_IS_ON(2)) {
|
||||
std::stringstream ss;
|
||||
simplicial_ldlt_->dumpMemory(ss);
|
||||
VLOG(2) << "Symbolic Analysis\n"
|
||||
<< ss.str();
|
||||
}
|
||||
event_logger.AddEvent("Analysis");
|
||||
if (simplicial_ldlt_->info() != Eigen::Success) {
|
||||
summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
|
||||
|
61
extern/ceres/internal/ceres/solver.cc
vendored
61
extern/ceres/internal/ceres/solver.cc
vendored
@@ -94,7 +94,7 @@ bool CommonOptionsAreValid(const Solver::Options& options, string* error) {
|
||||
OPTION_GT(num_linear_solver_threads, 0);
|
||||
if (options.check_gradients) {
|
||||
OPTION_GT(gradient_check_relative_precision, 0.0);
|
||||
OPTION_GT(numeric_derivative_relative_step_size, 0.0);
|
||||
OPTION_GT(gradient_check_numeric_derivative_relative_step_size, 0.0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -351,6 +351,7 @@ void PreSolveSummarize(const Solver::Options& options,
|
||||
summary->dense_linear_algebra_library_type = options.dense_linear_algebra_library_type; // NOLINT
|
||||
summary->dogleg_type = options.dogleg_type;
|
||||
summary->inner_iteration_time_in_seconds = 0.0;
|
||||
summary->num_line_search_steps = 0;
|
||||
summary->line_search_cost_evaluation_time_in_seconds = 0.0;
|
||||
summary->line_search_gradient_evaluation_time_in_seconds = 0.0;
|
||||
summary->line_search_polynomial_minimization_time_in_seconds = 0.0;
|
||||
@@ -495,21 +496,28 @@ void Solver::Solve(const Solver::Options& options,
|
||||
// values provided by the user.
|
||||
program->SetParameterBlockStatePtrsToUserStatePtrs();
|
||||
|
||||
// If gradient_checking is enabled, wrap all cost functions in a
|
||||
// gradient checker and install a callback that terminates if any gradient
|
||||
// error is detected.
|
||||
scoped_ptr<internal::ProblemImpl> gradient_checking_problem;
|
||||
internal::GradientCheckingIterationCallback gradient_checking_callback;
|
||||
Solver::Options modified_options = options;
|
||||
if (options.check_gradients) {
|
||||
modified_options.callbacks.push_back(&gradient_checking_callback);
|
||||
gradient_checking_problem.reset(
|
||||
CreateGradientCheckingProblemImpl(
|
||||
problem_impl,
|
||||
options.numeric_derivative_relative_step_size,
|
||||
options.gradient_check_relative_precision));
|
||||
options.gradient_check_numeric_derivative_relative_step_size,
|
||||
options.gradient_check_relative_precision,
|
||||
&gradient_checking_callback));
|
||||
problem_impl = gradient_checking_problem.get();
|
||||
program = problem_impl->mutable_program();
|
||||
}
|
||||
|
||||
scoped_ptr<Preprocessor> preprocessor(
|
||||
Preprocessor::Create(options.minimizer_type));
|
||||
Preprocessor::Create(modified_options.minimizer_type));
|
||||
PreprocessedProblem pp;
|
||||
const bool status = preprocessor->Preprocess(options, problem_impl, &pp);
|
||||
const bool status = preprocessor->Preprocess(modified_options, problem_impl, &pp);
|
||||
summary->fixed_cost = pp.fixed_cost;
|
||||
summary->preprocessor_time_in_seconds = WallTimeInSeconds() - start_time;
|
||||
|
||||
@@ -534,6 +542,13 @@ void Solver::Solve(const Solver::Options& options,
|
||||
summary->postprocessor_time_in_seconds =
|
||||
WallTimeInSeconds() - postprocessor_start_time;
|
||||
|
||||
// If the gradient checker reported an error, we want to report FAILURE
|
||||
// instead of USER_FAILURE and provide the error log.
|
||||
if (gradient_checking_callback.gradient_error_detected()) {
|
||||
summary->termination_type = FAILURE;
|
||||
summary->message = gradient_checking_callback.error_log();
|
||||
}
|
||||
|
||||
summary->total_time_in_seconds = WallTimeInSeconds() - start_time;
|
||||
}
|
||||
|
||||
@@ -556,6 +571,7 @@ Solver::Summary::Summary()
|
||||
num_successful_steps(-1),
|
||||
num_unsuccessful_steps(-1),
|
||||
num_inner_iteration_steps(-1),
|
||||
num_line_search_steps(-1),
|
||||
preprocessor_time_in_seconds(-1.0),
|
||||
minimizer_time_in_seconds(-1.0),
|
||||
postprocessor_time_in_seconds(-1.0),
|
||||
@@ -696,16 +712,14 @@ string Solver::Summary::FullReport() const {
|
||||
num_linear_solver_threads_given,
|
||||
num_linear_solver_threads_used);
|
||||
|
||||
if (IsSchurType(linear_solver_type_used)) {
|
||||
string given;
|
||||
StringifyOrdering(linear_solver_ordering_given, &given);
|
||||
string used;
|
||||
StringifyOrdering(linear_solver_ordering_used, &used);
|
||||
StringAppendF(&report,
|
||||
"Linear solver ordering %22s %24s\n",
|
||||
given.c_str(),
|
||||
used.c_str());
|
||||
}
|
||||
string given;
|
||||
StringifyOrdering(linear_solver_ordering_given, &given);
|
||||
string used;
|
||||
StringifyOrdering(linear_solver_ordering_used, &used);
|
||||
StringAppendF(&report,
|
||||
"Linear solver ordering %22s %24s\n",
|
||||
given.c_str(),
|
||||
used.c_str());
|
||||
|
||||
if (inner_iterations_given) {
|
||||
StringAppendF(&report,
|
||||
@@ -784,9 +798,14 @@ string Solver::Summary::FullReport() const {
|
||||
num_inner_iteration_steps);
|
||||
}
|
||||
|
||||
const bool print_line_search_timing_information =
|
||||
minimizer_type == LINE_SEARCH ||
|
||||
(minimizer_type == TRUST_REGION && is_constrained);
|
||||
const bool line_search_used =
|
||||
(minimizer_type == LINE_SEARCH ||
|
||||
(minimizer_type == TRUST_REGION && is_constrained));
|
||||
|
||||
if (line_search_used) {
|
||||
StringAppendF(&report, "Line search steps % 14d\n",
|
||||
num_line_search_steps);
|
||||
}
|
||||
|
||||
StringAppendF(&report, "\nTime (in seconds):\n");
|
||||
StringAppendF(&report, "Preprocessor %25.4f\n",
|
||||
@@ -794,13 +813,13 @@ string Solver::Summary::FullReport() const {
|
||||
|
||||
StringAppendF(&report, "\n Residual evaluation %23.4f\n",
|
||||
residual_evaluation_time_in_seconds);
|
||||
if (print_line_search_timing_information) {
|
||||
if (line_search_used) {
|
||||
StringAppendF(&report, " Line search cost evaluation %10.4f\n",
|
||||
line_search_cost_evaluation_time_in_seconds);
|
||||
}
|
||||
StringAppendF(&report, " Jacobian evaluation %23.4f\n",
|
||||
jacobian_evaluation_time_in_seconds);
|
||||
if (print_line_search_timing_information) {
|
||||
if (line_search_used) {
|
||||
StringAppendF(&report, " Line search gradient evaluation %6.4f\n",
|
||||
line_search_gradient_evaluation_time_in_seconds);
|
||||
}
|
||||
@@ -815,7 +834,7 @@ string Solver::Summary::FullReport() const {
|
||||
inner_iteration_time_in_seconds);
|
||||
}
|
||||
|
||||
if (print_line_search_timing_information) {
|
||||
if (line_search_used) {
|
||||
StringAppendF(&report, " Line search polynomial minimization %.4f\n",
|
||||
line_search_polynomial_minimization_time_in_seconds);
|
||||
}
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
|
||||
#include "ceres/compressed_row_sparse_matrix.h"
|
||||
#include "ceres/cxsparse.h"
|
||||
@@ -71,6 +72,12 @@ LinearSolver::Summary SimplicialLDLTSolve(
|
||||
|
||||
if (do_symbolic_analysis) {
|
||||
solver->analyzePattern(lhs);
|
||||
if (VLOG_IS_ON(2)) {
|
||||
std::stringstream ss;
|
||||
solver->dumpMemory(ss);
|
||||
VLOG(2) << "Symbolic Analysis\n"
|
||||
<< ss.str();
|
||||
}
|
||||
event_logger->AddEvent("Analyze");
|
||||
if (solver->info() != Eigen::Success) {
|
||||
summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
|
||||
|
41
extern/ceres/internal/ceres/stringprintf.cc
vendored
41
extern/ceres/internal/ceres/stringprintf.cc
vendored
@@ -43,14 +43,27 @@ namespace internal {
|
||||
|
||||
using std::string;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
enum { IS_COMPILER_MSVC = 1 };
|
||||
#if _MSC_VER < 1800
|
||||
#define va_copy(d, s) ((d) = (s))
|
||||
#endif
|
||||
// va_copy() was defined in the C99 standard. However, it did not appear in the
|
||||
// C++ standard until C++11. This means that if Ceres is being compiled with a
|
||||
// strict pre-C++11 standard (e.g. -std=c++03), va_copy() will NOT be defined,
|
||||
// as we are using the C++ compiler (it would however be defined if we were
|
||||
// using the C compiler). Note however that both GCC & Clang will in fact
|
||||
// define va_copy() when compiling for C++ if the C++ standard is not explicitly
|
||||
// specified (i.e. no -std=c++<XX> arg), even though it should not strictly be
|
||||
// defined unless -std=c++11 (or greater) was passed.
|
||||
#if !defined(va_copy)
|
||||
#if defined (__GNUC__)
|
||||
// On GCC/Clang, if va_copy() is not defined (C++ standard < C++11 explicitly
|
||||
// specified), use the internal __va_copy() version, which should be present
|
||||
// in even very old GCC versions.
|
||||
#define va_copy(d, s) __va_copy(d, s)
|
||||
#else
|
||||
enum { IS_COMPILER_MSVC = 0 };
|
||||
#endif
|
||||
// Some older versions of MSVC do not have va_copy(), in which case define it.
|
||||
// Although this is required for older MSVC versions, it should also work for
|
||||
// other non-GCC/Clang compilers which also do not defined va_copy().
|
||||
#define va_copy(d, s) ((d) = (s))
|
||||
#endif // defined (__GNUC__)
|
||||
#endif // !defined(va_copy)
|
||||
|
||||
void StringAppendV(string* dst, const char* format, va_list ap) {
|
||||
// First try with a small fixed size buffer
|
||||
@@ -71,13 +84,13 @@ void StringAppendV(string* dst, const char* format, va_list ap) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_COMPILER_MSVC) {
|
||||
// Error or MSVC running out of space. MSVC 8.0 and higher
|
||||
// can be asked about space needed with the special idiom below:
|
||||
va_copy(backup_ap, ap);
|
||||
result = vsnprintf(NULL, 0, format, backup_ap);
|
||||
va_end(backup_ap);
|
||||
}
|
||||
#if defined (_MSC_VER)
|
||||
// Error or MSVC running out of space. MSVC 8.0 and higher
|
||||
// can be asked about space needed with the special idiom below:
|
||||
va_copy(backup_ap, ap);
|
||||
result = vsnprintf(NULL, 0, format, backup_ap);
|
||||
va_end(backup_ap);
|
||||
#endif
|
||||
|
||||
if (result < 0) {
|
||||
// Just an error.
|
||||
|
1341
extern/ceres/internal/ceres/trust_region_minimizer.cc
vendored
1341
extern/ceres/internal/ceres/trust_region_minimizer.cc
vendored
File diff suppressed because it is too large
Load Diff
123
extern/ceres/internal/ceres/trust_region_minimizer.h
vendored
123
extern/ceres/internal/ceres/trust_region_minimizer.h
vendored
@@ -1,5 +1,5 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// http://ceres-solver.org/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
@@ -31,35 +31,136 @@
|
||||
#ifndef CERES_INTERNAL_TRUST_REGION_MINIMIZER_H_
|
||||
#define CERES_INTERNAL_TRUST_REGION_MINIMIZER_H_
|
||||
|
||||
#include "ceres/internal/eigen.h"
|
||||
#include "ceres/internal/scoped_ptr.h"
|
||||
#include "ceres/minimizer.h"
|
||||
#include "ceres/solver.h"
|
||||
#include "ceres/sparse_matrix.h"
|
||||
#include "ceres/trust_region_step_evaluator.h"
|
||||
#include "ceres/trust_region_strategy.h"
|
||||
#include "ceres/types.h"
|
||||
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
// Generic trust region minimization algorithm. The heavy lifting is
|
||||
// done by a TrustRegionStrategy object passed in as part of options.
|
||||
// Generic trust region minimization algorithm.
|
||||
//
|
||||
// For example usage, see SolverImpl::Minimize.
|
||||
class TrustRegionMinimizer : public Minimizer {
|
||||
public:
|
||||
~TrustRegionMinimizer() {}
|
||||
~TrustRegionMinimizer();
|
||||
|
||||
// This method is not thread safe.
|
||||
virtual void Minimize(const Minimizer::Options& options,
|
||||
double* parameters,
|
||||
Solver::Summary* summary);
|
||||
Solver::Summary* solver_summary);
|
||||
|
||||
private:
|
||||
void Init(const Minimizer::Options& options);
|
||||
void EstimateScale(const SparseMatrix& jacobian, double* scale) const;
|
||||
bool MaybeDumpLinearLeastSquaresProblem(const int iteration,
|
||||
const SparseMatrix* jacobian,
|
||||
const double* residuals,
|
||||
const double* step) const;
|
||||
void Init(const Minimizer::Options& options,
|
||||
double* parameters,
|
||||
Solver::Summary* solver_summary);
|
||||
bool IterationZero();
|
||||
bool FinalizeIterationAndCheckIfMinimizerCanContinue();
|
||||
bool ComputeTrustRegionStep();
|
||||
|
||||
bool EvaluateGradientAndJacobian();
|
||||
void ComputeCandidatePointAndEvaluateCost();
|
||||
|
||||
void DoLineSearch(const Vector& x,
|
||||
const Vector& gradient,
|
||||
const double cost,
|
||||
Vector* delta);
|
||||
void DoInnerIterationsIfNeeded();
|
||||
|
||||
bool ParameterToleranceReached();
|
||||
bool FunctionToleranceReached();
|
||||
bool GradientToleranceReached();
|
||||
bool MaxSolverTimeReached();
|
||||
bool MaxSolverIterationsReached();
|
||||
bool MinTrustRegionRadiusReached();
|
||||
|
||||
bool IsStepSuccessful();
|
||||
void HandleUnsuccessfulStep();
|
||||
bool HandleSuccessfulStep();
|
||||
bool HandleInvalidStep();
|
||||
|
||||
Minimizer::Options options_;
|
||||
|
||||
// These pointers are shortcuts to objects passed to the
|
||||
// TrustRegionMinimizer. The TrustRegionMinimizer does not own them.
|
||||
double* parameters_;
|
||||
Solver::Summary* solver_summary_;
|
||||
Evaluator* evaluator_;
|
||||
SparseMatrix* jacobian_;
|
||||
TrustRegionStrategy* strategy_;
|
||||
|
||||
scoped_ptr<TrustRegionStepEvaluator> step_evaluator_;
|
||||
|
||||
bool is_not_silent_;
|
||||
bool inner_iterations_are_enabled_;
|
||||
bool inner_iterations_were_useful_;
|
||||
|
||||
// Summary of the current iteration.
|
||||
IterationSummary iteration_summary_;
|
||||
|
||||
// Dimensionality of the problem in the ambient space.
|
||||
int num_parameters_;
|
||||
// Dimensionality of the problem in the tangent space. This is the
|
||||
// number of columns in the Jacobian.
|
||||
int num_effective_parameters_;
|
||||
// Length of the residual vector, also the number of rows in the Jacobian.
|
||||
int num_residuals_;
|
||||
|
||||
// Current point.
|
||||
Vector x_;
|
||||
// Residuals at x_;
|
||||
Vector residuals_;
|
||||
// Gradient at x_.
|
||||
Vector gradient_;
|
||||
// Solution computed by the inner iterations.
|
||||
Vector inner_iteration_x_;
|
||||
// model_residuals = J * trust_region_step
|
||||
Vector model_residuals_;
|
||||
Vector negative_gradient_;
|
||||
// projected_gradient_step = Plus(x, -gradient), an intermediate
|
||||
// quantity used to compute the projected gradient norm.
|
||||
Vector projected_gradient_step_;
|
||||
// The step computed by the trust region strategy. If Jacobi scaling
|
||||
// is enabled, this is a vector in the scaled space.
|
||||
Vector trust_region_step_;
|
||||
// The current proposal for how far the trust region algorithm
|
||||
// thinks we should move. In the most basic case, it is just the
|
||||
// trust_region_step_ with the Jacobi scaling undone. If bounds
|
||||
// constraints are present, then it is the result of the projected
|
||||
// line search.
|
||||
Vector delta_;
|
||||
// candidate_x = Plus(x, delta)
|
||||
Vector candidate_x_;
|
||||
// Scaling vector to scale the columns of the Jacobian.
|
||||
Vector jacobian_scaling_;
|
||||
|
||||
// Euclidean norm of x_.
|
||||
double x_norm_;
|
||||
// Cost at x_.
|
||||
double x_cost_;
|
||||
// Minimum cost encountered up till now.
|
||||
double minimum_cost_;
|
||||
// How much did the trust region strategy reduce the cost of the
|
||||
// linearized Gauss-Newton model.
|
||||
double model_cost_change_;
|
||||
// Cost at candidate_x_.
|
||||
double candidate_cost_;
|
||||
|
||||
// Time at which the minimizer was started.
|
||||
double start_time_in_secs_;
|
||||
// Time at which the current iteration was started.
|
||||
double iteration_start_time_in_secs_;
|
||||
// Number of consecutive steps where the minimizer loop computed a
|
||||
// numerically invalid step.
|
||||
int num_consecutive_invalid_steps_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ceres
|
||||
|
||||
#endif // CERES_INTERNAL_TRUST_REGION_MINIMIZER_H_
|
||||
|
107
extern/ceres/internal/ceres/trust_region_step_evaluator.cc
vendored
Normal file
107
extern/ceres/internal/ceres/trust_region_step_evaluator.cc
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// http://ceres-solver.org/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: sameeragarwal@google.com (Sameer Agarwal)
|
||||
|
||||
#include <algorithm>
|
||||
#include "ceres/trust_region_step_evaluator.h"
|
||||
#include "glog/logging.h"
|
||||
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
TrustRegionStepEvaluator::TrustRegionStepEvaluator(
|
||||
const double initial_cost,
|
||||
const int max_consecutive_nonmonotonic_steps)
|
||||
: max_consecutive_nonmonotonic_steps_(max_consecutive_nonmonotonic_steps),
|
||||
minimum_cost_(initial_cost),
|
||||
current_cost_(initial_cost),
|
||||
reference_cost_(initial_cost),
|
||||
candidate_cost_(initial_cost),
|
||||
accumulated_reference_model_cost_change_(0.0),
|
||||
accumulated_candidate_model_cost_change_(0.0),
|
||||
num_consecutive_nonmonotonic_steps_(0){
|
||||
}
|
||||
|
||||
double TrustRegionStepEvaluator::StepQuality(
|
||||
const double cost,
|
||||
const double model_cost_change) const {
|
||||
const double relative_decrease = (current_cost_ - cost) / model_cost_change;
|
||||
const double historical_relative_decrease =
|
||||
(reference_cost_ - cost) /
|
||||
(accumulated_reference_model_cost_change_ + model_cost_change);
|
||||
return std::max(relative_decrease, historical_relative_decrease);
|
||||
}
|
||||
|
||||
void TrustRegionStepEvaluator::StepAccepted(
|
||||
const double cost,
|
||||
const double model_cost_change) {
|
||||
// Algorithm 10.1.2 from Trust Region Methods by Conn, Gould &
|
||||
// Toint.
|
||||
//
|
||||
// Step 3a
|
||||
current_cost_ = cost;
|
||||
accumulated_candidate_model_cost_change_ += model_cost_change;
|
||||
accumulated_reference_model_cost_change_ += model_cost_change;
|
||||
|
||||
// Step 3b.
|
||||
if (current_cost_ < minimum_cost_) {
|
||||
minimum_cost_ = current_cost_;
|
||||
num_consecutive_nonmonotonic_steps_ = 0;
|
||||
candidate_cost_ = current_cost_;
|
||||
accumulated_candidate_model_cost_change_ = 0.0;
|
||||
} else {
|
||||
// Step 3c.
|
||||
++num_consecutive_nonmonotonic_steps_;
|
||||
if (current_cost_ > candidate_cost_) {
|
||||
candidate_cost_ = current_cost_;
|
||||
accumulated_candidate_model_cost_change_ = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3d.
|
||||
//
|
||||
// At this point we have made too many non-monotonic steps and
|
||||
// we are going to reset the value of the reference iterate so
|
||||
// as to force the algorithm to descend.
|
||||
//
|
||||
// Note: In the original algorithm by Toint, this step was only
|
||||
// executed if the step was non-monotonic, but that would not handle
|
||||
// the case of max_consecutive_nonmonotonic_steps = 0. The small
|
||||
// modification of doing this always handles that corner case
|
||||
// correctly.
|
||||
if (num_consecutive_nonmonotonic_steps_ ==
|
||||
max_consecutive_nonmonotonic_steps_) {
|
||||
reference_cost_ = candidate_cost_;
|
||||
accumulated_reference_model_cost_change_ =
|
||||
accumulated_candidate_model_cost_change_;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ceres
|
122
extern/ceres/internal/ceres/trust_region_step_evaluator.h
vendored
Normal file
122
extern/ceres/internal/ceres/trust_region_step_evaluator.h
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// http://ceres-solver.org/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: sameeragarwal@google.com (Sameer Agarwal)
|
||||
|
||||
#ifndef CERES_INTERNAL_TRUST_REGION_STEP_EVALUATOR_H_
|
||||
#define CERES_INTERNAL_TRUST_REGION_STEP_EVALUATOR_H_
|
||||
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
// The job of the TrustRegionStepEvaluator is to evaluate the quality
|
||||
// of a step, i.e., how the cost of a step compares with the reduction
|
||||
// in the objective of the trust region problem.
|
||||
//
|
||||
// Classic trust region methods are descent methods, in that they only
|
||||
// accept a point if it strictly reduces the value of the objective
|
||||
// function. They do this by measuring the quality of a step as
|
||||
//
|
||||
// cost_change / model_cost_change.
|
||||
//
|
||||
// Relaxing the monotonic descent requirement allows the algorithm to
|
||||
// be more efficient in the long term at the cost of some local
|
||||
// increase in the value of the objective function.
|
||||
//
|
||||
// This is because allowing for non-decreasing objective function
|
||||
// values in a principled manner allows the algorithm to "jump over
|
||||
// boulders" as the method is not restricted to move into narrow
|
||||
// valleys while preserving its convergence properties.
|
||||
//
|
||||
// The parameter max_consecutive_nonmonotonic_steps controls the
|
||||
// window size used by the step selection algorithm to accept
|
||||
// non-monotonic steps. Setting this parameter to zero, recovers the
|
||||
// classic montonic descent algorithm.
|
||||
//
|
||||
// Based on algorithm 10.1.2 (page 357) of "Trust Region
|
||||
// Methods" by Conn Gould & Toint, or equations 33-40 of
|
||||
// "Non-monotone trust-region algorithms for nonlinear
|
||||
// optimization subject to convex constraints" by Phil Toint,
|
||||
// Mathematical Programming, 77, 1997.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// TrustRegionStepEvaluator* step_evaluator = ...
|
||||
//
|
||||
// cost = ... // Compute the non-linear objective function value.
|
||||
// model_cost_change = ... // Change in the value of the trust region objective.
|
||||
// if (step_evaluator->StepQuality(cost, model_cost_change) > threshold) {
|
||||
// x = x + delta;
|
||||
// step_evaluator->StepAccepted(cost, model_cost_change);
|
||||
// }
|
||||
class TrustRegionStepEvaluator {
|
||||
public:
|
||||
// initial_cost is as the name implies the cost of the starting
|
||||
// state of the trust region minimizer.
|
||||
//
|
||||
// max_consecutive_nonmonotonic_steps controls the window size used
|
||||
// by the step selection algorithm to accept non-monotonic
|
||||
// steps. Setting this parameter to zero, recovers the classic
|
||||
// montonic descent algorithm.
|
||||
TrustRegionStepEvaluator(double initial_cost,
|
||||
int max_consecutive_nonmonotonic_steps);
|
||||
|
||||
// Return the quality of the step given its cost and the decrease in
|
||||
// the cost of the model. model_cost_change has to be positive.
|
||||
double StepQuality(double cost, double model_cost_change) const;
|
||||
|
||||
// Inform the step evaluator that a step with the given cost and
|
||||
// model_cost_change has been accepted by the trust region
|
||||
// minimizer.
|
||||
void StepAccepted(double cost, double model_cost_change);
|
||||
|
||||
private:
|
||||
const int max_consecutive_nonmonotonic_steps_;
|
||||
// The minimum cost encountered up till now.
|
||||
double minimum_cost_;
|
||||
// The current cost of the trust region minimizer as informed by the
|
||||
// last call to StepAccepted.
|
||||
double current_cost_;
|
||||
double reference_cost_;
|
||||
double candidate_cost_;
|
||||
// Accumulated model cost since the last time the reference model
|
||||
// cost was updated, i.e., when a step with cost less than the
|
||||
// current known minimum cost is accepted.
|
||||
double accumulated_reference_model_cost_change_;
|
||||
// Accumulated model cost since the last time the candidate model
|
||||
// cost was updated, i.e., a non-monotonic step was taken with a
|
||||
// cost that was greater than the current candidate cost.
|
||||
double accumulated_candidate_model_cost_change_;
|
||||
// Number of steps taken since the last time minimum_cost was updated.
|
||||
int num_consecutive_nonmonotonic_steps_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ceres
|
||||
|
||||
#endif // CERES_INTERNAL_TRUST_REGION_STEP_EVALUATOR_H_
|
@@ -86,20 +86,20 @@ class TrustRegionStrategy {
|
||||
struct PerSolveOptions {
|
||||
PerSolveOptions()
|
||||
: eta(0),
|
||||
dump_filename_base(""),
|
||||
dump_format_type(TEXTFILE) {
|
||||
}
|
||||
|
||||
// Forcing sequence for inexact solves.
|
||||
double eta;
|
||||
|
||||
DumpFormatType dump_format_type;
|
||||
|
||||
// If non-empty and dump_format_type is not CONSOLE, the trust
|
||||
// regions strategy will write the linear system to file(s) with
|
||||
// name starting with dump_filename_base. If dump_format_type is
|
||||
// CONSOLE then dump_filename_base will be ignored and the linear
|
||||
// system will be written to the standard error.
|
||||
std::string dump_filename_base;
|
||||
DumpFormatType dump_format_type;
|
||||
};
|
||||
|
||||
struct Summary {
|
||||
|
2
extern/clew/README.blender
vendored
2
extern/clew/README.blender
vendored
@@ -1,5 +1,5 @@
|
||||
Project: OpenCL Wrangler
|
||||
URL: https://github.com/OpenCLWrangler/clew
|
||||
License: Apache 2.0
|
||||
Upstream version: 309a653
|
||||
Upstream version: 27a6867
|
||||
Local modifications: None
|
||||
|
32
extern/clew/include/clew.h
vendored
32
extern/clew/include/clew.h
vendored
@@ -369,7 +369,8 @@ typedef unsigned int cl_GLenum;
|
||||
#endif
|
||||
|
||||
/* Define basic vector types */
|
||||
#if defined( __VEC__ )
|
||||
/* Workaround for ppc64el platform: conflicts with bool from C++. */
|
||||
#if defined( __VEC__ ) && !(defined(__PPC64__) && defined(__LITTLE_ENDIAN__))
|
||||
#include <altivec.h> /* may be omitted depending on compiler. AltiVec spec provides no way to detect whether the header is required. */
|
||||
typedef vector unsigned char __cl_uchar16;
|
||||
typedef vector signed char __cl_char16;
|
||||
@@ -2764,11 +2765,40 @@ CLEW_FUN_EXPORT PFNCLGETGLCONTEXTINFOKHR __clewGetGLContextInfoKH
|
||||
#define CL_DEVICE_GPU_OVERLAP_NV 0x4004
|
||||
#define CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV 0x4005
|
||||
#define CL_DEVICE_INTEGRATED_MEMORY_NV 0x4006
|
||||
#define CL_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT_NV 0x4007
|
||||
#define CL_DEVICE_PCI_BUS_ID_NV 0x4008
|
||||
#define CL_DEVICE_PCI_SLOT_ID_NV 0x4009
|
||||
|
||||
/*********************************
|
||||
* cl_amd_device_attribute_query *
|
||||
*********************************/
|
||||
#define CL_DEVICE_PROFILING_TIMER_OFFSET_AMD 0x4036
|
||||
#define CL_DEVICE_TOPOLOGY_AMD 0x4037
|
||||
#define CL_DEVICE_BOARD_NAME_AMD 0x4038
|
||||
#define CL_DEVICE_GLOBAL_FREE_MEMORY_AMD 0x4039
|
||||
#define CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD 0x4040
|
||||
#define CL_DEVICE_SIMD_WIDTH_AMD 0x4041
|
||||
#define CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD 0x4042
|
||||
#define CL_DEVICE_WAVEFRONT_WIDTH_AMD 0x4043
|
||||
#define CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD 0x4044
|
||||
#define CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD 0x4045
|
||||
#define CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD 0x4046
|
||||
#define CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD 0x4047
|
||||
#define CL_DEVICE_LOCAL_MEM_BANKS_AMD 0x4048
|
||||
#define CL_DEVICE_THREAD_TRACE_SUPPORTED_AMD 0x4049
|
||||
#define CL_DEVICE_GFXIP_MAJOR_AMD 0x404A
|
||||
#define CL_DEVICE_GFXIP_MINOR_AMD 0x404B
|
||||
#define CL_DEVICE_AVAILABLE_ASYNC_QUEUES_AMD 0x404C
|
||||
|
||||
#ifndef CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD
|
||||
#define CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD 1
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct { cl_uint type; cl_uint data[5]; } raw;
|
||||
struct { cl_uint type; cl_char unused[17]; cl_char bus; cl_char device; cl_char function; } pcie;
|
||||
} cl_device_topology_amd;
|
||||
#endif
|
||||
|
||||
/*********************************
|
||||
* cl_arm_printf extension
|
||||
|
4
extern/clew/src/clew.c
vendored
4
extern/clew/src/clew.c
vendored
@@ -15,7 +15,7 @@
|
||||
|
||||
typedef HMODULE CLEW_DYNLIB_HANDLE;
|
||||
|
||||
#define CLEW_DYNLIB_OPEN LoadLibrary
|
||||
#define CLEW_DYNLIB_OPEN LoadLibraryA
|
||||
#define CLEW_DYNLIB_CLOSE FreeLibrary
|
||||
#define CLEW_DYNLIB_IMPORT GetProcAddress
|
||||
#else
|
||||
@@ -223,7 +223,7 @@ int clewInit()
|
||||
__clewSetCommandQueueProperty = (PFNCLSETCOMMANDQUEUEPROPERTY )CLEW_DYNLIB_IMPORT(module, "clSetCommandQueueProperty");
|
||||
#endif
|
||||
__clewCreateBuffer = (PFNCLCREATEBUFFER )CLEW_DYNLIB_IMPORT(module, "clCreateBuffer");
|
||||
__clewCreateSubBuffer = (PFNCLCREATESUBBUFFER )CLEW_DYNLIB_IMPORT(module, "clCreateBuffer");
|
||||
__clewCreateSubBuffer = (PFNCLCREATESUBBUFFER )CLEW_DYNLIB_IMPORT(module, "clCreateSubBuffer");
|
||||
__clewCreateImage = (PFNCLCREATEIMAGE )CLEW_DYNLIB_IMPORT(module, "clCreateImage");
|
||||
__clewRetainMemObject = (PFNCLRETAINMEMOBJECT )CLEW_DYNLIB_IMPORT(module, "clRetainMemObject");
|
||||
__clewReleaseMemObject = (PFNCLRELEASEMEMOBJECT )CLEW_DYNLIB_IMPORT(module, "clReleaseMemObject");
|
||||
|
2
extern/cuew/README
vendored
2
extern/cuew/README
vendored
@@ -4,7 +4,7 @@ for determining which CUDA functions and extensions extensions are supported
|
||||
on the target platform.
|
||||
|
||||
CUDA core and extension functionality is exposed in a single header file.
|
||||
GUEW has been tested on a variety of operating systems, including Windows,
|
||||
CUEW has been tested on a variety of operating systems, including Windows,
|
||||
Linux, Mac OS X.
|
||||
|
||||
LICENSE
|
||||
|
2
extern/cuew/README.blender
vendored
2
extern/cuew/README.blender
vendored
@@ -1,5 +1,5 @@
|
||||
Project: Cuda Wrangler
|
||||
URL: https://github.com/CudaWrangler/cuew
|
||||
License: Apache 2.0
|
||||
Upstream version: e2e0315
|
||||
Upstream version: 63d2a0f
|
||||
Local modifications: None
|
||||
|
2
extern/cuew/include/cuew.h
vendored
2
extern/cuew/include/cuew.h
vendored
@@ -114,7 +114,7 @@ extern "C" {
|
||||
#define cuGLGetDevices cuGLGetDevices_v2
|
||||
|
||||
/* Types. */
|
||||
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
|
||||
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) || defined (__aarch64__)
|
||||
typedef unsigned long long CUdeviceptr;
|
||||
#else
|
||||
typedef unsigned int CUdeviceptr;
|
||||
|
2
extern/curve_fit_nd/curve_fit_nd.h
vendored
2
extern/curve_fit_nd/curve_fit_nd.h
vendored
@@ -137,7 +137,7 @@ int curve_fit_cubic_to_points_refit_db(
|
||||
const double error_threshold,
|
||||
const unsigned int calc_flag,
|
||||
const unsigned int *corners,
|
||||
unsigned int corners_len,
|
||||
const unsigned int corners_len,
|
||||
const double corner_angle,
|
||||
|
||||
double **r_cubic_array, unsigned int *r_cubic_array_len,
|
||||
|
54
extern/curve_fit_nd/intern/curve_fit_cubic.c
vendored
54
extern/curve_fit_nd/intern/curve_fit_cubic.c
vendored
@@ -255,7 +255,7 @@ static void cubic_list_clear(CubicList *clist)
|
||||
/** \name Cubic Evaluation
|
||||
* \{ */
|
||||
|
||||
static void cubic_evaluate(
|
||||
static void cubic_calc_point(
|
||||
const Cubic *cubic, const double t, const uint dims,
|
||||
double r_v[])
|
||||
{
|
||||
@@ -271,18 +271,6 @@ static void cubic_evaluate(
|
||||
}
|
||||
}
|
||||
|
||||
static void cubic_calc_point(
|
||||
const Cubic *cubic, const double t, const uint dims,
|
||||
double r_v[])
|
||||
{
|
||||
CUBIC_VARS_CONST(cubic, dims, p0, p1, p2, p3);
|
||||
const double s = 1.0 - t;
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
r_v[j] = p0[j] * s * s * s +
|
||||
3.0 * t * s * (s * p1[j] + t * p2[j]) + t * t * t * p3[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void cubic_calc_speed(
|
||||
const Cubic *cubic, const double t, const uint dims,
|
||||
double r_v[])
|
||||
@@ -332,7 +320,7 @@ static double cubic_calc_error(
|
||||
#endif
|
||||
|
||||
for (uint i = 1; i < points_offset_len - 1; i++, pt_real += dims) {
|
||||
cubic_evaluate(cubic, u[i], dims, pt_eval);
|
||||
cubic_calc_point(cubic, u[i], dims, pt_eval);
|
||||
|
||||
const double err_sq = len_squared_vnvn(pt_real, pt_eval, dims);
|
||||
if (err_sq >= error_max_sq) {
|
||||
@@ -368,7 +356,7 @@ static double cubic_calc_error_simple(
|
||||
#endif
|
||||
|
||||
for (uint i = 1; i < points_offset_len - 1; i++, pt_real += dims) {
|
||||
cubic_evaluate(cubic, u[i], dims, pt_eval);
|
||||
cubic_calc_point(cubic, u[i], dims, pt_eval);
|
||||
|
||||
const double err_sq = len_squared_vnvn(pt_real, pt_eval, dims);
|
||||
if (err_sq >= error_threshold_sq) {
|
||||
@@ -501,7 +489,7 @@ static double points_calc_circle_tangent_factor(
|
||||
return (1.0 / 3.0) * 0.75;
|
||||
}
|
||||
else if (tan_dot < -1.0 + eps) {
|
||||
/* parallele tangents (half-circle) */
|
||||
/* parallel tangents (half-circle) */
|
||||
return (1.0 / 2.0);
|
||||
}
|
||||
else {
|
||||
@@ -623,8 +611,8 @@ static void cubic_from_points_offset_fallback(
|
||||
}
|
||||
}
|
||||
|
||||
double alpha_l = (dists[0] / 0.75) / dot_vnvn(tan_l, a[0], dims);
|
||||
double alpha_r = (dists[1] / 0.75) / -dot_vnvn(tan_r, a[1], dims);
|
||||
double alpha_l = (dists[0] / 0.75) / fabs(dot_vnvn(tan_l, a[0], dims));
|
||||
double alpha_r = (dists[1] / 0.75) / fabs(dot_vnvn(tan_r, a[1], dims));
|
||||
|
||||
if (!(alpha_l > 0.0)) {
|
||||
alpha_l = dir_dist / 3.0;
|
||||
@@ -677,13 +665,11 @@ static void cubic_from_points(
|
||||
double alpha_l, alpha_r;
|
||||
#ifdef USE_VLA
|
||||
double a[2][dims];
|
||||
double tmp[dims];
|
||||
#else
|
||||
double *a[2] = {
|
||||
alloca(sizeof(double) * dims),
|
||||
alloca(sizeof(double) * dims),
|
||||
};
|
||||
double *tmp = alloca(sizeof(double) * dims);
|
||||
#endif
|
||||
|
||||
{
|
||||
@@ -694,22 +680,22 @@ static void cubic_from_points(
|
||||
mul_vnvn_fl(a[0], tan_l, B1(u_prime[i]), dims);
|
||||
mul_vnvn_fl(a[1], tan_r, B2(u_prime[i]), dims);
|
||||
|
||||
c[0][0] += dot_vnvn(a[0], a[0], dims);
|
||||
c[0][1] += dot_vnvn(a[0], a[1], dims);
|
||||
c[1][1] += dot_vnvn(a[1], a[1], dims);
|
||||
const double b0_plus_b1 = B0plusB1(u_prime[i]);
|
||||
const double b2_plus_b3 = B2plusB3(u_prime[i]);
|
||||
|
||||
/* inline dot product */
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
const double tmp = (pt[j] - (p0[j] * b0_plus_b1)) + (p3[j] * b2_plus_b3);
|
||||
|
||||
x[0] += a[0][j] * tmp;
|
||||
x[1] += a[1][j] * tmp;
|
||||
|
||||
c[0][0] += a[0][j] * a[0][j];
|
||||
c[0][1] += a[0][j] * a[1][j];
|
||||
c[1][1] += a[1][j] * a[1][j];
|
||||
}
|
||||
|
||||
c[1][0] = c[0][1];
|
||||
|
||||
{
|
||||
const double b0_plus_b1 = B0plusB1(u_prime[i]);
|
||||
const double b2_plus_b3 = B2plusB3(u_prime[i]);
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
tmp[j] = (pt[j] - (p0[j] * b0_plus_b1)) + (p3[j] * b2_plus_b3);
|
||||
}
|
||||
|
||||
x[0] += dot_vnvn(a[0], tmp, dims);
|
||||
x[1] += dot_vnvn(a[1], tmp, dims);
|
||||
}
|
||||
}
|
||||
|
||||
double det_C0_C1 = c[0][0] * c[1][1] - c[0][1] * c[1][0];
|
||||
|
@@ -463,7 +463,7 @@ static uint curve_incremental_simplify(
|
||||
rstate_pool_create(&epool, 0);
|
||||
#endif
|
||||
|
||||
Heap *heap = HEAP_new(knots_len);
|
||||
Heap *heap = HEAP_new(knots_len_remaining);
|
||||
|
||||
struct KnotRemove_Params params = {
|
||||
.pd = pd,
|
||||
@@ -698,7 +698,7 @@ static uint curve_incremental_simplify_refit(
|
||||
refit_pool_create(&epool, 0);
|
||||
#endif
|
||||
|
||||
Heap *heap = HEAP_new(knots_len);
|
||||
Heap *heap = HEAP_new(knots_len_remaining);
|
||||
|
||||
struct KnotRefit_Params params = {
|
||||
.pd = pd,
|
||||
@@ -890,7 +890,7 @@ static void knot_corner_error_recalculate(
|
||||
static uint curve_incremental_simplify_corners(
|
||||
const struct PointData *pd,
|
||||
struct Knot *knots, const uint knots_len, uint knots_len_remaining,
|
||||
const double error_sq_max, const double error_sq_2x_max,
|
||||
const double error_sq_max, const double error_sq_collapse_max,
|
||||
const double corner_angle,
|
||||
const uint dims,
|
||||
uint *r_corner_index_len)
|
||||
@@ -954,12 +954,12 @@ static uint curve_incremental_simplify_corners(
|
||||
project_vn_vnvn_normalized(k_proj_ref, co_prev, k_prev->tan[1], dims);
|
||||
project_vn_vnvn_normalized(k_proj_split, co_split, k_prev->tan[1], dims);
|
||||
|
||||
if (len_squared_vnvn(k_proj_ref, k_proj_split, dims) < error_sq_2x_max) {
|
||||
if (len_squared_vnvn(k_proj_ref, k_proj_split, dims) < error_sq_collapse_max) {
|
||||
|
||||
project_vn_vnvn_normalized(k_proj_ref, co_next, k_next->tan[0], dims);
|
||||
project_vn_vnvn_normalized(k_proj_split, co_split, k_next->tan[0], dims);
|
||||
|
||||
if (len_squared_vnvn(k_proj_ref, k_proj_split, dims) < error_sq_2x_max) {
|
||||
if (len_squared_vnvn(k_proj_ref, k_proj_split, dims) < error_sq_collapse_max) {
|
||||
|
||||
struct Knot *k_split = &knots[split_index];
|
||||
|
||||
@@ -1260,9 +1260,12 @@ int curve_fit_cubic_to_points_refit_db(
|
||||
|
||||
#ifdef USE_CORNER_DETECT
|
||||
if (use_corner) {
|
||||
|
||||
#ifdef DEBUG
|
||||
for (uint i = 0; i < knots_len; i++) {
|
||||
assert(knots[i].heap_node == NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
knots_len_remaining = curve_incremental_simplify_corners(
|
||||
&pd, knots, knots_len, knots_len_remaining,
|
||||
|
4
extern/gflags/README.blender
vendored
4
extern/gflags/README.blender
vendored
@@ -18,6 +18,8 @@ Local modifications:
|
||||
- Applied some modifications from fork https://github.com/Nazg-Gul/gflags.git
|
||||
(see https://github.com/gflags/gflags/pull/129)
|
||||
|
||||
- Avoid attemot of acquiring mutex lock in FlagRegistry::GlobalRegistry when
|
||||
- Avoid attempt of acquiring mutex lock in FlagRegistry::GlobalRegistry when
|
||||
doing static flags initialization. See d81dd2d in Blender repository.
|
||||
|
||||
- Made `google::{anonymous}::FlagValue::ValueSize() const` inlined, so it does
|
||||
not trigger strict compiler warning.
|
4
extern/gflags/src/gflags.cc
vendored
4
extern/gflags/src/gflags.cc
vendored
@@ -218,7 +218,7 @@ class FlagValue {
|
||||
bool Equal(const FlagValue& x) const;
|
||||
FlagValue* New() const; // creates a new one with default value
|
||||
void CopyFrom(const FlagValue& x);
|
||||
int ValueSize() const;
|
||||
inline int ValueSize() const;
|
||||
|
||||
// Calls the given validate-fn on value_buffer_, and returns
|
||||
// whatever it returns. But first casts validate_fn_proto to a
|
||||
@@ -443,7 +443,7 @@ void FlagValue::CopyFrom(const FlagValue& x) {
|
||||
}
|
||||
}
|
||||
|
||||
int FlagValue::ValueSize() const {
|
||||
inline int FlagValue::ValueSize() const {
|
||||
if (type_ > FV_MAX_INDEX) {
|
||||
assert(false); // unknown type
|
||||
return 0;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user