Compare commits
276 Commits
temp-layer
...
unlock_tas
Author | SHA1 | Date | |
---|---|---|---|
fe226dc5b3 | |||
9dab894e64 | |||
08b0b1c439 | |||
0c451bc530 | |||
1ea1b04e54 | |||
1659d42bf7 | |||
fbe84185de | |||
599f314f1d | |||
e0d486eb36 | |||
7b92b64742 | |||
2e8398c095 | |||
18c2a44333 | |||
5f05dac28f | |||
17cf423f30 | |||
91ce13e90d | |||
c0d0ef142f | |||
25de610876 | |||
cdfae957f2 | |||
810d7d4694 | |||
df88d54284 | |||
42cb93205c | |||
![]() |
a78717a72d | ||
![]() |
e7dc46d278 | ||
a83a68b9b6 | |||
87f8bb8d1d | |||
499faa8b11 | |||
856077618a | |||
193827e59b | |||
49c99549eb | |||
278fce1170 | |||
7fcae7ba60 | |||
ecee40e919 | |||
714e85b534 | |||
32c5f3d772 | |||
f0cf15b5c6 | |||
351c9239ed | |||
c1012c6c3a | |||
87f236cd10 | |||
efe78d824e | |||
a581b65822 | |||
6d1ac79514 | |||
4fa4132e45 | |||
cd5c853307 | |||
2342cd0a0f | |||
691ffb60b9 | |||
bf7006c15a | |||
5acac13eb4 | |||
f1b21d5960 | |||
209a64111e | |||
00ceb6d2f4 | |||
f7d67835e9 | |||
cc78690be3 | |||
238db604c5 | |||
845ba1a6fb | |||
406398213c | |||
631ecbc4ca | |||
112e4de885 | |||
0561aa771b | |||
5c3216e233 | |||
d66d5790e9 | |||
94ca09e01c | |||
2c4564b044 | |||
a0b8a9fe68 | |||
8c5826f59a | |||
15f1072ee2 | |||
caaf5f0a09 | |||
9062c086b4 | |||
1e29286c8c | |||
f49e28bae7 | |||
4c164487bc | |||
29859d0d5e | |||
c067f1d0d4 | |||
c7ad27fc07 | |||
6a249bb000 | |||
50328b41a7 | |||
4e12113bea | |||
13e075600a | |||
9eb647f1c8 | |||
60592f6778 | |||
9dd194716b | |||
![]() |
7359cc1060 | ||
43299f9465 | |||
5e1d4714fe | |||
b637db2a7a | |||
99947e2943 | |||
75cc33fa20 | |||
36c4fc1ea9 | |||
2c30fd83f1 | |||
ae1c1cd8c0 | |||
3622074bf7 | |||
4e9b17da4c | |||
34a502c16a | |||
696836af1d | |||
75ce4ebc12 | |||
333dc8d60f | |||
9992e6a169 | |||
3f5b2e2682 | |||
6f1493f68f | |||
31123f09cd | |||
d41451a0ca | |||
6c59a3b37a | |||
7819d36d4e | |||
99a6bbf7dd | |||
21eae869ad | |||
306acb7dda | |||
26c8d559fe | |||
6468cb5f9c | |||
5cbaf56b26 | |||
fc185fb1d2 | |||
809ed38075 | |||
781507d2dd | |||
9b3d415f6a | |||
40e5bc15e9 | |||
41e0085fd3 | |||
e22d4699cb | |||
13d31b1604 | |||
3e628eefa9 | |||
efbe47f9cd | |||
fe47163a1e | |||
20283bfa0b | |||
dd79f907a7 | |||
8b8c0d0049 | |||
6cdc954e8c | |||
dc7bbd731a | |||
088c6a17ba | |||
5723aa8c02 | |||
b36e26bbce | |||
384b7e18f1 | |||
402b0aa59b | |||
af1e48e8ab | |||
737a3b8a0a | |||
324d057b25 | |||
4d325693e1 | |||
6c104f62b9 | |||
54102ab36e | |||
930186d3df | |||
21dbfb7828 | |||
581c819013 | |||
81eee0f536 | |||
37afa965a4 | |||
594015fb7e | |||
9148ce9f3c | |||
5552e83b53 | |||
e76364adcd | |||
1ac6e4c7a2 | |||
3ede515b5b | |||
9d8a9cacc3 | |||
e33e58bf23 | |||
e991af0934 | |||
cd4309ced0 | |||
0178915ce9 | |||
fd7e9f7974 | |||
d395d81bfc | |||
0b65b889ef | |||
b26da8b467 | |||
b929eef8c5 | |||
38155c7d3c | |||
bb1367cdaf | |||
e523cde574 | |||
d2f4900d1a | |||
351eb4fad1 | |||
316d23f2ba | |||
117d90b3da | |||
b16fd22018 | |||
da31a82832 | |||
04cf1538b5 | |||
31a025f51e | |||
dde40989f3 | |||
7447950bc3 | |||
9830eeb44b | |||
9c3d202e56 | |||
58a10122d0 | |||
98a1855803 | |||
8cda364d6f | |||
ac38d5652b | |||
95e7f93fa2 | |||
b320873382 | |||
ce9df09067 | |||
82df7100c8 | |||
69dbeeca48 | |||
b641d016e1 | |||
ce629c5dd9 | |||
e5bb005369 | |||
5d6177111d | |||
03be3102c7 | |||
03544eccb4 | |||
53896d4235 | |||
1158800d1b | |||
f7eaaf35b4 | |||
e217839fd3 | |||
dbdc346e9f | |||
0170c682fe | |||
e3f99329d8 | |||
ac8348d033 | |||
9e97b00873 | |||
c7f40caa2c | |||
c5cc9e046d | |||
d0015cba02 | |||
89f3837d68 | |||
385fe4f0ce | |||
223aff987a | |||
![]() |
351c409317 | ||
22156d951d | |||
da08aa4b96 | |||
75aa866211 | |||
47caf343c0 | |||
a2c469edc2 | |||
6663099810 | |||
c367e23d46 | |||
a0561a05ef | |||
21f3767809 | |||
0b4a9caf51 | |||
0e459ad1a3 | |||
52696a0d3f | |||
f3a7104adb | |||
a1820afa30 | |||
030e99588d | |||
aea17a612d | |||
dc1b45ff1a | |||
e1e85454ea | |||
103f2655ab | |||
ddf99214dc | |||
9f67367f0a | |||
33e456b0ce | |||
9e2dca933e | |||
feb588060a | |||
86747ff180 | |||
6edfa73f5c | |||
![]() |
7f10a889e3 | ||
![]() |
d4e0557cf1 | ||
![]() |
3ab8895610 | ||
fb61711b1a | |||
c231c29afa | |||
fa19940dc6 | |||
92258f3678 | |||
75a4c836d6 | |||
a90622ce93 | |||
326516c9d7 | |||
b3690cdecd | |||
![]() |
887fc0ff6d | ||
b5682a6fdd | |||
60e387f5e3 | |||
a928a9c1e1 | |||
d07e2416db | |||
b841d60bf8 | |||
a50b173952 | |||
4e1025376e | |||
bc4aeefe82 | |||
eadfd901ad | |||
fbd28d375a | |||
4443bad30a | |||
997a210b08 | |||
4580ace4c1 | |||
62f2c44ffb | |||
505ff16dbf | |||
318ee2e8c1 | |||
167ab03f36 | |||
cdff659036 | |||
6c23a1b8b9 | |||
b99491caf7 | |||
cf6ca226fa | |||
dead79a16a | |||
88b0b22914 | |||
cd596fa1c7 | |||
d6f965b99c | |||
15b253c082 | |||
ba116c8e9c | |||
c64c901535 | |||
e4e1900012 | |||
11abb13483 | |||
fb2f95c91a | |||
bfe3b967fa | |||
436f1e3345 | |||
0330741548 | |||
![]() |
84b18162cf | ||
bce9e80d82 |
@@ -445,6 +445,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
|
||||
@@ -723,7 +724,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()
|
||||
|
@@ -795,7 +795,7 @@ CXXFLAGS_BACK=$CXXFLAGS
|
||||
if [ "$USE_CXX11" = true ]; then
|
||||
WARNING "You are trying to use c++11, this *should* go smoothely 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.
|
||||
* 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
|
||||
|
@@ -72,10 +72,8 @@ 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/cuda8-hack/bin/nvcc')
|
||||
cmake_extra_options.append('-DWITH_CODEC_QUICKTIME=OFF')
|
||||
cmake_extra_options.append('-DCMAKE_OSX_DEPLOYMENT_TARGET=10.6')
|
||||
build_cubins = False
|
||||
|
||||
|
||||
elif builder.startswith('win'):
|
||||
|
@@ -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")
|
||||
|
||||
@@ -135,4 +137,3 @@ unset(MINOR_VERSION)
|
||||
unset(PATCH_VERSION)
|
||||
|
||||
unset(BUILD_REV)
|
||||
|
||||
|
@@ -453,6 +453,12 @@ if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
|
||||
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()
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -427,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----------------------------------
|
||||
|
||||
|
@@ -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,19 +113,24 @@ def main():
|
||||
subprocess.run(doc_gen_cmd)
|
||||
|
||||
# III) Get Blender version info.
|
||||
blenver = blenver_zip = ""
|
||||
getver_file = os.path.join(tmp_dir, "blendver.txt")
|
||||
getver_script = (""
|
||||
"import sys, bpy\n"
|
||||
"with open(sys.argv[-1], 'w') as f:\n"
|
||||
" f.write('%d_%d%s_release\\n' % (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\\n' % bpy.app.version)\n"
|
||||
" f.write('%d_%d_%d' % bpy.app.version)\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 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, blenver_zip = f.read().split("\n")
|
||||
is_release, branch, blenver, blenver_zip = f.read().split("\n")
|
||||
is_release = bool(int(is_release))
|
||||
os.remove(getver_file)
|
||||
|
||||
# IV) Build doc.
|
||||
@@ -132,7 +142,7 @@ 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)
|
||||
@@ -150,19 +160,15 @@ def main():
|
||||
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)
|
||||
|
@@ -62,7 +62,7 @@ if(WITH_IK_ITASC)
|
||||
add_subdirectory(itasc)
|
||||
endif()
|
||||
|
||||
if(WITH_IK_SOLVER OR WITH_GAMEENGINE OR WITH_MOD_BOOLEAN)
|
||||
if(WITH_GAMEENGINE)
|
||||
add_subdirectory(moto)
|
||||
endif()
|
||||
|
||||
|
@@ -101,11 +101,11 @@ ATOMIC_INLINE size_t atomic_fetch_and_add_z(size_t *p, size_t x);
|
||||
ATOMIC_INLINE size_t atomic_fetch_and_sub_z(size_t *p, size_t x);
|
||||
ATOMIC_INLINE size_t atomic_cas_z(size_t *v, size_t old, size_t _new);
|
||||
|
||||
ATOMIC_INLINE unsigned atomic_add_and_fetch_u(unsigned *p, unsigned x);
|
||||
ATOMIC_INLINE unsigned atomic_sub_and_fetch_u(unsigned *p, unsigned x);
|
||||
ATOMIC_INLINE unsigned atomic_fetch_and_add_u(unsigned *p, unsigned x);
|
||||
ATOMIC_INLINE unsigned atomic_fetch_and_sub_u(unsigned *p, unsigned x);
|
||||
ATOMIC_INLINE unsigned atomic_cas_u(unsigned *v, unsigned old, unsigned _new);
|
||||
ATOMIC_INLINE unsigned int atomic_add_and_fetch_u(unsigned int *p, unsigned int x);
|
||||
ATOMIC_INLINE unsigned int atomic_sub_and_fetch_u(unsigned int *p, unsigned int x);
|
||||
ATOMIC_INLINE unsigned int atomic_fetch_and_add_u(unsigned int *p, unsigned int x);
|
||||
ATOMIC_INLINE unsigned int atomic_fetch_and_sub_u(unsigned int *p, unsigned int x);
|
||||
ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsigned int _new);
|
||||
|
||||
/* WARNING! Float 'atomics' are really faked ones, those are actually closer to some kind of spinlock-sync'ed operation,
|
||||
* which means they are only efficient if collisions are highly unlikely (i.e. if probability of two threads
|
||||
|
@@ -113,58 +113,58 @@ ATOMIC_INLINE size_t atomic_cas_z(size_t *v, size_t old, size_t _new)
|
||||
|
||||
/******************************************************************************/
|
||||
/* unsigned operations. */
|
||||
ATOMIC_INLINE unsigned atomic_add_and_fetch_u(unsigned *p, unsigned x)
|
||||
ATOMIC_INLINE unsigned int atomic_add_and_fetch_u(unsigned int *p, unsigned int x)
|
||||
{
|
||||
assert(sizeof(unsigned) == LG_SIZEOF_INT);
|
||||
assert(sizeof(unsigned int) == LG_SIZEOF_INT);
|
||||
|
||||
#if (LG_SIZEOF_INT == 8)
|
||||
return (unsigned)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)x);
|
||||
return (unsigned int)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)x);
|
||||
#elif (LG_SIZEOF_INT == 4)
|
||||
return (unsigned)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)x);
|
||||
return (unsigned int)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)x);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE unsigned atomic_sub_and_fetch_u(unsigned *p, unsigned x)
|
||||
ATOMIC_INLINE unsigned int atomic_sub_and_fetch_u(unsigned int *p, unsigned int x)
|
||||
{
|
||||
assert(sizeof(unsigned) == LG_SIZEOF_INT);
|
||||
assert(sizeof(unsigned int) == LG_SIZEOF_INT);
|
||||
|
||||
#if (LG_SIZEOF_INT == 8)
|
||||
return (unsigned)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
|
||||
return (unsigned int)atomic_add_and_fetch_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
|
||||
#elif (LG_SIZEOF_INT == 4)
|
||||
return (unsigned)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
|
||||
return (unsigned int)atomic_add_and_fetch_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE unsigned atomic_fetch_and_add_u(unsigned *p, unsigned x)
|
||||
ATOMIC_INLINE unsigned int atomic_fetch_and_add_u(unsigned int *p, unsigned int x)
|
||||
{
|
||||
assert(sizeof(unsigned) == LG_SIZEOF_INT);
|
||||
assert(sizeof(unsigned int) == LG_SIZEOF_INT);
|
||||
|
||||
#if (LG_SIZEOF_INT == 8)
|
||||
return (unsigned)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)x);
|
||||
return (unsigned int)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)x);
|
||||
#elif (LG_SIZEOF_INT == 4)
|
||||
return (unsigned)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)x);
|
||||
return (unsigned int)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)x);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE unsigned atomic_fetch_and_sub_u(unsigned *p, unsigned x)
|
||||
ATOMIC_INLINE unsigned int atomic_fetch_and_sub_u(unsigned int *p, unsigned int x)
|
||||
{
|
||||
assert(sizeof(unsigned) == LG_SIZEOF_INT);
|
||||
assert(sizeof(unsigned int) == LG_SIZEOF_INT);
|
||||
|
||||
#if (LG_SIZEOF_INT == 8)
|
||||
return (unsigned)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
|
||||
return (unsigned int)atomic_fetch_and_add_uint64((uint64_t *)p, (uint64_t)-((int64_t)x));
|
||||
#elif (LG_SIZEOF_INT == 4)
|
||||
return (unsigned)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
|
||||
return (unsigned int)atomic_fetch_and_add_uint32((uint32_t *)p, (uint32_t)-((int32_t)x));
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_INLINE unsigned atomic_cas_u(unsigned *v, unsigned old, unsigned _new)
|
||||
ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsigned int _new)
|
||||
{
|
||||
assert(sizeof(unsigned) == LG_SIZEOF_INT);
|
||||
assert(sizeof(unsigned int) == LG_SIZEOF_INT);
|
||||
|
||||
#if (LG_SIZEOF_INT == 8)
|
||||
return (unsigned)atomic_cas_uint64((uint64_t *)v, (uint64_t)old, (uint64_t)_new);
|
||||
return (unsigned int)atomic_cas_uint64((uint64_t *)v, (uint64_t)old, (uint64_t)_new);
|
||||
#elif (LG_SIZEOF_INT == 4)
|
||||
return (unsigned)atomic_cas_uint32((uint32_t *)v, (uint32_t)old, (uint32_t)_new);
|
||||
return (unsigned int)atomic_cas_uint32((uint32_t *)v, (uint32_t)old, (uint32_t)_new);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -74,6 +74,7 @@ elseif(CMAKE_COMPILER_IS_GNUCC)
|
||||
if(CXX_HAS_AVX2)
|
||||
set(CYCLES_AVX2_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mavx -mavx2 -mfma -mlzcnt -mbmi -mbmi2 -mf16c -mfpmath=sse")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math -fno-finite-math-only")
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
check_cxx_compiler_flag(-msse CXX_HAS_SSE)
|
||||
check_cxx_compiler_flag(-mavx CXX_HAS_AVX)
|
||||
@@ -89,6 +90,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(CXX_HAS_AVX2)
|
||||
set(CYCLES_AVX2_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mavx -mavx2 -mfma -mlzcnt -mbmi -mbmi2 -mf16c")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math -fno-finite-math-only")
|
||||
endif()
|
||||
|
||||
if(CXX_HAS_SSE)
|
||||
|
@@ -62,7 +62,7 @@ def _parse_command_line():
|
||||
num_resumable_chunks = None
|
||||
current_resumable_chunk = None
|
||||
|
||||
# TODO(sergey): Add some nice error ptins if argument is not used properly.
|
||||
# TODO(sergey): Add some nice error prints if argument is not used properly.
|
||||
idx = 0
|
||||
while idx < len(argv) - 1:
|
||||
arg = argv[idx]
|
||||
|
@@ -638,6 +638,20 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
items=enum_texture_limit
|
||||
)
|
||||
|
||||
cls.ao_bounces = IntProperty(
|
||||
name="AO Bounces",
|
||||
default=0,
|
||||
description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
|
||||
min=0, max=1024,
|
||||
)
|
||||
|
||||
cls.ao_bounces_render = IntProperty(
|
||||
name="AO Bounces Render",
|
||||
default=0,
|
||||
description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
|
||||
min=0, max=1024,
|
||||
)
|
||||
|
||||
# Various fine-tuning debug flags
|
||||
|
||||
def devices_update_callback(self, context):
|
||||
|
@@ -1038,10 +1038,11 @@ class CyclesWorld_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
|
||||
layout = self.layout
|
||||
|
||||
light = context.world.light_settings
|
||||
scene = context.scene
|
||||
|
||||
row = layout.row()
|
||||
sub = row.row()
|
||||
sub.active = light.use_ambient_occlusion
|
||||
sub.active = light.use_ambient_occlusion or scene.render.use_simplify
|
||||
sub.prop(light, "ao_factor", text="Factor")
|
||||
row.prop(light, "distance", text="Distance")
|
||||
|
||||
@@ -1612,6 +1613,13 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
|
||||
row.active = cscene.use_distance_cull
|
||||
row.prop(cscene, "distance_cull_margin", text="Distance")
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.prop(cscene, "ao_bounces")
|
||||
|
||||
col = split.column()
|
||||
col.prop(cscene, "ao_bounces_render")
|
||||
|
||||
def draw_device(self, context):
|
||||
scene = context.scene
|
||||
layout = self.layout
|
||||
|
@@ -411,6 +411,7 @@ static void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData,
|
||||
}
|
||||
}
|
||||
|
||||
mesh->resize_mesh(mesh->verts.size(), mesh->triangles.size());
|
||||
mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
|
||||
mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
|
||||
mesh->add_face_normals();
|
||||
@@ -434,8 +435,8 @@ static void ExportCurveTriangleGeometry(Mesh *mesh,
|
||||
if(CData->curve_keynum[curve] <= 1 || CData->curve_length[curve] == 0.0f)
|
||||
continue;
|
||||
|
||||
numverts += (CData->curve_keynum[curve] - 2)*2*resolution + resolution;
|
||||
numtris += (CData->curve_keynum[curve] - 2)*resolution;
|
||||
numverts += (CData->curve_keynum[curve] - 1)*resolution + resolution;
|
||||
numtris += (CData->curve_keynum[curve] - 1)*2*resolution;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,6 +546,7 @@ static void ExportCurveTriangleGeometry(Mesh *mesh,
|
||||
}
|
||||
}
|
||||
|
||||
mesh->resize_mesh(mesh->verts.size(), mesh->triangles.size());
|
||||
mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
|
||||
mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
|
||||
mesh->add_face_normals();
|
||||
@@ -890,7 +892,7 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
||||
}
|
||||
|
||||
/* obtain general settings */
|
||||
bool use_curves = scene->curve_system_manager->use_curves;
|
||||
const bool use_curves = scene->curve_system_manager->use_curves;
|
||||
|
||||
if(!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT)) {
|
||||
if(!motion)
|
||||
@@ -898,11 +900,11 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
||||
return;
|
||||
}
|
||||
|
||||
int primitive = scene->curve_system_manager->primitive;
|
||||
int triangle_method = scene->curve_system_manager->triangle_method;
|
||||
int resolution = scene->curve_system_manager->resolution;
|
||||
size_t vert_num = mesh->verts.size();
|
||||
size_t tri_num = mesh->num_triangles();
|
||||
const int primitive = scene->curve_system_manager->primitive;
|
||||
const int triangle_method = scene->curve_system_manager->triangle_method;
|
||||
const int resolution = scene->curve_system_manager->resolution;
|
||||
const size_t vert_num = mesh->verts.size();
|
||||
const size_t tri_num = mesh->num_triangles();
|
||||
int used_res = 1;
|
||||
|
||||
/* extract particle hair data - should be combined with connecting to mesh later*/
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include "subd_patch.h"
|
||||
#include "subd_split.h"
|
||||
|
||||
#include "util_algorithm.h"
|
||||
#include "util_foreach.h"
|
||||
#include "util_logging.h"
|
||||
#include "util_math.h"
|
||||
@@ -525,69 +526,177 @@ static void attr_create_uv_map(Scene *scene,
|
||||
}
|
||||
|
||||
/* Create vertex pointiness attributes. */
|
||||
|
||||
/* Compare vertices by sum of their coordinates. */
|
||||
class VertexAverageComparator {
|
||||
public:
|
||||
VertexAverageComparator(const array<float3>& verts)
|
||||
: verts_(verts) {
|
||||
}
|
||||
|
||||
bool operator()(const int& vert_idx_a, const int& vert_idx_b)
|
||||
{
|
||||
const float3 &vert_a = verts_[vert_idx_a];
|
||||
const float3 &vert_b = verts_[vert_idx_b];
|
||||
if(vert_a == vert_b) {
|
||||
/* Special case for doubles, so we ensure ordering. */
|
||||
return vert_idx_a > vert_idx_b;
|
||||
}
|
||||
const float x1 = vert_a.x + vert_a.y + vert_a.z;
|
||||
const float x2 = vert_b.x + vert_b.y + vert_b.z;
|
||||
return x1 < x2;
|
||||
}
|
||||
|
||||
protected:
|
||||
const array<float3>& verts_;
|
||||
};
|
||||
|
||||
static void attr_create_pointiness(Scene *scene,
|
||||
Mesh *mesh,
|
||||
BL::Mesh& b_mesh,
|
||||
bool subdivision)
|
||||
{
|
||||
if(mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
|
||||
const int numverts = b_mesh.vertices.length();
|
||||
AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
|
||||
Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
|
||||
float *data = attr->data_float();
|
||||
int *counter = new int[numverts];
|
||||
float *raw_data = new float[numverts];
|
||||
float3 *edge_accum = new float3[numverts];
|
||||
|
||||
/* Calculate pointiness using single ring neighborhood. */
|
||||
memset(counter, 0, sizeof(int) * numverts);
|
||||
memset(raw_data, 0, sizeof(float) * numverts);
|
||||
memset(edge_accum, 0, sizeof(float3) * numverts);
|
||||
BL::Mesh::edges_iterator e;
|
||||
int i = 0;
|
||||
for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
|
||||
int v0 = b_mesh.edges[i].vertices()[0],
|
||||
v1 = b_mesh.edges[i].vertices()[1];
|
||||
float3 co0 = get_float3(b_mesh.vertices[v0].co()),
|
||||
co1 = get_float3(b_mesh.vertices[v1].co());
|
||||
float3 edge = normalize(co1 - co0);
|
||||
edge_accum[v0] += edge;
|
||||
edge_accum[v1] += -edge;
|
||||
++counter[v0];
|
||||
++counter[v1];
|
||||
}
|
||||
i = 0;
|
||||
BL::Mesh::vertices_iterator v;
|
||||
for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++i) {
|
||||
if(counter[i] > 0) {
|
||||
float3 normal = get_float3(b_mesh.vertices[i].normal());
|
||||
float angle = safe_acosf(dot(normal, edge_accum[i] / counter[i]));
|
||||
raw_data[i] = angle * M_1_PI_F;
|
||||
if(!mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
|
||||
return;
|
||||
}
|
||||
const int num_verts = b_mesh.vertices.length();
|
||||
/* STEP 1: Find out duplicated vertices and point duplicates to a single
|
||||
* original vertex.
|
||||
*/
|
||||
vector<int> sorted_vert_indeices(num_verts);
|
||||
for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
|
||||
sorted_vert_indeices[vert_index] = vert_index;
|
||||
}
|
||||
VertexAverageComparator compare(mesh->verts);
|
||||
sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare);
|
||||
/* This array stores index of the original vertex for the given vertex
|
||||
* index.
|
||||
*/
|
||||
vector<int> vert_orig_index(num_verts);
|
||||
for(int sorted_vert_index = 0;
|
||||
sorted_vert_index < num_verts;
|
||||
++sorted_vert_index)
|
||||
{
|
||||
const int vert_index = sorted_vert_indeices[sorted_vert_index];
|
||||
const float3 &vert_co = mesh->verts[vert_index];
|
||||
bool found = false;
|
||||
for(int other_sorted_vert_index = sorted_vert_index + 1;
|
||||
other_sorted_vert_index < num_verts;
|
||||
++other_sorted_vert_index)
|
||||
{
|
||||
const int other_vert_index =
|
||||
sorted_vert_indeices[other_sorted_vert_index];
|
||||
const float3 &other_vert_co = mesh->verts[other_vert_index];
|
||||
/* We are too far away now, we wouldn't have duplicate. */
|
||||
if ((other_vert_co.x + other_vert_co.y + other_vert_co.z) -
|
||||
(vert_co.x + vert_co.y + vert_co.z) > 3 * FLT_EPSILON)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else {
|
||||
raw_data[i] = 0.0f;
|
||||
/* Found duplicate. */
|
||||
if(len_squared(other_vert_co - vert_co) < FLT_EPSILON) {
|
||||
found = true;
|
||||
vert_orig_index[vert_index] = other_vert_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Blur vertices to approximate 2 ring neighborhood. */
|
||||
memset(counter, 0, sizeof(int) * numverts);
|
||||
memcpy(data, raw_data, sizeof(float) * numverts);
|
||||
i = 0;
|
||||
for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
|
||||
int v0 = b_mesh.edges[i].vertices()[0],
|
||||
v1 = b_mesh.edges[i].vertices()[1];
|
||||
data[v0] += raw_data[v1];
|
||||
data[v1] += raw_data[v0];
|
||||
++counter[v0];
|
||||
++counter[v1];
|
||||
if(!found) {
|
||||
vert_orig_index[vert_index] = vert_index;
|
||||
}
|
||||
for(i = 0; i < numverts; ++i) {
|
||||
data[i] /= counter[i] + 1;
|
||||
}
|
||||
/* Make sure we always points to the very first orig vertex. */
|
||||
for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
|
||||
int orig_index = vert_orig_index[vert_index];
|
||||
while(orig_index != vert_orig_index[orig_index]) {
|
||||
orig_index = vert_orig_index[orig_index];
|
||||
}
|
||||
|
||||
delete [] counter;
|
||||
delete [] raw_data;
|
||||
delete [] edge_accum;
|
||||
vert_orig_index[vert_index] = orig_index;
|
||||
}
|
||||
sorted_vert_indeices.free_memory();
|
||||
/* STEP 2: Calculate vertex normals taking into account their possible
|
||||
* duplicates which gets "welded" together.
|
||||
*/
|
||||
vector<float3> vert_normal(num_verts, make_float3(0.0f, 0.0f, 0.0f));
|
||||
/* First we accumulate all vertex normals in the original index. */
|
||||
for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
|
||||
const float3 normal = get_float3(b_mesh.vertices[vert_index].normal());
|
||||
const int orig_index = vert_orig_index[vert_index];
|
||||
vert_normal[orig_index] += normal;
|
||||
}
|
||||
/* Then we normalize the accumulated result and flush it to all duplicates
|
||||
* as well.
|
||||
*/
|
||||
for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
|
||||
const int orig_index = vert_orig_index[vert_index];
|
||||
vert_normal[vert_index] = normalize(vert_normal[orig_index]);
|
||||
}
|
||||
/* STEP 3: Calculate pointiness using single ring neighborhood. */
|
||||
vector<int> counter(num_verts, 0);
|
||||
vector<float> raw_data(num_verts, 0.0f);
|
||||
vector<float3> edge_accum(num_verts, make_float3(0.0f, 0.0f, 0.0f));
|
||||
BL::Mesh::edges_iterator e;
|
||||
EdgeMap visited_edges;
|
||||
int edge_index = 0;
|
||||
memset(&counter[0], 0, sizeof(int) * counter.size());
|
||||
for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
|
||||
const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
|
||||
v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
|
||||
if(visited_edges.exists(v0, v1)) {
|
||||
continue;
|
||||
}
|
||||
visited_edges.insert(v0, v1);
|
||||
float3 co0 = get_float3(b_mesh.vertices[v0].co()),
|
||||
co1 = get_float3(b_mesh.vertices[v1].co());
|
||||
float3 edge = normalize(co1 - co0);
|
||||
edge_accum[v0] += edge;
|
||||
edge_accum[v1] += -edge;
|
||||
++counter[v0];
|
||||
++counter[v1];
|
||||
}
|
||||
for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
|
||||
const int orig_index = vert_orig_index[vert_index];
|
||||
if(orig_index != vert_index) {
|
||||
/* Skip duplicates, they'll be overwritten later on. */
|
||||
continue;
|
||||
}
|
||||
if(counter[vert_index] > 0) {
|
||||
const float3 normal = vert_normal[vert_index];
|
||||
const float angle =
|
||||
safe_acosf(dot(normal,
|
||||
edge_accum[vert_index] / counter[vert_index]));
|
||||
raw_data[vert_index] = angle * M_1_PI_F;
|
||||
}
|
||||
else {
|
||||
raw_data[vert_index] = 0.0f;
|
||||
}
|
||||
}
|
||||
/* STEP 3: Blur vertices to approximate 2 ring neighborhood. */
|
||||
AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
|
||||
Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
|
||||
float *data = attr->data_float();
|
||||
memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
|
||||
memset(&counter[0], 0, sizeof(int) * counter.size());
|
||||
edge_index = 0;
|
||||
visited_edges.clear();
|
||||
for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
|
||||
const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
|
||||
v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
|
||||
if(visited_edges.exists(v0, v1)) {
|
||||
continue;
|
||||
}
|
||||
visited_edges.insert(v0, v1);
|
||||
data[v0] += raw_data[v1];
|
||||
data[v1] += raw_data[v0];
|
||||
++counter[v0];
|
||||
++counter[v1];
|
||||
}
|
||||
for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
|
||||
data[vert_index] /= counter[vert_index] + 1;
|
||||
}
|
||||
/* STEP 4: Copy attribute to the duplicated vertices. */
|
||||
for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
|
||||
const int orig_index = vert_orig_index[vert_index];
|
||||
data[vert_index] = data[orig_index];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,9 +765,6 @@ static void create_mesh(Scene *scene,
|
||||
generated[i++] = get_float3(v->undeformed_co())*size - loc;
|
||||
}
|
||||
|
||||
/* Create needed vertex attributes. */
|
||||
attr_create_pointiness(scene, mesh, b_mesh, subdivision);
|
||||
|
||||
/* create faces */
|
||||
vector<int> nverts(numfaces);
|
||||
vector<int> face_flags(numfaces, FACE_FLAG_NONE);
|
||||
@@ -671,6 +777,15 @@ static void create_mesh(Scene *scene,
|
||||
int shader = clamp(f->material_index(), 0, used_shaders.size()-1);
|
||||
bool smooth = f->use_smooth() || use_loop_normals;
|
||||
|
||||
if(use_loop_normals) {
|
||||
BL::Array<float, 12> loop_normals = f->split_normals();
|
||||
for(int i = 0; i < n; i++) {
|
||||
N[vi[i]] = make_float3(loop_normals[i * 3],
|
||||
loop_normals[i * 3 + 1],
|
||||
loop_normals[i * 3 + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create triangles.
|
||||
*
|
||||
* NOTE: Autosmooth is already taken care about.
|
||||
@@ -718,6 +833,7 @@ static void create_mesh(Scene *scene,
|
||||
/* Create all needed attributes.
|
||||
* The calculate functions will check whether they're needed or not.
|
||||
*/
|
||||
attr_create_pointiness(scene, mesh, b_mesh, subdivision);
|
||||
attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags, subdivision);
|
||||
attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags, subdivision, subdivide_uvs);
|
||||
|
||||
@@ -1178,4 +1294,3 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob,
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
@@ -1352,6 +1352,9 @@ void BlenderSession::update_resumable_tile_manager(int num_samples)
|
||||
VLOG(1) << "Samples range start is " << range_start_sample << ", "
|
||||
<< "number of samples to render is " << range_num_samples;
|
||||
|
||||
scene->integrator->start_sample = range_start_sample;
|
||||
scene->integrator->tag_update(scene);
|
||||
|
||||
session->tile_manager.range_start_sample = range_start_sample;
|
||||
session->tile_manager.range_num_samples = range_num_samples;
|
||||
}
|
||||
|
@@ -609,7 +609,8 @@ static ShaderNode *add_node(Scene *scene,
|
||||
bool is_builtin = b_image.packed_file() ||
|
||||
b_image.source() == BL::Image::source_GENERATED ||
|
||||
b_image.source() == BL::Image::source_MOVIE ||
|
||||
b_engine.is_preview();
|
||||
(b_engine.is_preview() &&
|
||||
b_image.source() != BL::Image::source_SEQUENCE);
|
||||
|
||||
if(is_builtin) {
|
||||
/* for builtin images we're using image datablock name to find an image to
|
||||
@@ -662,7 +663,8 @@ static ShaderNode *add_node(Scene *scene,
|
||||
bool is_builtin = b_image.packed_file() ||
|
||||
b_image.source() == BL::Image::source_GENERATED ||
|
||||
b_image.source() == BL::Image::source_MOVIE ||
|
||||
b_engine.is_preview();
|
||||
(b_engine.is_preview() &&
|
||||
b_image.source() != BL::Image::source_SEQUENCE);
|
||||
|
||||
if(is_builtin) {
|
||||
int scene_frame = b_scene.frame_current();
|
||||
|
@@ -322,6 +322,15 @@ void BlenderSync::sync_integrator()
|
||||
integrator->volume_samples = volume_samples;
|
||||
}
|
||||
|
||||
if(b_scene.render().use_simplify()) {
|
||||
if(preview) {
|
||||
integrator->ao_bounces = get_int(cscene, "ao_bounces");
|
||||
}
|
||||
else {
|
||||
integrator->ao_bounces = get_int(cscene, "ao_bounces_render");
|
||||
}
|
||||
}
|
||||
|
||||
if(integrator->modified(previntegrator))
|
||||
integrator->tag_update(scene);
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "mesh.h"
|
||||
|
||||
#include "util_algorithm.h"
|
||||
#include "util_map.h"
|
||||
#include "util_path.h"
|
||||
#include "util_set.h"
|
||||
@@ -78,7 +79,7 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data,
|
||||
me.calc_normals_split();
|
||||
}
|
||||
else {
|
||||
me.split_faces();
|
||||
me.split_faces(false);
|
||||
}
|
||||
}
|
||||
if(subdivision_type == Mesh::SUBDIVISION_NONE) {
|
||||
@@ -786,6 +787,35 @@ struct ParticleSystemKey {
|
||||
}
|
||||
};
|
||||
|
||||
class EdgeMap {
|
||||
public:
|
||||
EdgeMap() {
|
||||
}
|
||||
|
||||
void clear() {
|
||||
edges_.clear();
|
||||
}
|
||||
|
||||
void insert(int v0, int v1) {
|
||||
get_sorted_verts(v0, v1);
|
||||
edges_.insert(std::pair<int, int>(v0, v1));
|
||||
}
|
||||
|
||||
bool exists(int v0, int v1) {
|
||||
get_sorted_verts(v0, v1);
|
||||
return edges_.find(std::pair<int, int>(v0, v1)) != edges_.end();
|
||||
}
|
||||
|
||||
protected:
|
||||
void get_sorted_verts(int& v0, int& v1) {
|
||||
if(v0 > v1) {
|
||||
swap(v0, v1);
|
||||
}
|
||||
}
|
||||
|
||||
set< std::pair<int, int> > edges_;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __BLENDER_UTIL_H__ */
|
||||
|
@@ -81,6 +81,7 @@ void BVH::build(Progress& progress)
|
||||
pack.prim_type,
|
||||
pack.prim_index,
|
||||
pack.prim_object,
|
||||
pack.prim_time,
|
||||
params,
|
||||
progress);
|
||||
BVHNode *root = bvh_build.run();
|
||||
@@ -256,6 +257,10 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
pack.leaf_nodes.resize(leaf_nodes_size);
|
||||
pack.object_node.resize(objects.size());
|
||||
|
||||
if(params.num_motion_curve_steps > 0 || params.num_motion_triangle_steps > 0) {
|
||||
pack.prim_time.resize(prim_index_size);
|
||||
}
|
||||
|
||||
int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
|
||||
int *pack_prim_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL;
|
||||
int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
|
||||
@@ -264,6 +269,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
uint *pack_prim_tri_index = (pack.prim_tri_index.size())? &pack.prim_tri_index[0]: NULL;
|
||||
int4 *pack_nodes = (pack.nodes.size())? &pack.nodes[0]: NULL;
|
||||
int4 *pack_leaf_nodes = (pack.leaf_nodes.size())? &pack.leaf_nodes[0]: NULL;
|
||||
float2 *pack_prim_time = (pack.prim_time.size())? &pack.prim_time[0]: NULL;
|
||||
|
||||
/* merge */
|
||||
foreach(Object *ob, objects) {
|
||||
@@ -309,6 +315,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
int *bvh_prim_type = &bvh->pack.prim_type[0];
|
||||
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
|
||||
uint *bvh_prim_tri_index = &bvh->pack.prim_tri_index[0];
|
||||
float2 *bvh_prim_time = bvh->pack.prim_time.size()? &bvh->pack.prim_time[0]: NULL;
|
||||
|
||||
for(size_t i = 0; i < bvh_prim_index_size; i++) {
|
||||
if(bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
|
||||
@@ -324,6 +331,9 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
|
||||
pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
|
||||
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
|
||||
if(bvh_prim_time != NULL) {
|
||||
pack_prim_time[pack_prim_index_offset] = bvh_prim_time[i];
|
||||
}
|
||||
pack_prim_index_offset++;
|
||||
}
|
||||
}
|
||||
|
@@ -68,6 +68,8 @@ struct PackedBVH {
|
||||
array<int> prim_index;
|
||||
/* mapping from BVH primitive index, to the object id of that primitive. */
|
||||
array<int> prim_object;
|
||||
/* Time range of BVH primitive. */
|
||||
array<float2> prim_time;
|
||||
|
||||
/* index of the root node. */
|
||||
int root_index;
|
||||
|
@@ -93,12 +93,14 @@ BVHBuild::BVHBuild(const vector<Object*>& objects_,
|
||||
array<int>& prim_type_,
|
||||
array<int>& prim_index_,
|
||||
array<int>& prim_object_,
|
||||
array<float2>& prim_time_,
|
||||
const BVHParams& params_,
|
||||
Progress& progress_)
|
||||
: objects(objects_),
|
||||
prim_type(prim_type_),
|
||||
prim_index(prim_index_),
|
||||
prim_object(prim_object_),
|
||||
prim_time(prim_time_),
|
||||
params(params_),
|
||||
progress(progress_),
|
||||
progress_start_time(0.0),
|
||||
@@ -465,6 +467,9 @@ BVHNode* BVHBuild::run()
|
||||
}
|
||||
spatial_free_index = 0;
|
||||
|
||||
need_prim_time = params.num_motion_curve_steps > 0 ||
|
||||
params.num_motion_triangle_steps > 0;
|
||||
|
||||
/* init progress updates */
|
||||
double build_start_time;
|
||||
build_start_time = progress_start_time = time_dt();
|
||||
@@ -475,6 +480,12 @@ BVHNode* BVHBuild::run()
|
||||
prim_type.resize(references.size());
|
||||
prim_index.resize(references.size());
|
||||
prim_object.resize(references.size());
|
||||
if(need_prim_time) {
|
||||
prim_time.resize(references.size());
|
||||
}
|
||||
else {
|
||||
prim_time.resize(0);
|
||||
}
|
||||
|
||||
/* build recursively */
|
||||
BVHNode *rootnode;
|
||||
@@ -849,6 +860,9 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
|
||||
prim_type[start] = ref->prim_type();
|
||||
prim_index[start] = ref->prim_index();
|
||||
prim_object[start] = ref->prim_object();
|
||||
if(need_prim_time) {
|
||||
prim_time[start] = make_float2(ref->time_from(), ref->time_to());
|
||||
}
|
||||
|
||||
uint visibility = objects[ref->prim_object()]->visibility;
|
||||
BVHNode *leaf_node = new LeafNode(ref->bounds(), visibility, start, start+1);
|
||||
@@ -891,11 +905,13 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
|
||||
* can not control.
|
||||
*/
|
||||
typedef StackAllocator<256, int> LeafStackAllocator;
|
||||
typedef StackAllocator<256, float2> LeafTimeStackAllocator;
|
||||
typedef StackAllocator<256, BVHReference> LeafReferenceStackAllocator;
|
||||
|
||||
vector<int, LeafStackAllocator> p_type[PRIMITIVE_NUM_TOTAL];
|
||||
vector<int, LeafStackAllocator> p_index[PRIMITIVE_NUM_TOTAL];
|
||||
vector<int, LeafStackAllocator> p_object[PRIMITIVE_NUM_TOTAL];
|
||||
vector<float2, LeafTimeStackAllocator> p_time[PRIMITIVE_NUM_TOTAL];
|
||||
vector<BVHReference, LeafReferenceStackAllocator> p_ref[PRIMITIVE_NUM_TOTAL];
|
||||
|
||||
/* TODO(sergey): In theory we should be able to store references. */
|
||||
@@ -918,6 +934,8 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
|
||||
p_type[type_index].push_back(ref.prim_type());
|
||||
p_index[type_index].push_back(ref.prim_index());
|
||||
p_object[type_index].push_back(ref.prim_object());
|
||||
p_time[type_index].push_back(make_float2(ref.time_from(),
|
||||
ref.time_to()));
|
||||
|
||||
bounds[type_index].grow(ref.bounds());
|
||||
visibility[type_index] |= objects[ref.prim_object()]->visibility;
|
||||
@@ -947,9 +965,13 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
|
||||
vector<int, LeafStackAllocator> local_prim_type,
|
||||
local_prim_index,
|
||||
local_prim_object;
|
||||
vector<float2, LeafTimeStackAllocator> local_prim_time;
|
||||
local_prim_type.resize(num_new_prims);
|
||||
local_prim_index.resize(num_new_prims);
|
||||
local_prim_object.resize(num_new_prims);
|
||||
if(need_prim_time) {
|
||||
local_prim_time.resize(num_new_prims);
|
||||
}
|
||||
for(int i = 0; i < PRIMITIVE_NUM_TOTAL; ++i) {
|
||||
int num = (int)p_type[i].size();
|
||||
if(num != 0) {
|
||||
@@ -962,6 +984,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
|
||||
local_prim_type[index] = p_type[i][j];
|
||||
local_prim_index[index] = p_index[i][j];
|
||||
local_prim_object[index] = p_object[i][j];
|
||||
if(need_prim_time) {
|
||||
local_prim_time[index] = p_time[i][j];
|
||||
}
|
||||
if(params.use_unaligned_nodes && !alignment_found) {
|
||||
alignment_found =
|
||||
unaligned_heuristic.compute_aligned_space(p_ref[i][j],
|
||||
@@ -1028,11 +1053,17 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
|
||||
prim_type.reserve(reserve);
|
||||
prim_index.reserve(reserve);
|
||||
prim_object.reserve(reserve);
|
||||
if(need_prim_time) {
|
||||
prim_time.reserve(reserve);
|
||||
}
|
||||
}
|
||||
|
||||
prim_type.resize(range_end);
|
||||
prim_index.resize(range_end);
|
||||
prim_object.resize(range_end);
|
||||
if(need_prim_time) {
|
||||
prim_time.resize(range_end);
|
||||
}
|
||||
}
|
||||
spatial_spin_lock.unlock();
|
||||
|
||||
@@ -1041,6 +1072,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
|
||||
memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
|
||||
memcpy(&prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
|
||||
memcpy(&prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
|
||||
if(need_prim_time) {
|
||||
memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1053,6 +1087,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
|
||||
memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
|
||||
memcpy(&prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
|
||||
memcpy(&prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
|
||||
if(need_prim_time) {
|
||||
memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -48,6 +48,7 @@ public:
|
||||
array<int>& prim_type,
|
||||
array<int>& prim_index,
|
||||
array<int>& prim_object,
|
||||
array<float2>& prim_time,
|
||||
const BVHParams& params,
|
||||
Progress& progress);
|
||||
~BVHBuild();
|
||||
@@ -112,6 +113,9 @@ protected:
|
||||
array<int>& prim_type;
|
||||
array<int>& prim_index;
|
||||
array<int>& prim_object;
|
||||
array<float2>& prim_time;
|
||||
|
||||
bool need_prim_time;
|
||||
|
||||
/* Build parameters. */
|
||||
BVHParams params;
|
||||
|
@@ -104,6 +104,7 @@ public:
|
||||
primitive_mask = PRIMITIVE_ALL;
|
||||
|
||||
num_motion_curve_steps = 0;
|
||||
num_motion_triangle_steps = 0;
|
||||
}
|
||||
|
||||
/* SAH costs */
|
||||
|
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <climits>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@@ -162,6 +162,7 @@ public:
|
||||
void mem_free(device_memory& mem)
|
||||
{
|
||||
device_ptr tmp = mem.device_pointer;
|
||||
stats.mem_free(mem.device_size);
|
||||
|
||||
foreach(SubDevice& sub, devices) {
|
||||
mem.device_pointer = sub.ptr_map[tmp];
|
||||
@@ -170,7 +171,6 @@ public:
|
||||
}
|
||||
|
||||
mem.device_pointer = 0;
|
||||
stats.mem_free(mem.device_size);
|
||||
}
|
||||
|
||||
void const_copy_to(const char *name, void *host, size_t size)
|
||||
@@ -202,6 +202,7 @@ public:
|
||||
void tex_free(device_memory& mem)
|
||||
{
|
||||
device_ptr tmp = mem.device_pointer;
|
||||
stats.mem_free(mem.device_size);
|
||||
|
||||
foreach(SubDevice& sub, devices) {
|
||||
mem.device_pointer = sub.ptr_map[tmp];
|
||||
@@ -210,7 +211,6 @@ public:
|
||||
}
|
||||
|
||||
mem.device_pointer = 0;
|
||||
stats.mem_free(mem.device_size);
|
||||
}
|
||||
|
||||
void pixels_alloc(device_memory& mem)
|
||||
|
@@ -309,6 +309,8 @@ bool OpenCLDeviceBase::OpenCLProgram::build_kernel(const string *debug_src)
|
||||
string build_options;
|
||||
build_options = device->kernel_build_options(debug_src) + kernel_build_options;
|
||||
|
||||
VLOG(1) << "Build options passed to clBuildProgram: '"
|
||||
<< build_options << "'.";
|
||||
cl_int ciErr = clBuildProgram(program, 0, NULL, build_options.c_str(), NULL, NULL);
|
||||
|
||||
/* show warnings even if build is successful */
|
||||
|
@@ -357,7 +357,7 @@ ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__SHADOW_RECORD_ALL__) || defined (__VOLUME_RECORD_ALL__)
|
||||
#if defined(__VOLUME_RECORD_ALL__) || (defined(__SHADOW_RECORD_ALL__) && defined(__KERNEL_CPU__))
|
||||
/* ToDo: Move to another file? */
|
||||
ccl_device int intersections_compare(const void *a, const void *b)
|
||||
{
|
||||
@@ -373,5 +373,28 @@ ccl_device int intersections_compare(const void *a, const void *b)
|
||||
}
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
#if defined(__SHADOW_RECORD_ALL__)
|
||||
ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits)
|
||||
{
|
||||
#ifdef __KERNEL_GPU__
|
||||
/* Use bubble sort which has more friendly memory pattern on GPU. */
|
||||
bool swapped;
|
||||
do {
|
||||
swapped = false;
|
||||
for(int j = 0; j < num_hits - 1; ++j) {
|
||||
if(hits[j].t > hits[j + 1].t) {
|
||||
struct Intersection tmp = hits[j];
|
||||
hits[j] = hits[j + 1];
|
||||
hits[j + 1] = tmp;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
--num_hits;
|
||||
} while(swapped);
|
||||
#else
|
||||
qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
|
||||
#endif
|
||||
}
|
||||
#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -229,6 +229,15 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
|
||||
float3 P, float3 dir, uint visibility, int object, int curveAddr, float time,int type, uint *lcg_state, float difl, float extmax)
|
||||
#endif
|
||||
{
|
||||
const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
|
||||
|
||||
if(!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
|
||||
const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
|
||||
if(time < prim_time.x || time > prim_time.y) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int segment = PRIMITIVE_UNPACK_SEGMENT(type);
|
||||
float epsilon = 0.0f;
|
||||
float r_st, r_en;
|
||||
@@ -257,7 +266,7 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
|
||||
|
||||
#ifdef __KERNEL_AVX2__
|
||||
avxf P_curve_0_1, P_curve_2_3;
|
||||
if(type & PRIMITIVE_CURVE) {
|
||||
if(is_curve_primitive) {
|
||||
P_curve_0_1 = _mm256_loadu2_m128(&kg->__curve_keys.data[k0].x, &kg->__curve_keys.data[ka].x);
|
||||
P_curve_2_3 = _mm256_loadu2_m128(&kg->__curve_keys.data[kb].x, &kg->__curve_keys.data[k1].x);
|
||||
}
|
||||
@@ -268,7 +277,7 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
|
||||
#else /* __KERNEL_AVX2__ */
|
||||
ssef P_curve[4];
|
||||
|
||||
if(type & PRIMITIVE_CURVE) {
|
||||
if(is_curve_primitive) {
|
||||
P_curve[0] = load4f(&kg->__curve_keys.data[ka].x);
|
||||
P_curve[1] = load4f(&kg->__curve_keys.data[k0].x);
|
||||
P_curve[2] = load4f(&kg->__curve_keys.data[k1].x);
|
||||
@@ -363,7 +372,7 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
|
||||
|
||||
float4 P_curve[4];
|
||||
|
||||
if(type & PRIMITIVE_CURVE) {
|
||||
if(is_curve_primitive) {
|
||||
P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
|
||||
P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
|
||||
P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
|
||||
@@ -689,6 +698,15 @@ ccl_device_forceinline bool bvh_curve_intersect(KernelGlobals *kg, Intersection
|
||||
# define dot3(x, y) dot(x, y)
|
||||
#endif
|
||||
|
||||
const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
|
||||
|
||||
if(!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
|
||||
const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
|
||||
if(time < prim_time.x || time > prim_time.y) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int segment = PRIMITIVE_UNPACK_SEGMENT(type);
|
||||
/* curve Intersection check */
|
||||
int flags = kernel_data.curve.curveflags;
|
||||
@@ -703,7 +721,7 @@ ccl_device_forceinline bool bvh_curve_intersect(KernelGlobals *kg, Intersection
|
||||
#ifndef __KERNEL_SSE2__
|
||||
float4 P_curve[2];
|
||||
|
||||
if(type & PRIMITIVE_CURVE) {
|
||||
if(is_curve_primitive) {
|
||||
P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
|
||||
P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
|
||||
}
|
||||
@@ -738,7 +756,7 @@ ccl_device_forceinline bool bvh_curve_intersect(KernelGlobals *kg, Intersection
|
||||
#else
|
||||
ssef P_curve[2];
|
||||
|
||||
if(type & PRIMITIVE_CURVE) {
|
||||
if(is_curve_primitive) {
|
||||
P_curve[0] = load4f(&kg->__curve_keys.data[k0].x);
|
||||
P_curve[1] = load4f(&kg->__curve_keys.data[k1].x);
|
||||
}
|
||||
|
@@ -54,7 +54,8 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
|
||||
float rbsdf = path_state_rng_1D(kg, &rng, &state, PRNG_BSDF);
|
||||
shader_eval_surface(kg, sd, &rng, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
|
||||
|
||||
/* TODO, disable the closures we won't need */
|
||||
/* TODO, disable more closures we don't need besides transparent */
|
||||
shader_bsdf_disable_transparency(kg, sd);
|
||||
|
||||
#ifdef __BRANCHED_PATH__
|
||||
if(!kernel_data.integrator.branched) {
|
||||
|
@@ -76,7 +76,10 @@ typedef struct KernelGlobals {
|
||||
#ifdef __KERNEL_CUDA__
|
||||
|
||||
__constant__ KernelData __data;
|
||||
typedef struct KernelGlobals {} KernelGlobals;
|
||||
typedef struct KernelGlobals {
|
||||
/* NOTE: Keep the size in sync with SHADOW_STACK_MAX_HITS. */
|
||||
Intersection hits_stack[64];
|
||||
} KernelGlobals;
|
||||
|
||||
# ifdef __KERNEL_CUDA_TEX_STORAGE__
|
||||
# define KERNEL_TEX(type, ttype, name) ttype name;
|
||||
|
@@ -109,6 +109,10 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
|
||||
/* intersect scene */
|
||||
Intersection isect;
|
||||
uint visibility = path_state_ray_visibility(kg, state);
|
||||
if(state->bounce > kernel_data.integrator.ao_bounces) {
|
||||
visibility = PATH_RAY_SHADOW;
|
||||
ray->t = kernel_data.background.ao_distance;
|
||||
}
|
||||
bool hit = scene_intersect(kg,
|
||||
*ray,
|
||||
visibility,
|
||||
@@ -292,6 +296,9 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
|
||||
|
||||
break;
|
||||
}
|
||||
else if(state->bounce > kernel_data.integrator.ao_bounces) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* setup shading */
|
||||
shader_setup_from_ray(kg,
|
||||
@@ -627,6 +634,11 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg,
|
||||
lcg_state = lcg_state_init(rng, &state, 0x51633e2d);
|
||||
}
|
||||
|
||||
if(state.bounce > kernel_data.integrator.ao_bounces) {
|
||||
visibility = PATH_RAY_SHADOW;
|
||||
ray.t = kernel_data.background.ao_distance;
|
||||
}
|
||||
|
||||
bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax);
|
||||
#else
|
||||
bool hit = scene_intersect(kg, ray, visibility, &isect, NULL, 0.0f, 0.0f);
|
||||
@@ -769,6 +781,9 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg,
|
||||
|
||||
break;
|
||||
}
|
||||
else if(state.bounce > kernel_data.integrator.ao_bounces) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* setup shading */
|
||||
shader_setup_from_ray(kg, &sd, &isect, &ray);
|
||||
|
@@ -30,7 +30,7 @@ ccl_device_inline void kernel_path_trace_setup(KernelGlobals *kg,
|
||||
|
||||
int num_samples = kernel_data.integrator.aa_samples;
|
||||
|
||||
if(sample == 0) {
|
||||
if(sample == kernel_data.integrator.start_sample) {
|
||||
*rng_state = hash_int_2d(x, y);
|
||||
}
|
||||
|
||||
|
@@ -685,6 +685,18 @@ ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
|
||||
return eval;
|
||||
}
|
||||
|
||||
ccl_device void shader_bsdf_disable_transparency(KernelGlobals *kg, ShaderData *sd)
|
||||
{
|
||||
for(int i = 0; i < ccl_fetch(sd, num_closure); i++) {
|
||||
ShaderClosure *sc = ccl_fetch_array(sd, closure, i);
|
||||
|
||||
if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) {
|
||||
sc->sample_weight = 0.0f;
|
||||
sc->weight = make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float3 shader_bsdf_alpha(KernelGlobals *kg, ShaderData *sd)
|
||||
{
|
||||
float3 alpha = make_float3(1.0f, 1.0f, 1.0f) - shader_bsdf_transparency(kg, sd);
|
||||
|
@@ -16,9 +16,84 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
#ifdef __SHADOW_RECORD_ALL__
|
||||
/* Attenuate throughput accordingly to the given intersection event.
|
||||
* Returns true if the throughput is zero and traversal can be aborted.
|
||||
*/
|
||||
ccl_device_forceinline bool shadow_handle_transparent_isect(
|
||||
KernelGlobals *kg,
|
||||
ShaderData *shadow_sd,
|
||||
ccl_addr_space PathState *state,
|
||||
# ifdef __VOLUME__
|
||||
struct PathState *volume_state,
|
||||
# endif
|
||||
Intersection *isect,
|
||||
Ray *ray,
|
||||
float3 *throughput)
|
||||
{
|
||||
#ifdef __VOLUME__
|
||||
/* Attenuation between last surface and next surface. */
|
||||
if(volume_state->volume_stack[0].shader != SHADER_NONE) {
|
||||
Ray segment_ray = *ray;
|
||||
segment_ray.t = isect->t;
|
||||
kernel_volume_shadow(kg,
|
||||
shadow_sd,
|
||||
volume_state,
|
||||
&segment_ray,
|
||||
throughput);
|
||||
}
|
||||
#endif
|
||||
/* Setup shader data at surface. */
|
||||
shader_setup_from_ray(kg, shadow_sd, isect, ray);
|
||||
/* Attenuation from transparent surface. */
|
||||
if(!(ccl_fetch(shadow_sd, flag) & SD_HAS_ONLY_VOLUME)) {
|
||||
path_state_modify_bounce(state, true);
|
||||
shader_eval_surface(kg,
|
||||
shadow_sd,
|
||||
NULL,
|
||||
state,
|
||||
0.0f,
|
||||
PATH_RAY_SHADOW,
|
||||
SHADER_CONTEXT_SHADOW);
|
||||
path_state_modify_bounce(state, false);
|
||||
*throughput *= shader_bsdf_transparency(kg, shadow_sd);
|
||||
}
|
||||
/* Stop if all light is blocked. */
|
||||
if(is_zero(*throughput)) {
|
||||
return true;
|
||||
}
|
||||
#ifdef __VOLUME__
|
||||
/* Exit/enter volume. */
|
||||
kernel_volume_stack_enter_exit(kg, shadow_sd, volume_state->volume_stack);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Shadow function to compute how much light is blocked, CPU variation.
|
||||
/* Special version which only handles opaque shadows. */
|
||||
ccl_device bool shadow_blocked_opaque(KernelGlobals *kg,
|
||||
ShaderData *shadow_sd,
|
||||
ccl_addr_space PathState *state,
|
||||
Ray *ray,
|
||||
Intersection *isect,
|
||||
float3 *shadow)
|
||||
{
|
||||
const bool blocked = scene_intersect(kg,
|
||||
*ray,
|
||||
PATH_RAY_SHADOW_OPAQUE,
|
||||
isect,
|
||||
NULL,
|
||||
0.0f, 0.0f);
|
||||
#ifdef __VOLUME__
|
||||
if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
|
||||
/* Apply attenuation from current volume shader. */
|
||||
kernel_volume_shadow(kg, shadow_sd, state, ray, shadow);
|
||||
}
|
||||
#endif
|
||||
return blocked;
|
||||
}
|
||||
|
||||
#ifdef __TRANSPARENT_SHADOWS__
|
||||
# ifdef __SHADOW_RECORD_ALL__
|
||||
/* Shadow function to compute how much light is blocked,
|
||||
*
|
||||
* We trace a single ray. If it hits any opaque surface, or more than a given
|
||||
* number of transparent surfaces is hit, then we consider the geometry to be
|
||||
@@ -36,261 +111,355 @@ CCL_NAMESPACE_BEGIN
|
||||
* or there is a performance increase anyway due to avoiding the need to send
|
||||
* two rays with transparent shadows.
|
||||
*
|
||||
* This is CPU only because of qsort, and malloc or high stack space usage to
|
||||
* record all these intersections. */
|
||||
* On CPU it'll handle all transparent bounces (by allocating storage for
|
||||
* intersections when they don't fit into the stack storage).
|
||||
*
|
||||
* On GPU it'll only handle SHADOW_STACK_MAX_HITS-1 intersections, so this
|
||||
* is something to be kept an eye on.
|
||||
*/
|
||||
|
||||
#define STACK_MAX_HITS 64
|
||||
# define SHADOW_STACK_MAX_HITS 64
|
||||
|
||||
ccl_device_inline bool shadow_blocked(KernelGlobals *kg, ShaderData *shadow_sd, PathState *state, Ray *ray, float3 *shadow)
|
||||
/* Actual logic with traversal loop implementation which is free from device
|
||||
* specific tweaks.
|
||||
*
|
||||
* Note that hits array should be as big as max_hits+1.
|
||||
*/
|
||||
ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
|
||||
ShaderData *shadow_sd,
|
||||
ccl_addr_space PathState *state,
|
||||
Ray *ray,
|
||||
Intersection *hits,
|
||||
uint max_hits,
|
||||
float3 *shadow)
|
||||
{
|
||||
*shadow = make_float3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
if(ray->t == 0.0f)
|
||||
return false;
|
||||
|
||||
bool blocked;
|
||||
|
||||
if(kernel_data.integrator.transparent_shadows) {
|
||||
/* check transparent bounces here, for volume scatter which can do
|
||||
* lighting before surface path termination is checked */
|
||||
if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce)
|
||||
return true;
|
||||
|
||||
/* intersect to find an opaque surface, or record all transparent surface hits */
|
||||
Intersection hits_stack[STACK_MAX_HITS];
|
||||
Intersection *hits = hits_stack;
|
||||
const int transparent_max_bounce = kernel_data.integrator.transparent_max_bounce;
|
||||
uint max_hits = transparent_max_bounce - state->transparent_bounce - 1;
|
||||
|
||||
/* prefer to use stack but use dynamic allocation if too deep max hits
|
||||
* we need max_hits + 1 storage space due to the logic in
|
||||
* scene_intersect_shadow_all which will first store and then check if
|
||||
* the limit is exceeded */
|
||||
if(max_hits + 1 > STACK_MAX_HITS) {
|
||||
if(kg->transparent_shadow_intersections == NULL) {
|
||||
kg->transparent_shadow_intersections =
|
||||
(Intersection*)malloc(sizeof(Intersection)*(transparent_max_bounce + 1));
|
||||
/* Intersect to find an opaque surface, or record all transparent
|
||||
* surface hits.
|
||||
*/
|
||||
uint num_hits;
|
||||
const bool blocked = scene_intersect_shadow_all(kg,
|
||||
ray,
|
||||
hits,
|
||||
max_hits,
|
||||
&num_hits);
|
||||
/* If no opaque surface found but we did find transparent hits,
|
||||
* shade them.
|
||||
*/
|
||||
if(!blocked && num_hits > 0) {
|
||||
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
|
||||
float3 Pend = ray->P + ray->D*ray->t;
|
||||
float last_t = 0.0f;
|
||||
int bounce = state->transparent_bounce;
|
||||
Intersection *isect = hits;
|
||||
# ifdef __VOLUME__
|
||||
PathState ps = *state;
|
||||
# endif
|
||||
sort_intersections(hits, num_hits);
|
||||
for(int hit = 0; hit < num_hits; hit++, isect++) {
|
||||
/* Adjust intersection distance for moving ray forward. */
|
||||
float new_t = isect->t;
|
||||
isect->t -= last_t;
|
||||
/* Skip hit if we did not move forward, step by step raytracing
|
||||
* would have skipped it as well then.
|
||||
*/
|
||||
if(last_t == new_t) {
|
||||
continue;
|
||||
}
|
||||
hits = kg->transparent_shadow_intersections;
|
||||
}
|
||||
|
||||
uint num_hits;
|
||||
blocked = scene_intersect_shadow_all(kg, ray, hits, max_hits, &num_hits);
|
||||
|
||||
/* if no opaque surface found but we did find transparent hits, shade them */
|
||||
if(!blocked && num_hits > 0) {
|
||||
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
|
||||
float3 Pend = ray->P + ray->D*ray->t;
|
||||
float last_t = 0.0f;
|
||||
int bounce = state->transparent_bounce;
|
||||
Intersection *isect = hits;
|
||||
last_t = new_t;
|
||||
/* Attenuate the throughput. */
|
||||
if(shadow_handle_transparent_isect(kg,
|
||||
shadow_sd,
|
||||
state,
|
||||
#ifdef __VOLUME__
|
||||
PathState ps = *state;
|
||||
&ps,
|
||||
#endif
|
||||
|
||||
qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
|
||||
|
||||
for(int hit = 0; hit < num_hits; hit++, isect++) {
|
||||
/* adjust intersection distance for moving ray forward */
|
||||
float new_t = isect->t;
|
||||
isect->t -= last_t;
|
||||
|
||||
/* skip hit if we did not move forward, step by step raytracing
|
||||
* would have skipped it as well then */
|
||||
if(last_t == new_t)
|
||||
continue;
|
||||
|
||||
last_t = new_t;
|
||||
|
||||
#ifdef __VOLUME__
|
||||
/* attenuation between last surface and next surface */
|
||||
if(ps.volume_stack[0].shader != SHADER_NONE) {
|
||||
Ray segment_ray = *ray;
|
||||
segment_ray.t = isect->t;
|
||||
kernel_volume_shadow(kg, shadow_sd, &ps, &segment_ray, &throughput);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* setup shader data at surface */
|
||||
shader_setup_from_ray(kg, shadow_sd, isect, ray);
|
||||
|
||||
/* attenuation from transparent surface */
|
||||
if(!(shadow_sd->flag & SD_HAS_ONLY_VOLUME)) {
|
||||
path_state_modify_bounce(state, true);
|
||||
shader_eval_surface(kg, shadow_sd, NULL, state, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW);
|
||||
path_state_modify_bounce(state, false);
|
||||
|
||||
throughput *= shader_bsdf_transparency(kg, shadow_sd);
|
||||
}
|
||||
|
||||
/* stop if all light is blocked */
|
||||
if(is_zero(throughput)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* move ray forward */
|
||||
ray->P = shadow_sd->P;
|
||||
if(ray->t != FLT_MAX) {
|
||||
ray->D = normalize_len(Pend - ray->P, &ray->t);
|
||||
}
|
||||
|
||||
#ifdef __VOLUME__
|
||||
/* exit/enter volume */
|
||||
kernel_volume_stack_enter_exit(kg, shadow_sd, ps.volume_stack);
|
||||
#endif
|
||||
|
||||
bounce++;
|
||||
isect,
|
||||
ray,
|
||||
&throughput))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef __VOLUME__
|
||||
/* attenuation for last line segment towards light */
|
||||
if(ps.volume_stack[0].shader != SHADER_NONE)
|
||||
kernel_volume_shadow(kg, shadow_sd, &ps, ray, &throughput);
|
||||
#endif
|
||||
|
||||
*shadow = throughput;
|
||||
|
||||
return is_zero(throughput);
|
||||
/* Move ray forward. */
|
||||
ray->P = ccl_fetch(shadow_sd, P);
|
||||
if(ray->t != FLT_MAX) {
|
||||
ray->D = normalize_len(Pend - ray->P, &ray->t);
|
||||
}
|
||||
bounce++;
|
||||
}
|
||||
# ifdef __VOLUME__
|
||||
/* Attenuation for last line segment towards light. */
|
||||
if(ps.volume_stack[0].shader != SHADER_NONE) {
|
||||
kernel_volume_shadow(kg, shadow_sd, &ps, ray, &throughput);
|
||||
}
|
||||
# endif
|
||||
*shadow = throughput;
|
||||
return is_zero(throughput);
|
||||
}
|
||||
else {
|
||||
Intersection isect;
|
||||
blocked = scene_intersect(kg, *ray, PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
#ifdef __VOLUME__
|
||||
# ifdef __VOLUME__
|
||||
if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
|
||||
/* apply attenuation from current volume shader */
|
||||
/* Apply attenuation from current volume shader/ */
|
||||
kernel_volume_shadow(kg, shadow_sd, state, ray, shadow);
|
||||
}
|
||||
#endif
|
||||
|
||||
# endif
|
||||
return blocked;
|
||||
}
|
||||
|
||||
#undef STACK_MAX_HITS
|
||||
/* Here we do all device specific trickery before invoking actual traversal
|
||||
* loop to help readability of the actual logic.
|
||||
*/
|
||||
ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
|
||||
ShaderData *shadow_sd,
|
||||
ccl_addr_space PathState *state,
|
||||
Ray *ray,
|
||||
uint max_hits,
|
||||
float3 *shadow)
|
||||
{
|
||||
# ifdef __KERNEL_CUDA__
|
||||
Intersection *hits = kg->hits_stack;
|
||||
# else
|
||||
Intersection hits_stack[SHADOW_STACK_MAX_HITS];
|
||||
Intersection *hits = hits_stack;
|
||||
# endif
|
||||
# ifndef __KERNEL_GPU__
|
||||
/* Prefer to use stack but use dynamic allocation if too deep max hits
|
||||
* we need max_hits + 1 storage space due to the logic in
|
||||
* scene_intersect_shadow_all which will first store and then check if
|
||||
* the limit is exceeded.
|
||||
*
|
||||
* Ignore this on GPU because of slow/unavailable malloc().
|
||||
*/
|
||||
if(max_hits + 1 > SHADOW_STACK_MAX_HITS) {
|
||||
if(kg->transparent_shadow_intersections == NULL) {
|
||||
const int transparent_max_bounce = kernel_data.integrator.transparent_max_bounce;
|
||||
kg->transparent_shadow_intersections =
|
||||
(Intersection*)malloc(sizeof(Intersection)*(transparent_max_bounce + 1));
|
||||
}
|
||||
hits = kg->transparent_shadow_intersections;
|
||||
}
|
||||
# endif /* __KERNEL_GPU__ */
|
||||
/* Invoke actual traversal. */
|
||||
return shadow_blocked_transparent_all_loop(kg,
|
||||
shadow_sd,
|
||||
state,
|
||||
ray,
|
||||
hits,
|
||||
max_hits,
|
||||
shadow);
|
||||
}
|
||||
# endif /* __SHADOW_RECORD_ALL__ */
|
||||
|
||||
#else
|
||||
|
||||
/* Shadow function to compute how much light is blocked, GPU variation.
|
||||
# ifdef __KERNEL_GPU__
|
||||
/* Shadow function to compute how much light is blocked,
|
||||
*
|
||||
* Here we raytrace from one transparent surface to the next step by step.
|
||||
* To minimize overhead in cases where we don't need transparent shadows, we
|
||||
* first trace a regular shadow ray. We check if the hit primitive was
|
||||
* potentially transparent, and only in that case start marching. this gives
|
||||
* one extra ray cast for the cases were we do want transparency. */
|
||||
* one extra ray cast for the cases were we do want transparency.
|
||||
*/
|
||||
|
||||
ccl_device_noinline bool shadow_blocked(KernelGlobals *kg,
|
||||
ShaderData *shadow_sd,
|
||||
ccl_addr_space PathState *state,
|
||||
ccl_addr_space Ray *ray_input,
|
||||
float3 *shadow)
|
||||
/* This function is only implementing device-independent traversal logic
|
||||
* which requires some precalculation done.
|
||||
*/
|
||||
ccl_device bool shadow_blocked_transparent_stepped_loop(
|
||||
KernelGlobals *kg,
|
||||
ShaderData *shadow_sd,
|
||||
ccl_addr_space PathState *state,
|
||||
Ray *ray,
|
||||
Intersection *isect,
|
||||
const bool blocked,
|
||||
const bool is_transparent_isect,
|
||||
float3 *shadow)
|
||||
{
|
||||
*shadow = make_float3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
if(ray_input->t == 0.0f)
|
||||
return false;
|
||||
|
||||
#ifdef __SPLIT_KERNEL__
|
||||
Ray private_ray = *ray_input;
|
||||
Ray *ray = &private_ray;
|
||||
#else
|
||||
Ray *ray = ray_input;
|
||||
#endif
|
||||
|
||||
#ifdef __SPLIT_KERNEL__
|
||||
Intersection *isect = &kg->isect_shadow[SD_THREAD];
|
||||
#else
|
||||
Intersection isect_object;
|
||||
Intersection *isect = &isect_object;
|
||||
#endif
|
||||
|
||||
bool blocked = scene_intersect(kg, *ray, PATH_RAY_SHADOW_OPAQUE, isect, NULL, 0.0f, 0.0f);
|
||||
|
||||
#ifdef __TRANSPARENT_SHADOWS__
|
||||
if(blocked && kernel_data.integrator.transparent_shadows) {
|
||||
if(shader_transparent_shadow(kg, isect)) {
|
||||
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
|
||||
float3 Pend = ray->P + ray->D*ray->t;
|
||||
int bounce = state->transparent_bounce;
|
||||
#ifdef __VOLUME__
|
||||
PathState ps = *state;
|
||||
#endif
|
||||
|
||||
for(;;) {
|
||||
if(bounce >= kernel_data.integrator.transparent_max_bounce)
|
||||
return true;
|
||||
|
||||
if(!scene_intersect(kg, *ray, PATH_RAY_SHADOW_TRANSPARENT, isect, NULL, 0.0f, 0.0f))
|
||||
{
|
||||
#ifdef __VOLUME__
|
||||
/* attenuation for last line segment towards light */
|
||||
if(ps.volume_stack[0].shader != SHADER_NONE)
|
||||
kernel_volume_shadow(kg, shadow_sd, &ps, ray, &throughput);
|
||||
#endif
|
||||
|
||||
*shadow *= throughput;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!shader_transparent_shadow(kg, isect)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef __VOLUME__
|
||||
/* attenuation between last surface and next surface */
|
||||
if(ps.volume_stack[0].shader != SHADER_NONE) {
|
||||
Ray segment_ray = *ray;
|
||||
segment_ray.t = isect->t;
|
||||
kernel_volume_shadow(kg, shadow_sd, &ps, &segment_ray, &throughput);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* setup shader data at surface */
|
||||
shader_setup_from_ray(kg, shadow_sd, isect, ray);
|
||||
|
||||
/* attenuation from transparent surface */
|
||||
if(!(ccl_fetch(shadow_sd, flag) & SD_HAS_ONLY_VOLUME)) {
|
||||
path_state_modify_bounce(state, true);
|
||||
shader_eval_surface(kg, shadow_sd, NULL, state, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW);
|
||||
path_state_modify_bounce(state, false);
|
||||
|
||||
throughput *= shader_bsdf_transparency(kg, shadow_sd);
|
||||
}
|
||||
|
||||
/* stop if all light is blocked */
|
||||
if(is_zero(throughput)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* move ray forward */
|
||||
ray->P = ray_offset(ccl_fetch(shadow_sd, P), -ccl_fetch(shadow_sd, Ng));
|
||||
if(ray->t != FLT_MAX) {
|
||||
ray->D = normalize_len(Pend - ray->P, &ray->t);
|
||||
}
|
||||
|
||||
#ifdef __VOLUME__
|
||||
/* exit/enter volume */
|
||||
kernel_volume_stack_enter_exit(kg, shadow_sd, ps.volume_stack);
|
||||
#endif
|
||||
|
||||
bounce++;
|
||||
if(blocked && is_transparent_isect) {
|
||||
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
|
||||
float3 Pend = ray->P + ray->D*ray->t;
|
||||
int bounce = state->transparent_bounce;
|
||||
# ifdef __VOLUME__
|
||||
PathState ps = *state;
|
||||
# endif
|
||||
for(;;) {
|
||||
if(bounce >= kernel_data.integrator.transparent_max_bounce) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!scene_intersect(kg,
|
||||
*ray,
|
||||
PATH_RAY_SHADOW_TRANSPARENT,
|
||||
isect,
|
||||
NULL,
|
||||
0.0f, 0.0f))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(!shader_transparent_shadow(kg, isect)) {
|
||||
return true;
|
||||
}
|
||||
/* Attenuate the throughput. */
|
||||
if(shadow_handle_transparent_isect(kg,
|
||||
shadow_sd,
|
||||
state,
|
||||
#ifdef __VOLUME__
|
||||
else if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
|
||||
/* apply attenuation from current volume shader */
|
||||
&ps,
|
||||
#endif
|
||||
isect,
|
||||
ray,
|
||||
&throughput))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/* Move ray forward. */
|
||||
ray->P = ray_offset(ccl_fetch(shadow_sd, P), -ccl_fetch(shadow_sd, Ng));
|
||||
if(ray->t != FLT_MAX) {
|
||||
ray->D = normalize_len(Pend - ray->P, &ray->t);
|
||||
}
|
||||
bounce++;
|
||||
}
|
||||
# ifdef __VOLUME__
|
||||
/* Attenuation for last line segment towards light. */
|
||||
if(ps.volume_stack[0].shader != SHADER_NONE) {
|
||||
kernel_volume_shadow(kg, shadow_sd, &ps, ray, &throughput);
|
||||
}
|
||||
# endif
|
||||
*shadow *= throughput;
|
||||
return is_zero(throughput);
|
||||
}
|
||||
# ifdef __VOLUME__
|
||||
if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
|
||||
/* Apply attenuation from current volume shader. */
|
||||
kernel_volume_shadow(kg, shadow_sd, state, ray, shadow);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
# endif
|
||||
return blocked;
|
||||
}
|
||||
|
||||
ccl_device bool shadow_blocked_transparent_stepped(
|
||||
KernelGlobals *kg,
|
||||
ShaderData *shadow_sd,
|
||||
ccl_addr_space PathState *state,
|
||||
Ray *ray,
|
||||
Intersection *isect,
|
||||
float3 *shadow)
|
||||
{
|
||||
const bool blocked = scene_intersect(kg,
|
||||
*ray,
|
||||
PATH_RAY_SHADOW_OPAQUE,
|
||||
isect,
|
||||
NULL,
|
||||
0.0f, 0.0f);
|
||||
const bool is_transparent_isect = blocked
|
||||
? shader_transparent_shadow(kg, isect)
|
||||
: false;
|
||||
return shadow_blocked_transparent_stepped_loop(kg,
|
||||
shadow_sd,
|
||||
state,
|
||||
ray,
|
||||
isect,
|
||||
blocked,
|
||||
is_transparent_isect,
|
||||
shadow);
|
||||
}
|
||||
|
||||
# endif /* __KERNEL_GPU__ */
|
||||
#endif /* __TRANSPARENT_SHADOWS__ */
|
||||
|
||||
ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
|
||||
ShaderData *shadow_sd,
|
||||
ccl_addr_space PathState *state,
|
||||
ccl_addr_space Ray *ray_input,
|
||||
float3 *shadow)
|
||||
{
|
||||
/* Special trickery for split kernel: some data is coming from the
|
||||
* global memory.
|
||||
*/
|
||||
#ifdef __SPLIT_KERNEL__
|
||||
Ray private_ray = *ray_input;
|
||||
Ray *ray = &private_ray;
|
||||
Intersection *isect = &kg->isect_shadow[SD_THREAD];
|
||||
#else /* __SPLIT_KERNEL__ */
|
||||
Ray *ray = ray_input;
|
||||
Intersection isect_object;
|
||||
Intersection *isect = &isect_object;
|
||||
#endif /* __SPLIT_KERNEL__ */
|
||||
/* Some common early checks. */
|
||||
*shadow = make_float3(1.0f, 1.0f, 1.0f);
|
||||
if(ray->t == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
/* Do actual shadow shading. */
|
||||
/* First of all, we check if integrator requires transparent shadows.
|
||||
* if not, we use simplest and fastest ever way to calculate occlusion.
|
||||
*/
|
||||
#ifdef __TRANSPARENT_SHADOWS__
|
||||
if(!kernel_data.integrator.transparent_shadows)
|
||||
#endif
|
||||
{
|
||||
return shadow_blocked_opaque(kg,
|
||||
shadow_sd,
|
||||
state,
|
||||
ray,
|
||||
isect,
|
||||
shadow);
|
||||
}
|
||||
#ifdef __TRANSPARENT_SHADOWS__
|
||||
# ifdef __SHADOW_RECORD_ALL__
|
||||
/* For the transparent shadows we try to use record-all logic on the
|
||||
* devices which supports this.
|
||||
*/
|
||||
const int transparent_max_bounce = kernel_data.integrator.transparent_max_bounce;
|
||||
/* Check transparent bounces here, for volume scatter which can do
|
||||
* lighting before surface path termination is checked.
|
||||
*/
|
||||
if(state->transparent_bounce >= transparent_max_bounce) {
|
||||
return true;
|
||||
}
|
||||
const uint max_hits = transparent_max_bounce - state->transparent_bounce - 1;
|
||||
# ifdef __KERNEL_GPU__
|
||||
/* On GPU we do trickey with tracing opaque ray first, this avoids speed
|
||||
* regressions in some files.
|
||||
*
|
||||
* TODO(sergey): Check why using record-all behavior causes slowdown in such
|
||||
* cases. Could that be caused by a higher spill pressure?
|
||||
*/
|
||||
const bool blocked = scene_intersect(kg,
|
||||
*ray,
|
||||
PATH_RAY_SHADOW_OPAQUE,
|
||||
isect,
|
||||
NULL,
|
||||
0.0f, 0.0f);
|
||||
const bool is_transparent_isect = blocked
|
||||
? shader_transparent_shadow(kg, isect)
|
||||
: false;
|
||||
if(!blocked || !is_transparent_isect ||
|
||||
max_hits + 1 >= SHADOW_STACK_MAX_HITS)
|
||||
{
|
||||
return shadow_blocked_transparent_stepped_loop(kg,
|
||||
shadow_sd,
|
||||
state,
|
||||
ray,
|
||||
isect,
|
||||
blocked,
|
||||
is_transparent_isect,
|
||||
shadow);
|
||||
}
|
||||
# endif /* __KERNEL_GPU__ */
|
||||
return shadow_blocked_transparent_all(kg,
|
||||
shadow_sd,
|
||||
state,
|
||||
ray,
|
||||
max_hits,
|
||||
shadow);
|
||||
# else /* __SHADOW_RECORD_ALL__ */
|
||||
/* Fallback to a slowest version which works on all devices. */
|
||||
return shadow_blocked_transparent_stepped(kg,
|
||||
shadow_sd,
|
||||
state,
|
||||
ray,
|
||||
isect,
|
||||
shadow);
|
||||
# endif /* __SHADOW_RECORD_ALL__ */
|
||||
#endif /* __TRANSPARENT_SHADOWS__ */
|
||||
}
|
||||
|
||||
#undef SHADOW_STACK_MAX_HITS
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
@@ -32,6 +32,7 @@ KERNEL_TEX(uint, texture_uint, __prim_visibility)
|
||||
KERNEL_TEX(uint, texture_uint, __prim_index)
|
||||
KERNEL_TEX(uint, texture_uint, __prim_object)
|
||||
KERNEL_TEX(uint, texture_uint, __object_node)
|
||||
KERNEL_TEX(float2, texture_float2, __prim_time)
|
||||
|
||||
/* objects */
|
||||
KERNEL_TEX(float4, texture_float4, __objects)
|
||||
@@ -177,7 +178,6 @@ KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_085)
|
||||
KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_086)
|
||||
KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_087)
|
||||
KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_088)
|
||||
KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_089)
|
||||
|
||||
# else
|
||||
/* bindless textures */
|
||||
|
@@ -84,6 +84,7 @@ CCL_NAMESPACE_BEGIN
|
||||
# define __VOLUME_SCATTER__
|
||||
# define __SUBSURFACE__
|
||||
# define __CMJ__
|
||||
# define __SHADOW_RECORD_ALL__
|
||||
#endif /* __KERNEL_CUDA__ */
|
||||
|
||||
#ifdef __KERNEL_OPENCL__
|
||||
@@ -1143,6 +1144,8 @@ typedef struct KernelIntegrator {
|
||||
int max_transmission_bounce;
|
||||
int max_volume_bounce;
|
||||
|
||||
int ao_bounces;
|
||||
|
||||
/* transparent */
|
||||
int transparent_min_bounce;
|
||||
int transparent_max_bounce;
|
||||
@@ -1186,7 +1189,8 @@ typedef struct KernelIntegrator {
|
||||
|
||||
float light_inv_rr_threshold;
|
||||
|
||||
int pad1;
|
||||
int start_sample;
|
||||
int pad1, pad2, pad3;
|
||||
} KernelIntegrator;
|
||||
static_assert_align(KernelIntegrator, 16);
|
||||
|
||||
@@ -1198,7 +1202,8 @@ typedef struct KernelBVH {
|
||||
int have_curves;
|
||||
int have_instancing;
|
||||
int use_qbvh;
|
||||
int pad1, pad2;
|
||||
int use_bvh_steps;
|
||||
int pad1;
|
||||
} KernelBVH;
|
||||
static_assert_align(KernelBVH, 16);
|
||||
|
||||
|
@@ -966,7 +966,7 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
|
||||
mis_weight = 2.0f*power_heuristic(pdf, distance_pdf);
|
||||
}
|
||||
}
|
||||
if(sample_t < 1e-6f) {
|
||||
if(sample_t < 1e-6f || pdf == 0.0f) {
|
||||
return VOLUME_PATH_SCATTERED;
|
||||
}
|
||||
|
||||
|
@@ -130,8 +130,10 @@ kernel_cuda_path_trace(float *buffer, uint *rng_state, int sample, int sx, int s
|
||||
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
|
||||
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
|
||||
|
||||
if(x < sx + sw && y < sy + sh)
|
||||
kernel_path_trace(NULL, buffer, rng_state, sample, x, y, offset, stride);
|
||||
if(x < sx + sw && y < sy + sh) {
|
||||
KernelGlobals kg;
|
||||
kernel_path_trace(&kg, buffer, rng_state, sample, x, y, offset, stride);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __BRANCHED_PATH__
|
||||
@@ -142,8 +144,10 @@ kernel_cuda_branched_path_trace(float *buffer, uint *rng_state, int sample, int
|
||||
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
|
||||
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
|
||||
|
||||
if(x < sx + sw && y < sy + sh)
|
||||
kernel_branched_path_trace(NULL, buffer, rng_state, sample, x, y, offset, stride);
|
||||
if(x < sx + sw && y < sy + sh) {
|
||||
KernelGlobals kg;
|
||||
kernel_branched_path_trace(&kg, buffer, rng_state, sample, x, y, offset, stride);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -154,8 +158,9 @@ kernel_cuda_convert_to_byte(uchar4 *rgba, float *buffer, float sample_scale, int
|
||||
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
|
||||
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
|
||||
|
||||
if(x < sx + sw && y < sy + sh)
|
||||
if(x < sx + sw && y < sy + sh) {
|
||||
kernel_film_convert_to_byte(NULL, rgba, buffer, sample_scale, x, y, offset, stride);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" __global__ void
|
||||
@@ -165,8 +170,9 @@ kernel_cuda_convert_to_half_float(uchar4 *rgba, float *buffer, float sample_scal
|
||||
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
|
||||
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
|
||||
|
||||
if(x < sx + sw && y < sy + sh)
|
||||
if(x < sx + sw && y < sy + sh) {
|
||||
kernel_film_convert_to_half_float(NULL, rgba, buffer, sample_scale, x, y, offset, stride);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" __global__ void
|
||||
@@ -183,7 +189,8 @@ kernel_cuda_shader(uint4 *input,
|
||||
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
|
||||
|
||||
if(x < sx + sw) {
|
||||
kernel_shader_evaluate(NULL,
|
||||
KernelGlobals kg;
|
||||
kernel_shader_evaluate(&kg,
|
||||
input,
|
||||
output,
|
||||
output_luma,
|
||||
@@ -200,8 +207,10 @@ kernel_cuda_bake(uint4 *input, float4 *output, int type, int filter, int sx, int
|
||||
{
|
||||
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
|
||||
|
||||
if(x < sx + sw)
|
||||
kernel_bake_evaluate(NULL, input, output, (ShaderEvalType)type, filter, x, offset, sample);
|
||||
if(x < sx + sw) {
|
||||
KernelGlobals kg;
|
||||
kernel_bake_evaluate(&kg, input, output, (ShaderEvalType)type, filter, x, offset, sample);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -144,7 +144,6 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
|
||||
case 86: r = kernel_tex_image_interp(__tex_image_byte4_086, x, y); break;
|
||||
case 87: r = kernel_tex_image_interp(__tex_image_byte4_087, x, y); break;
|
||||
case 88: r = kernel_tex_image_interp(__tex_image_byte4_088, x, y); break;
|
||||
case 89: r = kernel_tex_image_interp(__tex_image_byte4_089, x, y); break;
|
||||
default:
|
||||
kernel_assert(0);
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
@@ -134,32 +134,37 @@ ccl_device float3 svm_math_blackbody_color(float t) {
|
||||
{ 6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f },
|
||||
};
|
||||
|
||||
if(t >= 12000.0f)
|
||||
int i;
|
||||
if(t >= 12000.0f) {
|
||||
return make_float3(0.826270103f, 0.994478524f, 1.56626022f);
|
||||
}
|
||||
else if(t >= 6365.0f) {
|
||||
i = 5;
|
||||
}
|
||||
else if(t >= 3315.0f) {
|
||||
i = 4;
|
||||
}
|
||||
else if(t >= 1902.0f) {
|
||||
i = 3;
|
||||
}
|
||||
else if(t >= 1449.0f) {
|
||||
i = 2;
|
||||
}
|
||||
else if(t >= 1167.0f) {
|
||||
i = 1;
|
||||
}
|
||||
else if(t >= 965.0f) {
|
||||
i = 0;
|
||||
}
|
||||
else {
|
||||
/* For 800 <= t < 965 color does not change in OSL implementation, so keep color the same */
|
||||
return make_float3(4.70366907f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
/* Define a macro to reduce stack usage for nvcc */
|
||||
#define MAKE_BB_RGB(i) make_float3(\
|
||||
rc[i][0] / t + rc[i][1] * t + rc[i][2],\
|
||||
gc[i][0] / t + gc[i][1] * t + gc[i][2],\
|
||||
((bc[i][0] * t + bc[i][1]) * t + bc[i][2]) * t + bc[i][3])
|
||||
|
||||
if(t >= 6365.0f)
|
||||
return MAKE_BB_RGB(5);
|
||||
if(t >= 3315.0f)
|
||||
return MAKE_BB_RGB(4);
|
||||
if(t >= 1902.0f)
|
||||
return MAKE_BB_RGB(3);
|
||||
if(t >= 1449.0f)
|
||||
return MAKE_BB_RGB(2);
|
||||
if(t >= 1167.0f)
|
||||
return MAKE_BB_RGB(1);
|
||||
if(t >= 965.0f)
|
||||
return MAKE_BB_RGB(0);
|
||||
|
||||
#undef MAKE_BB_RGB
|
||||
|
||||
/* For 800 <= t < 965 color does not change in OSL implementation, so keep color the same */
|
||||
return make_float3(4.70366907f, 0.0f, 0.0f);
|
||||
const float t_inv = 1.0f / t;
|
||||
return make_float3(rc[i][0] * t_inv + rc[i][1] * t + rc[i][2],
|
||||
gc[i][0] * t_inv + gc[i][1] * t + gc[i][2],
|
||||
((bc[i][0] * t + bc[i][1]) * t + bc[i][2]) * t + bc[i][3]);
|
||||
}
|
||||
|
||||
ccl_device_inline float3 svm_math_gamma_color(float3 color, float gamma)
|
||||
|
@@ -18,8 +18,19 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Noise */
|
||||
|
||||
ccl_device_inline void svm_noise(float3 p, float detail, float distortion, float *fac, float3 *color)
|
||||
ccl_device void svm_node_tex_noise(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
|
||||
{
|
||||
uint co_offset, scale_offset, detail_offset, distortion_offset, fac_offset, color_offset;
|
||||
|
||||
decode_node_uchar4(node.y, &co_offset, &scale_offset, &detail_offset, &distortion_offset);
|
||||
decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL);
|
||||
|
||||
uint4 node2 = read_node(kg, offset);
|
||||
|
||||
float scale = stack_load_float_default(stack, scale_offset, node2.x);
|
||||
float detail = stack_load_float_default(stack, detail_offset, node2.y);
|
||||
float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
|
||||
float3 p = stack_load_float3(stack, co_offset) * scale;
|
||||
int hard = 0;
|
||||
|
||||
if(distortion != 0.0f) {
|
||||
@@ -32,36 +43,17 @@ ccl_device_inline void svm_noise(float3 p, float detail, float distortion, float
|
||||
p += r;
|
||||
}
|
||||
|
||||
*fac = noise_turbulence(p, detail, hard);
|
||||
*color = make_float3(*fac,
|
||||
noise_turbulence(make_float3(p.y, p.x, p.z), detail, hard),
|
||||
noise_turbulence(make_float3(p.y, p.z, p.x), detail, hard));
|
||||
}
|
||||
float f = noise_turbulence(p, detail, hard);
|
||||
|
||||
ccl_device void svm_node_tex_noise(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
|
||||
{
|
||||
uint co_offset, scale_offset, detail_offset, distortion_offset, fac_offset, color_offset;
|
||||
|
||||
decode_node_uchar4(node.y, &co_offset, &scale_offset, &detail_offset, &distortion_offset);
|
||||
|
||||
uint4 node2 = read_node(kg, offset);
|
||||
|
||||
float scale = stack_load_float_default(stack, scale_offset, node2.x);
|
||||
float detail = stack_load_float_default(stack, detail_offset, node2.y);
|
||||
float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
|
||||
float3 color;
|
||||
float f;
|
||||
|
||||
svm_noise(co*scale, detail, distortion, &f, &color);
|
||||
|
||||
decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL);
|
||||
|
||||
if(stack_valid(fac_offset))
|
||||
if(stack_valid(fac_offset)) {
|
||||
stack_store_float(stack, fac_offset, f);
|
||||
if(stack_valid(color_offset))
|
||||
}
|
||||
if(stack_valid(color_offset)) {
|
||||
float3 color = make_float3(f,
|
||||
noise_turbulence(make_float3(p.y, p.x, p.z), detail, hard),
|
||||
noise_turbulence(make_float3(p.y, p.z, p.x), detail, hard));
|
||||
stack_store_float3(stack, color_offset, color);
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -73,7 +73,7 @@ public:
|
||||
|
||||
bool need_update;
|
||||
|
||||
int total_pixel_samples;
|
||||
size_t total_pixel_samples;
|
||||
|
||||
private:
|
||||
BakeData *m_bake_data;
|
||||
|
@@ -285,9 +285,8 @@ int ImageManager::add_image(const string& filename,
|
||||
|
||||
thread_scoped_lock device_lock(device_mutex);
|
||||
|
||||
/* Do we have a float? */
|
||||
if(type == IMAGE_DATA_TYPE_FLOAT || type == IMAGE_DATA_TYPE_FLOAT4)
|
||||
is_float = true;
|
||||
/* Check whether it's a float texture. */
|
||||
is_float = (type == IMAGE_DATA_TYPE_FLOAT || type == IMAGE_DATA_TYPE_FLOAT4);
|
||||
|
||||
/* No single channel and half textures on CUDA (Fermi) and no half on OpenCL, use available slots */
|
||||
if((type == IMAGE_DATA_TYPE_FLOAT ||
|
||||
|
@@ -43,6 +43,8 @@ NODE_DEFINE(Integrator)
|
||||
SOCKET_INT(transparent_max_bounce, "Transparent Max Bounce", 7);
|
||||
SOCKET_BOOLEAN(transparent_shadows, "Transparent Shadows", false);
|
||||
|
||||
SOCKET_INT(ao_bounces, "AO Bounces", 0);
|
||||
|
||||
SOCKET_INT(volume_max_steps, "Volume Max Steps", 1024);
|
||||
SOCKET_FLOAT(volume_step_size, "Volume Step Size", 0.1f);
|
||||
|
||||
@@ -62,6 +64,7 @@ NODE_DEFINE(Integrator)
|
||||
SOCKET_INT(mesh_light_samples, "Mesh Light Samples", 1);
|
||||
SOCKET_INT(subsurface_samples, "Subsurface Samples", 1);
|
||||
SOCKET_INT(volume_samples, "Volume Samples", 1);
|
||||
SOCKET_INT(start_sample, "Start Sample", 0);
|
||||
|
||||
SOCKET_BOOLEAN(sample_all_lights_direct, "Sample All Lights Direct", true);
|
||||
SOCKET_BOOLEAN(sample_all_lights_indirect, "Sample All Lights Indirect", true);
|
||||
@@ -111,6 +114,13 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
||||
kintegrator->transparent_max_bounce = transparent_max_bounce + 1;
|
||||
kintegrator->transparent_min_bounce = transparent_min_bounce + 1;
|
||||
|
||||
if(ao_bounces == 0) {
|
||||
kintegrator->ao_bounces = INT_MAX;
|
||||
}
|
||||
else {
|
||||
kintegrator->ao_bounces = ao_bounces - 1;
|
||||
}
|
||||
|
||||
/* Transparent Shadows
|
||||
* We only need to enable transparent shadows, if we actually have
|
||||
* transparent shaders in the scene. Otherwise we can disable it
|
||||
@@ -152,6 +162,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
||||
kintegrator->mesh_light_samples = mesh_light_samples;
|
||||
kintegrator->subsurface_samples = subsurface_samples;
|
||||
kintegrator->volume_samples = volume_samples;
|
||||
kintegrator->start_sample = start_sample;
|
||||
|
||||
if(method == BRANCHED_PATH) {
|
||||
kintegrator->sample_all_lights_direct = sample_all_lights_direct;
|
||||
|
@@ -43,6 +43,8 @@ public:
|
||||
int transparent_max_bounce;
|
||||
bool transparent_shadows;
|
||||
|
||||
int ao_bounces;
|
||||
|
||||
int volume_max_steps;
|
||||
float volume_step_size;
|
||||
|
||||
@@ -64,6 +66,7 @@ public:
|
||||
int mesh_light_samples;
|
||||
int subsurface_samples;
|
||||
int volume_samples;
|
||||
int start_sample;
|
||||
|
||||
bool sample_all_lights_direct;
|
||||
bool sample_all_lights_indirect;
|
||||
|
@@ -486,10 +486,18 @@ static void background_cdf(int start,
|
||||
float2 *cond_cdf)
|
||||
{
|
||||
/* Conditional CDFs (rows, U direction). */
|
||||
/* NOTE: It is possible to have some NaN pixels on background
|
||||
* which will ruin CDF causing wrong shading. We replace such
|
||||
* pixels with black.
|
||||
*/
|
||||
for(int i = start; i < end; i++) {
|
||||
float sin_theta = sinf(M_PI_F * (i + 0.5f) / res);
|
||||
float3 env_color = (*pixels)[i * res];
|
||||
float ave_luminance = average(env_color);
|
||||
/* TODO(sergey): Consider adding average_safe(). */
|
||||
if(!isfinite(ave_luminance)) {
|
||||
ave_luminance = 0.0f;
|
||||
}
|
||||
|
||||
cond_cdf[i * cdf_count].x = ave_luminance * sin_theta;
|
||||
cond_cdf[i * cdf_count].y = 0.0f;
|
||||
@@ -497,6 +505,9 @@ static void background_cdf(int start,
|
||||
for(int j = 1; j < res; j++) {
|
||||
env_color = (*pixels)[i * res + j];
|
||||
ave_luminance = average(env_color);
|
||||
if(!isfinite(ave_luminance)) {
|
||||
ave_luminance = 0.0f;
|
||||
}
|
||||
|
||||
cond_cdf[i * cdf_count + j].x = ave_luminance * sin_theta;
|
||||
cond_cdf[i * cdf_count + j].y = cond_cdf[i * cdf_count + j - 1].y + cond_cdf[i * cdf_count + j - 1].x / res;
|
||||
|
@@ -1873,9 +1873,14 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
|
||||
dscene->prim_object.reference((uint*)&pack.prim_object[0], pack.prim_object.size());
|
||||
device->tex_alloc("__prim_object", dscene->prim_object);
|
||||
}
|
||||
if(pack.prim_time.size()) {
|
||||
dscene->prim_time.reference((float2*)&pack.prim_time[0], pack.prim_time.size());
|
||||
device->tex_alloc("__prim_time", dscene->prim_time);
|
||||
}
|
||||
|
||||
dscene->data.bvh.root = pack.root_index;
|
||||
dscene->data.bvh.use_qbvh = scene->params.use_qbvh;
|
||||
dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
|
||||
}
|
||||
|
||||
void MeshManager::device_update_flags(Device * /*device*/,
|
||||
@@ -2152,6 +2157,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
|
||||
device->tex_free(dscene->prim_visibility);
|
||||
device->tex_free(dscene->prim_index);
|
||||
device->tex_free(dscene->prim_object);
|
||||
device->tex_free(dscene->prim_time);
|
||||
device->tex_free(dscene->tri_shader);
|
||||
device->tex_free(dscene->tri_vnormal);
|
||||
device->tex_free(dscene->tri_vindex);
|
||||
@@ -2173,6 +2179,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
|
||||
dscene->prim_visibility.clear();
|
||||
dscene->prim_index.clear();
|
||||
dscene->prim_object.clear();
|
||||
dscene->prim_time.clear();
|
||||
dscene->tri_shader.clear();
|
||||
dscene->tri_vnormal.clear();
|
||||
dscene->tri_vindex.clear();
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "util_sky_model.h"
|
||||
#include "util_foreach.h"
|
||||
#include "util_logging.h"
|
||||
#include "util_transform.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -1931,21 +1932,38 @@ GlossyBsdfNode::GlossyBsdfNode()
|
||||
void GlossyBsdfNode::simplify_settings(Scene *scene)
|
||||
{
|
||||
if(distribution_orig == NBUILTIN_CLOSURES) {
|
||||
roughness_orig = roughness;
|
||||
distribution_orig = distribution;
|
||||
}
|
||||
else {
|
||||
/* By default we use original values, so we don't worry about restoring
|
||||
* defaults later one and can only do override when needed.
|
||||
*/
|
||||
roughness = roughness_orig;
|
||||
distribution = distribution_orig;
|
||||
}
|
||||
Integrator *integrator = scene->integrator;
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(integrator->filter_glossy == 0.0f) {
|
||||
/* Fallback to Sharp closure for Roughness close to 0.
|
||||
* Note: Keep the epsilon in sync with kernel!
|
||||
*/
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(!roughness_input->link && roughness <= 1e-4f) {
|
||||
VLOG(1) << "Using sharp glossy BSDF.";
|
||||
distribution = CLOSURE_BSDF_REFLECTION_ID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Rollback to original distribution when filter glossy is used. */
|
||||
distribution = distribution_orig;
|
||||
/* If filter glossy is used we replace Sharp glossy with GGX so we can
|
||||
* benefit from closure blur to remove unwanted noise.
|
||||
*/
|
||||
if(roughness_input->link == NULL &&
|
||||
distribution == CLOSURE_BSDF_REFLECTION_ID)
|
||||
{
|
||||
VLOG(1) << "Using GGX glossy with filter glossy.";
|
||||
distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
|
||||
roughness = 0.0f;
|
||||
}
|
||||
}
|
||||
closure = distribution;
|
||||
}
|
||||
@@ -1953,7 +1971,8 @@ void GlossyBsdfNode::simplify_settings(Scene *scene)
|
||||
bool GlossyBsdfNode::has_integrator_dependency()
|
||||
{
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
return !roughness_input->link && roughness <= 1e-4f;
|
||||
return !roughness_input->link &&
|
||||
(distribution == CLOSURE_BSDF_REFLECTION_ID || roughness <= 1e-4f);
|
||||
}
|
||||
|
||||
void GlossyBsdfNode::compile(SVMCompiler& compiler)
|
||||
@@ -2008,21 +2027,38 @@ GlassBsdfNode::GlassBsdfNode()
|
||||
void GlassBsdfNode::simplify_settings(Scene *scene)
|
||||
{
|
||||
if(distribution_orig == NBUILTIN_CLOSURES) {
|
||||
roughness_orig = roughness;
|
||||
distribution_orig = distribution;
|
||||
}
|
||||
else {
|
||||
/* By default we use original values, so we don't worry about restoring
|
||||
* defaults later one and can only do override when needed.
|
||||
*/
|
||||
roughness = roughness_orig;
|
||||
distribution = distribution_orig;
|
||||
}
|
||||
Integrator *integrator = scene->integrator;
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(integrator->filter_glossy == 0.0f) {
|
||||
/* Fallback to Sharp closure for Roughness close to 0.
|
||||
* Note: Keep the epsilon in sync with kernel!
|
||||
*/
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(!roughness_input->link && roughness <= 1e-4f) {
|
||||
VLOG(1) << "Using sharp glass BSDF.";
|
||||
distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Rollback to original distribution when filter glossy is used. */
|
||||
distribution = distribution_orig;
|
||||
/* If filter glossy is used we replace Sharp glossy with GGX so we can
|
||||
* benefit from closure blur to remove unwanted noise.
|
||||
*/
|
||||
if(roughness_input->link == NULL &&
|
||||
distribution == CLOSURE_BSDF_SHARP_GLASS_ID)
|
||||
{
|
||||
VLOG(1) << "Using GGX glass with filter glossy.";
|
||||
distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
|
||||
roughness = 0.0f;
|
||||
}
|
||||
}
|
||||
closure = distribution;
|
||||
}
|
||||
@@ -2030,7 +2066,8 @@ void GlassBsdfNode::simplify_settings(Scene *scene)
|
||||
bool GlassBsdfNode::has_integrator_dependency()
|
||||
{
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
return !roughness_input->link && roughness <= 1e-4f;
|
||||
return !roughness_input->link &&
|
||||
(distribution == CLOSURE_BSDF_SHARP_GLASS_ID || roughness <= 1e-4f);
|
||||
}
|
||||
|
||||
void GlassBsdfNode::compile(SVMCompiler& compiler)
|
||||
@@ -2085,21 +2122,38 @@ RefractionBsdfNode::RefractionBsdfNode()
|
||||
void RefractionBsdfNode::simplify_settings(Scene *scene)
|
||||
{
|
||||
if(distribution_orig == NBUILTIN_CLOSURES) {
|
||||
roughness_orig = roughness;
|
||||
distribution_orig = distribution;
|
||||
}
|
||||
else {
|
||||
/* By default we use original values, so we don't worry about restoring
|
||||
* defaults later one and can only do override when needed.
|
||||
*/
|
||||
roughness = roughness_orig;
|
||||
distribution = distribution_orig;
|
||||
}
|
||||
Integrator *integrator = scene->integrator;
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(integrator->filter_glossy == 0.0f) {
|
||||
/* Fallback to Sharp closure for Roughness close to 0.
|
||||
* Note: Keep the epsilon in sync with kernel!
|
||||
*/
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(!roughness_input->link && roughness <= 1e-4f) {
|
||||
VLOG(1) << "Using sharp refraction BSDF.";
|
||||
distribution = CLOSURE_BSDF_REFRACTION_ID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Rollback to original distribution when filter glossy is used. */
|
||||
distribution = distribution_orig;
|
||||
/* If filter glossy is used we replace Sharp glossy with GGX so we can
|
||||
* benefit from closure blur to remove unwanted noise.
|
||||
*/
|
||||
if(roughness_input->link == NULL &&
|
||||
distribution == CLOSURE_BSDF_REFRACTION_ID)
|
||||
{
|
||||
VLOG(1) << "Using GGX refraction with filter glossy.";
|
||||
distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
|
||||
roughness = 0.0f;
|
||||
}
|
||||
}
|
||||
closure = distribution;
|
||||
}
|
||||
@@ -2107,7 +2161,8 @@ void RefractionBsdfNode::simplify_settings(Scene *scene)
|
||||
bool RefractionBsdfNode::has_integrator_dependency()
|
||||
{
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
return !roughness_input->link && roughness <= 1e-4f;
|
||||
return !roughness_input->link &&
|
||||
(distribution == CLOSURE_BSDF_REFRACTION_ID || roughness <= 1e-4f);
|
||||
}
|
||||
|
||||
void RefractionBsdfNode::compile(SVMCompiler& compiler)
|
||||
|
@@ -388,7 +388,7 @@ public:
|
||||
bool has_integrator_dependency();
|
||||
ClosureType get_closure_type() { return distribution; }
|
||||
|
||||
float roughness;
|
||||
float roughness, roughness_orig;
|
||||
ClosureType distribution, distribution_orig;
|
||||
};
|
||||
|
||||
@@ -400,7 +400,7 @@ public:
|
||||
bool has_integrator_dependency();
|
||||
ClosureType get_closure_type() { return distribution; }
|
||||
|
||||
float roughness, IOR;
|
||||
float roughness, roughness_orig, IOR;
|
||||
ClosureType distribution, distribution_orig;
|
||||
};
|
||||
|
||||
@@ -412,7 +412,7 @@ public:
|
||||
bool has_integrator_dependency();
|
||||
ClosureType get_closure_type() { return distribution; }
|
||||
|
||||
float roughness, IOR;
|
||||
float roughness, roughness_orig, IOR;
|
||||
ClosureType distribution, distribution_orig;
|
||||
};
|
||||
|
||||
|
@@ -69,6 +69,7 @@ public:
|
||||
device_vector<uint> prim_visibility;
|
||||
device_vector<uint> prim_index;
|
||||
device_vector<uint> prim_object;
|
||||
device_vector<float2> prim_time;
|
||||
|
||||
/* mesh */
|
||||
device_vector<uint> tri_shader;
|
||||
|
@@ -230,7 +230,9 @@ void Session::run_gpu()
|
||||
while(1) {
|
||||
scoped_timer pause_timer;
|
||||
pause_cond.wait(pause_lock);
|
||||
progress.add_skip_time(pause_timer, params.background);
|
||||
if(pause) {
|
||||
progress.add_skip_time(pause_timer, params.background);
|
||||
}
|
||||
|
||||
update_status_time(pause, no_tiles);
|
||||
progress.set_update();
|
||||
@@ -520,7 +522,9 @@ void Session::run_cpu()
|
||||
while(1) {
|
||||
scoped_timer pause_timer;
|
||||
pause_cond.wait(pause_lock);
|
||||
progress.add_skip_time(pause_timer, params.background);
|
||||
if(pause) {
|
||||
progress.add_skip_time(pause_timer, params.background);
|
||||
}
|
||||
|
||||
update_status_time(pause, no_tiles);
|
||||
progress.set_update();
|
||||
|
@@ -92,7 +92,7 @@ public:
|
||||
template<typename T>
|
||||
ShaderGraphBuilder& add_node(const T& node)
|
||||
{
|
||||
EXPECT_EQ(NULL, find_node(node.name()));
|
||||
EXPECT_EQ(find_node(node.name()), (void*)NULL);
|
||||
graph_->add(node.node());
|
||||
node_map_[node.name()] = node.node();
|
||||
return *this;
|
||||
@@ -104,8 +104,8 @@ public:
|
||||
vector<string> tokens_from, tokens_to;
|
||||
string_split(tokens_from, from, "::");
|
||||
string_split(tokens_to, to, "::");
|
||||
EXPECT_EQ(2, tokens_from.size());
|
||||
EXPECT_EQ(2, tokens_to.size());
|
||||
EXPECT_EQ(tokens_from.size(), 2);
|
||||
EXPECT_EQ(tokens_to.size(), 2);
|
||||
ShaderNode *node_from = find_node(tokens_from[0]),
|
||||
*node_to = find_node(tokens_to[0]);
|
||||
EXPECT_NE((void*)NULL, node_from);
|
||||
|
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "util/util_aligned_malloc.h"
|
||||
|
||||
#define CHECK_ALIGNMENT(ptr, align) EXPECT_EQ(0, (size_t)ptr % align)
|
||||
#define CHECK_ALIGNMENT(ptr, align) EXPECT_EQ((size_t)ptr % align, 0)
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@@ -26,63 +26,63 @@ CCL_NAMESPACE_BEGIN
|
||||
TEST(util_path_filename, simple_unix)
|
||||
{
|
||||
string str = path_filename("/tmp/foo.txt");
|
||||
EXPECT_EQ("foo.txt", str);
|
||||
EXPECT_EQ(str, "foo.txt");
|
||||
}
|
||||
|
||||
TEST(util_path_filename, root_unix)
|
||||
{
|
||||
string str = path_filename("/");
|
||||
EXPECT_EQ("/", str);
|
||||
EXPECT_EQ(str, "/");
|
||||
}
|
||||
|
||||
TEST(util_path_filename, last_slash_unix)
|
||||
{
|
||||
string str = path_filename("/tmp/foo.txt/");
|
||||
EXPECT_EQ(".", str);
|
||||
EXPECT_EQ(str, ".");
|
||||
}
|
||||
|
||||
TEST(util_path_filename, alternate_slash_unix)
|
||||
{
|
||||
string str = path_filename("/tmp\\foo.txt");
|
||||
EXPECT_EQ("tmp\\foo.txt", str);
|
||||
EXPECT_EQ(str, "tmp\\foo.txt");
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
TEST(util_path_filename, file_only)
|
||||
{
|
||||
string str = path_filename("foo.txt");
|
||||
EXPECT_EQ("foo.txt", str);
|
||||
EXPECT_EQ(str, "foo.txt");
|
||||
}
|
||||
|
||||
TEST(util_path_filename, empty)
|
||||
{
|
||||
string str = path_filename("");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST(util_path_filename, simple_windows)
|
||||
{
|
||||
string str = path_filename("C:\\tmp\\foo.txt");
|
||||
EXPECT_EQ("foo.txt", str);
|
||||
EXPECT_EQ(str, "foo.txt");
|
||||
}
|
||||
|
||||
TEST(util_path_filename, root_windows)
|
||||
{
|
||||
string str = path_filename("C:\\");
|
||||
EXPECT_EQ("\\", str);
|
||||
EXPECT_EQ(str, "\\");
|
||||
}
|
||||
|
||||
TEST(util_path_filename, last_slash_windows)
|
||||
{
|
||||
string str = path_filename("C:\\tmp\\foo.txt\\");
|
||||
EXPECT_EQ(".", str);
|
||||
EXPECT_EQ(str, ".");
|
||||
}
|
||||
|
||||
TEST(util_path_filename, alternate_slash_windows)
|
||||
{
|
||||
string str = path_filename("C:\\tmp/foo.txt");
|
||||
EXPECT_EQ("foo.txt", str);
|
||||
EXPECT_EQ(str, "foo.txt");
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
@@ -92,63 +92,63 @@ TEST(util_path_filename, alternate_slash_windows)
|
||||
TEST(util_path_dirname, simple_unix)
|
||||
{
|
||||
string str = path_dirname("/tmp/foo.txt");
|
||||
EXPECT_EQ("/tmp", str);
|
||||
EXPECT_EQ(str, "/tmp");
|
||||
}
|
||||
|
||||
TEST(util_path_dirname, root_unix)
|
||||
{
|
||||
string str = path_dirname("/");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
TEST(util_path_dirname, last_slash_unix)
|
||||
{
|
||||
string str = path_dirname("/tmp/foo.txt/");
|
||||
EXPECT_EQ("/tmp/foo.txt", str);
|
||||
EXPECT_EQ(str, "/tmp/foo.txt");
|
||||
}
|
||||
|
||||
TEST(util_path_dirname, alternate_slash_unix)
|
||||
{
|
||||
string str = path_dirname("/tmp\\foo.txt");
|
||||
EXPECT_EQ("/", str);
|
||||
EXPECT_EQ(str, "/");
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
TEST(util_path_dirname, file_only)
|
||||
{
|
||||
string str = path_dirname("foo.txt");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
TEST(util_path_dirname, empty)
|
||||
{
|
||||
string str = path_dirname("");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST(util_path_dirname, simple_windows)
|
||||
{
|
||||
string str = path_dirname("C:\\tmp\\foo.txt");
|
||||
EXPECT_EQ("C:\\tmp", str);
|
||||
EXPECT_EQ(str, "C:\\tmp");
|
||||
}
|
||||
|
||||
TEST(util_path_dirname, root_windows)
|
||||
{
|
||||
string str = path_dirname("C:\\");
|
||||
EXPECT_EQ("C:", str);
|
||||
EXPECT_EQ(str, "C:");
|
||||
}
|
||||
|
||||
TEST(util_path_dirname, last_slash_windows)
|
||||
{
|
||||
string str = path_dirname("C:\\tmp\\foo.txt\\");
|
||||
EXPECT_EQ("C:\\tmp\\foo.txt", str);
|
||||
EXPECT_EQ(str, "C:\\tmp\\foo.txt");
|
||||
}
|
||||
|
||||
TEST(util_path_dirname, alternate_slash_windows)
|
||||
{
|
||||
string str = path_dirname("C:\\tmp/foo.txt");
|
||||
EXPECT_EQ("C:\\tmp", str);
|
||||
EXPECT_EQ(str, "C:\\tmp");
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
@@ -157,152 +157,152 @@ TEST(util_path_dirname, alternate_slash_windows)
|
||||
TEST(util_path_join, empty_both)
|
||||
{
|
||||
string str = path_join("", "");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
TEST(util_path_join, empty_directory)
|
||||
{
|
||||
string str = path_join("", "foo.txt");
|
||||
EXPECT_EQ("foo.txt", str);
|
||||
EXPECT_EQ(str, "foo.txt");
|
||||
}
|
||||
|
||||
TEST(util_path_join, empty_filename)
|
||||
{
|
||||
string str = path_join("foo", "");
|
||||
EXPECT_EQ("foo", str);
|
||||
EXPECT_EQ(str, "foo");
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
TEST(util_path_join, simple_unix)
|
||||
{
|
||||
string str = path_join("foo", "bar");
|
||||
EXPECT_EQ("foo/bar", str);
|
||||
EXPECT_EQ(str, "foo/bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, directory_slash_unix)
|
||||
{
|
||||
string str = path_join("foo/", "bar");
|
||||
EXPECT_EQ("foo/bar", str);
|
||||
EXPECT_EQ(str, "foo/bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, filename_slash_unix)
|
||||
{
|
||||
string str = path_join("foo", "/bar");
|
||||
EXPECT_EQ("foo/bar", str);
|
||||
EXPECT_EQ(str, "foo/bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, both_slash_unix)
|
||||
{
|
||||
string str = path_join("foo/", "/bar");
|
||||
EXPECT_EQ("foo//bar", str);
|
||||
EXPECT_EQ(str, "foo//bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, directory_alternate_slash_unix)
|
||||
{
|
||||
string str = path_join("foo\\", "bar");
|
||||
EXPECT_EQ("foo\\/bar", str);
|
||||
EXPECT_EQ(str, "foo\\/bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, filename_alternate_slash_unix)
|
||||
{
|
||||
string str = path_join("foo", "\\bar");
|
||||
EXPECT_EQ("foo/\\bar", str);
|
||||
EXPECT_EQ(str, "foo/\\bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, both_alternate_slash_unix)
|
||||
{
|
||||
string str = path_join("foo", "\\bar");
|
||||
EXPECT_EQ("foo/\\bar", str);
|
||||
EXPECT_EQ(str, "foo/\\bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, empty_dir_filename_slash_unix)
|
||||
{
|
||||
string str = path_join("", "/foo.txt");
|
||||
EXPECT_EQ("/foo.txt", str);
|
||||
EXPECT_EQ(str, "/foo.txt");
|
||||
}
|
||||
|
||||
TEST(util_path_join, empty_dir_filename_alternate_slash_unix)
|
||||
{
|
||||
string str = path_join("", "\\foo.txt");
|
||||
EXPECT_EQ("\\foo.txt", str);
|
||||
EXPECT_EQ(str, "\\foo.txt");
|
||||
}
|
||||
|
||||
TEST(util_path_join, empty_filename_dir_slash_unix)
|
||||
{
|
||||
string str = path_join("foo/", "");
|
||||
EXPECT_EQ("foo/", str);
|
||||
EXPECT_EQ(str, "foo/");
|
||||
}
|
||||
|
||||
TEST(util_path_join, empty_filename_dir_alternate_slash_unix)
|
||||
{
|
||||
string str = path_join("foo\\", "");
|
||||
EXPECT_EQ("foo\\", str);
|
||||
EXPECT_EQ(str, "foo\\");
|
||||
}
|
||||
#else /* !_WIN32 */
|
||||
TEST(util_path_join, simple_windows)
|
||||
{
|
||||
string str = path_join("foo", "bar");
|
||||
EXPECT_EQ("foo\\bar", str);
|
||||
EXPECT_EQ(str, "foo\\bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, directory_slash_windows)
|
||||
{
|
||||
string str = path_join("foo\\", "bar");
|
||||
EXPECT_EQ("foo\\bar", str);
|
||||
EXPECT_EQ(str, "foo\\bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, filename_slash_windows)
|
||||
{
|
||||
string str = path_join("foo", "\\bar");
|
||||
EXPECT_EQ("foo\\bar", str);
|
||||
EXPECT_EQ(str, "foo\\bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, both_slash_windows)
|
||||
{
|
||||
string str = path_join("foo\\", "\\bar");
|
||||
EXPECT_EQ("foo\\\\bar", str);
|
||||
EXPECT_EQ(str, "foo\\\\bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, directory_alternate_slash_windows)
|
||||
{
|
||||
string str = path_join("foo/", "bar");
|
||||
EXPECT_EQ("foo/bar", str);
|
||||
EXPECT_EQ(str, "foo/bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, filename_alternate_slash_windows)
|
||||
{
|
||||
string str = path_join("foo", "/bar");
|
||||
EXPECT_EQ("foo/bar", str);
|
||||
EXPECT_EQ(str, "foo/bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, both_alternate_slash_windows)
|
||||
{
|
||||
string str = path_join("foo/", "/bar");
|
||||
EXPECT_EQ("foo//bar", str);
|
||||
EXPECT_EQ(str, "foo//bar");
|
||||
}
|
||||
|
||||
TEST(util_path_join, empty_dir_filename_slash_windows)
|
||||
{
|
||||
string str = path_join("", "\\foo.txt");
|
||||
EXPECT_EQ("\\foo.txt", str);
|
||||
EXPECT_EQ(str, "\\foo.txt");
|
||||
}
|
||||
|
||||
TEST(util_path_join, empty_dir_filename_alternate_slash_windows)
|
||||
{
|
||||
string str = path_join("", "/foo.txt");
|
||||
EXPECT_EQ("/foo.txt", str);
|
||||
EXPECT_EQ(str, "/foo.txt");
|
||||
}
|
||||
|
||||
TEST(util_path_join, empty_filename_dir_slash_windows)
|
||||
{
|
||||
string str = path_join("foo\\", "");
|
||||
EXPECT_EQ("foo\\", str);
|
||||
EXPECT_EQ(str, "foo\\");
|
||||
}
|
||||
|
||||
TEST(util_path_join, empty_filename_dir_alternate_slash_windows)
|
||||
{
|
||||
string str = path_join("foo/", "");
|
||||
EXPECT_EQ("foo/", str);
|
||||
EXPECT_EQ(str, "foo/");
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
@@ -311,31 +311,31 @@ TEST(util_path_join, empty_filename_dir_alternate_slash_windows)
|
||||
TEST(util_path_escape, no_escape_chars)
|
||||
{
|
||||
string str = path_escape("/tmp/foo/bar");
|
||||
EXPECT_EQ("/tmp/foo/bar", str);
|
||||
EXPECT_EQ(str, "/tmp/foo/bar");
|
||||
}
|
||||
|
||||
TEST(util_path_escape, simple)
|
||||
{
|
||||
string str = path_escape("/tmp/foo bar");
|
||||
EXPECT_EQ("/tmp/foo\\ bar", str);
|
||||
EXPECT_EQ(str, "/tmp/foo\\ bar");
|
||||
}
|
||||
|
||||
TEST(util_path_escape, simple_end)
|
||||
{
|
||||
string str = path_escape("/tmp/foo/bar ");
|
||||
EXPECT_EQ("/tmp/foo/bar\\ ", str);
|
||||
EXPECT_EQ(str, "/tmp/foo/bar\\ ");
|
||||
}
|
||||
|
||||
TEST(util_path_escape, multiple)
|
||||
{
|
||||
string str = path_escape("/tmp/foo bar");
|
||||
EXPECT_EQ("/tmp/foo\\ \\ bar", str);
|
||||
EXPECT_EQ(str, "/tmp/foo\\ \\ bar");
|
||||
}
|
||||
|
||||
TEST(util_path_escape, simple_multiple_end)
|
||||
{
|
||||
string str = path_escape("/tmp/foo/bar ");
|
||||
EXPECT_EQ("/tmp/foo/bar\\ \\ ", str);
|
||||
EXPECT_EQ(str, "/tmp/foo/bar\\ \\ ");
|
||||
}
|
||||
|
||||
/* ******** Tests for path_is_relative() ******** */
|
||||
|
@@ -25,25 +25,25 @@ CCL_NAMESPACE_BEGIN
|
||||
TEST(util_string_printf, no_format)
|
||||
{
|
||||
string str = string_printf("foo bar");
|
||||
EXPECT_EQ(str, "foo bar");
|
||||
EXPECT_EQ("foo bar", str);
|
||||
}
|
||||
|
||||
TEST(util_string_printf, int_number)
|
||||
{
|
||||
string str = string_printf("foo %d bar", 314);
|
||||
EXPECT_EQ(str, "foo 314 bar");
|
||||
EXPECT_EQ("foo 314 bar", str);
|
||||
}
|
||||
|
||||
TEST(util_string_printf, float_number_default_precision)
|
||||
{
|
||||
string str = string_printf("foo %f bar", 3.1415);
|
||||
EXPECT_EQ(str, "foo 3.141500 bar");
|
||||
EXPECT_EQ("foo 3.141500 bar", str);
|
||||
}
|
||||
|
||||
TEST(util_string_printf, float_number_custom_precision)
|
||||
{
|
||||
string str = string_printf("foo %.1f bar", 3.1415);
|
||||
EXPECT_EQ(str, "foo 3.1 bar");
|
||||
EXPECT_EQ("foo 3.1 bar", str);
|
||||
}
|
||||
|
||||
/* ******** Tests for string_printf() ******** */
|
||||
@@ -78,44 +78,44 @@ TEST(util_string_split, empty)
|
||||
{
|
||||
vector<string> tokens;
|
||||
string_split(tokens, "");
|
||||
EXPECT_EQ(0, tokens.size());
|
||||
EXPECT_EQ(tokens.size(), 0);
|
||||
}
|
||||
|
||||
TEST(util_string_split, only_spaces)
|
||||
{
|
||||
vector<string> tokens;
|
||||
string_split(tokens, " \t\t \t");
|
||||
EXPECT_EQ(0, tokens.size());
|
||||
EXPECT_EQ(tokens.size(), 0);
|
||||
}
|
||||
|
||||
TEST(util_string_split, single)
|
||||
{
|
||||
vector<string> tokens;
|
||||
string_split(tokens, "foo");
|
||||
EXPECT_EQ(1, tokens.size());
|
||||
EXPECT_EQ("foo", tokens[0]);
|
||||
EXPECT_EQ(tokens.size(), 1);
|
||||
EXPECT_EQ(tokens[0], "foo");
|
||||
}
|
||||
|
||||
TEST(util_string_split, simple)
|
||||
{
|
||||
vector<string> tokens;
|
||||
string_split(tokens, "foo a bar b");
|
||||
EXPECT_EQ(4, tokens.size());
|
||||
EXPECT_EQ("foo", tokens[0]);
|
||||
EXPECT_EQ("a", tokens[1]);
|
||||
EXPECT_EQ("bar", tokens[2]);
|
||||
EXPECT_EQ("b", tokens[3]);
|
||||
EXPECT_EQ(tokens.size(), 4);
|
||||
EXPECT_EQ(tokens[0], "foo");
|
||||
EXPECT_EQ(tokens[1], "a");
|
||||
EXPECT_EQ(tokens[2], "bar");
|
||||
EXPECT_EQ(tokens[3], "b");
|
||||
}
|
||||
|
||||
TEST(util_string_split, multiple_spaces)
|
||||
{
|
||||
vector<string> tokens;
|
||||
string_split(tokens, " \t foo \ta bar b\t ");
|
||||
EXPECT_EQ(4, tokens.size());
|
||||
EXPECT_EQ("foo", tokens[0]);
|
||||
EXPECT_EQ("a", tokens[1]);
|
||||
EXPECT_EQ("bar", tokens[2]);
|
||||
EXPECT_EQ("b", tokens[3]);
|
||||
EXPECT_EQ(tokens.size(), 4);
|
||||
EXPECT_EQ(tokens[0], "foo");
|
||||
EXPECT_EQ(tokens[1], "a");
|
||||
EXPECT_EQ(tokens[2], "bar");
|
||||
EXPECT_EQ(tokens[3], "b");
|
||||
}
|
||||
|
||||
/* ******** Tests for string_replace() ******** */
|
||||
@@ -124,35 +124,35 @@ TEST(util_string_replace, empty_haystack_and_other)
|
||||
{
|
||||
string str = "";
|
||||
string_replace(str, "x", "");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
TEST(util_string_replace, empty_haystack)
|
||||
{
|
||||
string str = "";
|
||||
string_replace(str, "x", "y");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
TEST(util_string_replace, empty_other)
|
||||
{
|
||||
string str = "x";
|
||||
string_replace(str, "x", "");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
TEST(util_string_replace, long_haystack_empty_other)
|
||||
{
|
||||
string str = "a x b xxc";
|
||||
string_replace(str, "x", "");
|
||||
EXPECT_EQ("a b c", str);
|
||||
EXPECT_EQ(str, "a b c");
|
||||
}
|
||||
|
||||
TEST(util_string_replace, long_haystack)
|
||||
{
|
||||
string str = "a x b xxc";
|
||||
string_replace(str, "x", "FOO");
|
||||
EXPECT_EQ("a FOO b FOOFOOc", str);
|
||||
EXPECT_EQ(str, "a FOO b FOOFOOc");
|
||||
}
|
||||
|
||||
/* ******** Tests for string_endswith() ******** */
|
||||
@@ -192,25 +192,25 @@ TEST(util_string_endswith, simple_false)
|
||||
TEST(util_string_strip, empty)
|
||||
{
|
||||
string str = string_strip("");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
TEST(util_string_strip, only_spaces)
|
||||
{
|
||||
string str = string_strip(" ");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
TEST(util_string_strip, no_spaces)
|
||||
{
|
||||
string str = string_strip("foo bar");
|
||||
EXPECT_EQ("foo bar", str);
|
||||
EXPECT_EQ(str, "foo bar");
|
||||
}
|
||||
|
||||
TEST(util_string_strip, with_spaces)
|
||||
{
|
||||
string str = string_strip(" foo bar ");
|
||||
EXPECT_EQ("foo bar", str);
|
||||
EXPECT_EQ(str, "foo bar");
|
||||
}
|
||||
|
||||
/* ******** Tests for string_remove_trademark() ******** */
|
||||
@@ -218,31 +218,31 @@ TEST(util_string_strip, with_spaces)
|
||||
TEST(util_string_remove_trademark, empty)
|
||||
{
|
||||
string str = string_remove_trademark("");
|
||||
EXPECT_EQ("", str);
|
||||
EXPECT_EQ(str, "");
|
||||
}
|
||||
|
||||
TEST(util_string_remove_trademark, no_trademark)
|
||||
{
|
||||
string str = string_remove_trademark("foo bar");
|
||||
EXPECT_EQ("foo bar", str);
|
||||
EXPECT_EQ(str, "foo bar");
|
||||
}
|
||||
|
||||
TEST(util_string_remove_trademark, only_tm)
|
||||
{
|
||||
string str = string_remove_trademark("foo bar(TM) zzz");
|
||||
EXPECT_EQ("foo bar zzz", str);
|
||||
EXPECT_EQ(str, "foo bar zzz");
|
||||
}
|
||||
|
||||
TEST(util_string_remove_trademark, only_r)
|
||||
{
|
||||
string str = string_remove_trademark("foo bar(R) zzz");
|
||||
EXPECT_EQ("foo bar zzz", str);
|
||||
EXPECT_EQ(str, "foo bar zzz");
|
||||
}
|
||||
|
||||
TEST(util_string_remove_trademark, both)
|
||||
{
|
||||
string str = string_remove_trademark("foo bar(TM)(R) zzz");
|
||||
EXPECT_EQ("foo bar zzz", str);
|
||||
EXPECT_EQ(str, "foo bar zzz");
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#define __UTIL_HALF_H__
|
||||
|
||||
#include "util_types.h"
|
||||
#include "util_math.h"
|
||||
|
||||
#ifdef __KERNEL_SSE2__
|
||||
#include "util_simd.h"
|
||||
@@ -110,6 +111,28 @@ ccl_device_inline float4 half4_to_float4(half4 h)
|
||||
return f;
|
||||
}
|
||||
|
||||
ccl_device_inline half float_to_half(float f)
|
||||
{
|
||||
const uint u = __float_as_uint(f);
|
||||
/* Sign bit, shifted to it's position. */
|
||||
uint sign_bit = u & 0x80000000;
|
||||
sign_bit >>= 16;
|
||||
/* Exponent. */
|
||||
uint exponent_bits = u & 0x7f800000;
|
||||
/* Non-sign bits. */
|
||||
uint value_bits = u & 0x7fffffff;
|
||||
value_bits >>= 13; /* Align mantissa on MSB. */
|
||||
value_bits -= 0x1c000; /* Adjust bias. */
|
||||
/* Flush-to-zero. */
|
||||
value_bits = (exponent_bits < 0x38800000) ? 0 : value_bits;
|
||||
/* Clamp-to-max. */
|
||||
value_bits = (exponent_bits > 0x47000000) ? 0x7bff : value_bits;
|
||||
/* Denormals-as-zero. */
|
||||
value_bits = (exponent_bits == 0 ? 0 : value_bits);
|
||||
/* Re-insert sign bit and return. */
|
||||
return (value_bits | sign_bit);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "util_algorithm.h"
|
||||
#include "util_debug.h"
|
||||
#include "util_half.h"
|
||||
#include "util_image.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -38,6 +39,52 @@ const T *util_image_read(const vector<T>& pixels,
|
||||
return &pixels[index];
|
||||
}
|
||||
|
||||
/* Cast input pixel from unknown storage to float. */
|
||||
template<typename T>
|
||||
inline float cast_to_float(T value);
|
||||
|
||||
template<>
|
||||
inline float cast_to_float(float value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
template<>
|
||||
inline float cast_to_float(uchar value)
|
||||
{
|
||||
return (float)value / 255.0f;
|
||||
}
|
||||
template<>
|
||||
inline float cast_to_float(half value)
|
||||
{
|
||||
return half_to_float(value);
|
||||
}
|
||||
|
||||
/* Cast float value to output pixel type. */
|
||||
template<typename T>
|
||||
inline T cast_from_float(float value);
|
||||
|
||||
template<>
|
||||
inline float cast_from_float(float value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
template<>
|
||||
inline uchar cast_from_float(float value)
|
||||
{
|
||||
if(value < 0.0f) {
|
||||
return 0;
|
||||
}
|
||||
else if(value > (1.0f - 0.5f / 255.0f)) {
|
||||
return 255;
|
||||
}
|
||||
return (uchar)((255.0f * value) + 0.5f);
|
||||
}
|
||||
template<>
|
||||
inline half cast_from_float(float value)
|
||||
{
|
||||
return float_to_half(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void util_image_downscale_sample(const vector<T>& pixels,
|
||||
const size_t width,
|
||||
@@ -71,15 +118,22 @@ void util_image_downscale_sample(const vector<T>& pixels,
|
||||
components,
|
||||
nx, ny, nz);
|
||||
for(size_t k = 0; k < components; ++k) {
|
||||
accum[k] += pixel[k];
|
||||
accum[k] += cast_to_float(pixel[k]);
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
const float inv_count = 1.0f / (float)count;
|
||||
for(size_t k = 0; k < components; ++k) {
|
||||
result[k] = T(accum[k] * inv_count);
|
||||
if(count != 0) {
|
||||
const float inv_count = 1.0f / (float)count;
|
||||
for(size_t k = 0; k < components; ++k) {
|
||||
result[k] = cast_from_float<T>(accum[k] * inv_count);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(size_t k = 0; k < components; ++k) {
|
||||
result[k] = T(0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1329,7 +1329,7 @@ ccl_device_inline float3 safe_divide_even_color(float3 a, float3 b)
|
||||
y = (b.y != 0.0f)? a.y/b.y: 0.0f;
|
||||
z = (b.z != 0.0f)? a.z/b.z: 0.0f;
|
||||
|
||||
/* try to get grey even if b is zero */
|
||||
/* try to get gray even if b is zero */
|
||||
if(b.x == 0.0f) {
|
||||
if(b.y == 0.0f) {
|
||||
x = z;
|
||||
|
@@ -43,7 +43,9 @@ template <> class StaticAssertFailure<true> {};
|
||||
# endif /* __COUNTER__ */
|
||||
# endif /* C++11 or MSVC2015 */
|
||||
#else /* __KERNEL_GPU__ */
|
||||
# define static_assert(statement, message)
|
||||
# ifndef static_assert
|
||||
# define static_assert(statement, message)
|
||||
# endif
|
||||
#endif /* __KERNEL_GPU__ */
|
||||
|
||||
/* TODO(sergey): For until C++11 is a bare minimum for us,
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#if !defined(__MINGW64__)
|
||||
# if defined(_WIN32) || defined(__APPLE__) || \
|
||||
defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
static void sincos(double x, double *sinx, double *cosx) {
|
||||
inline void sincos(double x, double *sinx, double *cosx) {
|
||||
*sinx = sin(x);
|
||||
*cosx = cos(x);
|
||||
}
|
||||
|
@@ -93,7 +93,7 @@ wchar_t *alloc_utf16_from_8(const char *in8, size_t add);
|
||||
|
||||
/* Easy allocation and conversion of new utf-16 string. New string has _16 suffix. Must be deallocated with UTF16_UN_ENCODE in right order*/
|
||||
#define UTF16_ENCODE(in8str) if (1) { \
|
||||
wchar_t *in8str ## _16 = alloc_utf16_from_8((char *)in8str, 0)
|
||||
wchar_t *in8str ## _16 = alloc_utf16_from_8((const char *)in8str, 0)
|
||||
|
||||
#define UTF16_UN_ENCODE(in8str) \
|
||||
free(in8str ## _16); } (void)0
|
||||
|
25
make.bat
25
make.bat
@@ -5,8 +5,8 @@ REM This is for users who like to configure & build Blender with a single comman
|
||||
setlocal ENABLEEXTENSIONS
|
||||
set BLENDER_DIR=%~dp0
|
||||
set BLENDER_DIR_NOSPACES=%BLENDER_DIR: =%
|
||||
if not "%BLENDER_DIR%"=="%BLENDER_DIR_NOSPACES%" (
|
||||
echo There are spaces detected in the build path "%BLENDER_DIR%", this is currently not supported, exiting....
|
||||
if not "%BLENDER_DIR%"=="%BLENDER_DIR_NOSPACES%" (
|
||||
echo There are spaces detected in the build path "%BLENDER_DIR%", this is currently not supported, exiting....
|
||||
goto EOF
|
||||
)
|
||||
set BUILD_DIR=%BLENDER_DIR%..\build_windows
|
||||
@@ -79,7 +79,7 @@ if NOT "%1" == "" (
|
||||
set NOBUILD=1
|
||||
) else if "%1" == "showhash" (
|
||||
for /f "delims=" %%i in ('git rev-parse HEAD') do echo Branch_hash=%%i
|
||||
cd release/datafiles/locale
|
||||
cd release/datafiles/locale
|
||||
for /f "delims=" %%i in ('git rev-parse HEAD') do echo Locale_hash=%%i
|
||||
cd %~dp0
|
||||
cd release/scripts/addons
|
||||
@@ -132,13 +132,13 @@ if "%BUILD_ARCH%"=="x64" (
|
||||
|
||||
|
||||
if "%target%"=="Release" (
|
||||
rem for vc12 check for both cuda 7.5 and 8
|
||||
rem for vc12 check for both cuda 7.5 and 8
|
||||
if "%CUDA_PATH%"=="" (
|
||||
echo Cuda Not found, aborting!
|
||||
goto EOF
|
||||
)
|
||||
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% ^
|
||||
-C"%BLENDER_DIR%\build_files\cmake\config\blender_release.cmake"
|
||||
-C"%BLENDER_DIR%\build_files\cmake\config\blender_release.cmake"
|
||||
)
|
||||
|
||||
:DetectMSVC
|
||||
@@ -157,7 +157,7 @@ if DEFINED MSVC_VC_DIR goto msvc_detect_finally
|
||||
if DEFINED MSVC_VC_DIR call "%MSVC_VC_DIR%\vcvarsall.bat"
|
||||
if DEFINED MSVC_VC_DIR goto sanity_checks
|
||||
|
||||
rem MSVC Build environment 2017 and up.
|
||||
rem MSVC Build environment 2017 and up.
|
||||
for /F "usebackq skip=2 tokens=1-2*" %%A IN (`REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\SXS\VS7" /v %BUILD_VS_VER%.0 2^>nul`) DO set MSVC_VS_DIR=%%C
|
||||
if DEFINED MSVC_VS_DIR goto msvc_detect_finally_2017
|
||||
REM Check 32 bits
|
||||
@@ -202,7 +202,7 @@ if NOT EXIST %BLENDER_DIR%..\lib\nul (
|
||||
if "%TARGET%"=="" (
|
||||
echo Error: Convenience target not set
|
||||
echo This is required for building, aborting!
|
||||
echo .
|
||||
echo .
|
||||
goto HELP
|
||||
)
|
||||
|
||||
@@ -266,15 +266,15 @@ echo.
|
||||
echo At any point you can optionally modify your build configuration by editing:
|
||||
echo "%BUILD_DIR%\CMakeCache.txt", then run "make" again to build with the changes applied.
|
||||
echo.
|
||||
echo Blender successfully built, run from: "%BUILD_DIR%\bin\%BUILD_TYPE%"
|
||||
echo Blender successfully built, run from: "%BUILD_DIR%\bin\%BUILD_TYPE%\blender.exe"
|
||||
echo.
|
||||
goto EOF
|
||||
:HELP
|
||||
echo.
|
||||
echo Convenience targets
|
||||
echo - release ^(identical to the offical blender.org builds^)
|
||||
echo - release ^(identical to the official blender.org builds^)
|
||||
echo - full ^(same as release minus the cuda kernels^)
|
||||
echo - lite
|
||||
echo - lite
|
||||
echo - headless
|
||||
echo - cycles
|
||||
echo - bpy
|
||||
@@ -289,11 +289,10 @@ goto EOF
|
||||
echo - with_tests ^(enable building unit tests^)
|
||||
echo - debug ^(Build an unoptimized debuggable build^)
|
||||
echo - packagename [newname] ^(override default cpack package name^)
|
||||
echo - x86 ^(override host autodetect and build 32 bit code^)
|
||||
echo - x64 ^(override host autodetect and build 64 bit code^)
|
||||
echo - x86 ^(override host auto-detect and build 32 bit code^)
|
||||
echo - x64 ^(override host auto-detect and build 64 bit code^)
|
||||
echo - 2013 ^(build with visual studio 2013^)
|
||||
echo - 2015 ^(build with visual studio 2015^) [EXPERIMENTAL]
|
||||
echo.
|
||||
|
||||
:EOF
|
||||
|
||||
|
@@ -28201,7 +28201,7 @@
|
||||
xlink:href="#linearGradient37542-29"
|
||||
id="linearGradient17610"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-1,0,0,1,461.01011,-167)"
|
||||
gradientTransform="matrix(-1,0,0,1,865.01833,131.0342)"
|
||||
x1="392.0101"
|
||||
y1="224.99998"
|
||||
x2="392.0101"
|
||||
@@ -28263,7 +28263,7 @@
|
||||
xlink:href="#linearGradient37542-29-7"
|
||||
id="linearGradient17610-0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-1,0,0,1,461.01011,-167)"
|
||||
gradientTransform="translate(128.00098,130.98191)"
|
||||
x1="392.0101"
|
||||
y1="224.99998"
|
||||
x2="392.0101"
|
||||
@@ -28402,7 +28402,7 @@
|
||||
x2="228.5468"
|
||||
y1="118.91647"
|
||||
x1="228.5468"
|
||||
gradientTransform="matrix(1.180548,0,0,0.90042534,265.27784,265.13062)"
|
||||
gradientTransform="matrix(1.180548,0,0,0.90042534,265.83288,265.61628)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient17838"
|
||||
xlink:href="#linearGradient319-36-40-2"
|
||||
@@ -28433,7 +28433,7 @@
|
||||
x2="228.5468"
|
||||
y1="118.91647"
|
||||
x1="228.5468"
|
||||
gradientTransform="matrix(1.180548,0,0,0.90042534,223.26222,270.47438)"
|
||||
gradientTransform="matrix(1.180548,0,0,0.90042534,223.81726,270.99473)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient17872"
|
||||
xlink:href="#linearGradient319-36-40-2-4"
|
||||
@@ -29073,7 +29073,7 @@
|
||||
xlink:href="#linearGradient27854-0-6-9"
|
||||
id="linearGradient17162"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,1,-1,0,782.48614,-14.46331)"
|
||||
gradientTransform="matrix(0,1,-1,0,783.04118,-13.977664)"
|
||||
x1="388.86502"
|
||||
y1="244.02"
|
||||
x2="391.43173"
|
||||
@@ -29083,7 +29083,7 @@
|
||||
xlink:href="#linearGradient37542-29-7-8"
|
||||
id="linearGradient17165"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,1,-1,0,782.48614,-14.46331)"
|
||||
gradientTransform="matrix(0,1,-1,0,783.04118,-13.977664)"
|
||||
x1="368.97806"
|
||||
y1="249.99998"
|
||||
x2="393.85385"
|
||||
@@ -29113,7 +29113,7 @@
|
||||
xlink:href="#linearGradient37542-29-1"
|
||||
id="linearGradient17185"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-1,-1,0,740.48614,764.46331)"
|
||||
gradientTransform="matrix(0,-1,-1,0,741.04118,764.98366)"
|
||||
x1="409.93588"
|
||||
y1="249.99998"
|
||||
x2="385.11514"
|
||||
@@ -31338,6 +31338,26 @@
|
||||
d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
|
||||
style="display:inline;fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1610-6"
|
||||
id="linearGradient18199"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="189.76083"
|
||||
y1="248.13905"
|
||||
x2="116.05637"
|
||||
y2="183.6826" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient22562"
|
||||
id="radialGradient23167-6"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.99220964,-0.12457927,0.11585516,0.92272644,-34.13325,22.766225)"
|
||||
cx="-0.78262758"
|
||||
cy="294.63174"
|
||||
fx="-0.78262758"
|
||||
fy="294.63174"
|
||||
r="6.6750002" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
@@ -31349,17 +31369,17 @@
|
||||
objecttolerance="10000"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.274018"
|
||||
inkscape:cx="519.70993"
|
||||
inkscape:cy="325.90484"
|
||||
inkscape:zoom="19.997864"
|
||||
inkscape:cx="462.52244"
|
||||
inkscape:cy="435.14241"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:current-layer="g23149-4"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1005"
|
||||
inkscape:window-x="-2"
|
||||
inkscape:window-y="27"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:window-height="1025"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-bbox="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
@@ -31369,14 +31389,16 @@
|
||||
inkscape:snap-intersection-grid-guide="false"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:bbox-paths="false"
|
||||
inkscape:snap-global="false"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:snap-bbox-midpoints="false"
|
||||
inkscape:snap-grids="true"
|
||||
inkscape:snap-grids="false"
|
||||
inkscape:snap-to-guides="false"
|
||||
inkscape:snap-page="false"
|
||||
units="pt"
|
||||
inkscape:snap-center="false"
|
||||
inkscape:snap-object-midpoints="true">
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-midpoints="false"
|
||||
inkscape:snap-others="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid17394"
|
||||
@@ -88001,37 +88023,37 @@
|
||||
<g
|
||||
style="display:inline;enable-background:new"
|
||||
id="ICON_COLLAPSEMENU"
|
||||
transform="translate(279.8665,506.92392)">
|
||||
transform="translate(280,508)">
|
||||
<rect
|
||||
y="111"
|
||||
x="103"
|
||||
height="16"
|
||||
width="16"
|
||||
id="rect24489-7-4"
|
||||
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;enable-background:accumulate" />
|
||||
<rect
|
||||
style="fill:#ececec;fill-opacity:1;stroke:#141414;stroke-width:0.79452544;stroke-opacity:1"
|
||||
id="rect29842"
|
||||
width="11.816368"
|
||||
height="2.1883197"
|
||||
x="105.18671"
|
||||
y="-116.88043"
|
||||
width="11.209318"
|
||||
height="2.1883163"
|
||||
x="105.39484"
|
||||
y="-116.60292"
|
||||
transform="scale(1,-1)" />
|
||||
<rect
|
||||
style="fill:#ececec;fill-opacity:1;stroke:#141414;stroke-width:0.79452544;stroke-opacity:1;display:inline;enable-background:new"
|
||||
style="display:inline;fill:#ececec;fill-opacity:1;stroke:#141414;stroke-width:0.79452544;stroke-opacity:1;enable-background:new"
|
||||
id="rect29842-4"
|
||||
width="11.816368"
|
||||
height="2.1883197"
|
||||
x="105.31538"
|
||||
y="-120.80865"
|
||||
width="11.191971"
|
||||
height="2.2056611"
|
||||
x="105.41944"
|
||||
y="-120.61786"
|
||||
transform="scale(1,-1)" />
|
||||
<rect
|
||||
style="fill:#ececec;fill-opacity:1;stroke:#141414;stroke-width:0.79452544;stroke-opacity:1;display:inline;enable-background:new"
|
||||
style="display:inline;fill:#ececec;fill-opacity:1;stroke:#141414;stroke-width:0.79500002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
|
||||
id="rect29842-4-5"
|
||||
width="11.816368"
|
||||
height="2.1883197"
|
||||
x="105.41832"
|
||||
y="-124.71391"
|
||||
width="11.22666"
|
||||
height="2.2056642"
|
||||
x="105.38363"
|
||||
y="-124.60985"
|
||||
transform="scale(1,-1)" />
|
||||
</g>
|
||||
<g
|
||||
@@ -89360,17 +89382,18 @@
|
||||
y="69" />
|
||||
<g
|
||||
id="g17605"
|
||||
transform="translate(-1.5467961,-0.48613592)">
|
||||
transform="translate(-0.99177519,0.03419629)">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccccc"
|
||||
style="fill:url(#linearGradient17610);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 472.51758,370.53516 -1.04688,0.0312 0.0371,9.96875 1.00977,0 3.95117,-3.70704 -5.3e-4,3.72852 3.1119,0 0,-10.01758 -3.1119,0 5.3e-4,3.73242 z"
|
||||
transform="translate(-404.00822,-298.0342)"
|
||||
id="path11011-6"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 72.839729,82.521675 2.731705,0 0,-10.016275 -2.731705,0 L 72.84,76.59374 68.51011,72.5 67.4632,72.53125 67.5,82.49999 68.51011,82.5 72.84,78.43749 z"
|
||||
style="fill:url(#linearGradient17610);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path11011-6" />
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
style="fill:none;stroke:url(#linearGradient17612);stroke-width:0.91056824px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 73.7503,81.408784 0,-7.99274 0.910568,-6.3e-5"
|
||||
d="m 73.368723,81.408784 0,-7.99274 1.292145,-6.3e-5"
|
||||
id="path10830-6"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
@@ -89397,17 +89420,18 @@
|
||||
y="69" />
|
||||
<g
|
||||
id="g17605-3"
|
||||
transform="translate(-1.5467961,-0.48613592)">
|
||||
transform="translate(-1.9392553,-0.11820549)">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccccc"
|
||||
style="fill:url(#linearGradient17610-0);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 520.5,370.48242 -4.01758,3.80078 -6.6e-4,-3.79492 -3.04231,0 0,10.01563 3.04231,0 6.6e-4,-3.79297 4.01758,3.77148 1.01172,0 0.0371,-9.96875 z"
|
||||
transform="matrix(-1,0,0,1,589.01109,-297.98191)"
|
||||
id="path11011-6-2"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 72.839729,82.521675 2.731705,0 0,-10.016275 -2.731705,0 L 72.84,76.59374 68.51011,72.5 67.4632,72.53125 67.5,82.49999 68.51011,82.5 72.84,78.43749 z"
|
||||
style="fill:url(#linearGradient17610-0);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path11011-6-2" />
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
style="fill:none;stroke:url(#linearGradient17612-5);stroke-width:0.91056824px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 74.660868,81.408784 0,-7.99274 -0.910568,-6.3e-5"
|
||||
d="m 74.660868,81.408784 0,-7.99274 -1.220453,-6.3e-5"
|
||||
id="path10830-6-2"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
@@ -89432,16 +89456,16 @@
|
||||
y="-546"
|
||||
transform="matrix(0,-1,-1,0,0,0)" />
|
||||
<path
|
||||
style="fill:url(#linearGradient17165);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 533.51953,371.46094 0,3.04042 3.79492,5.9e-4 -3.77343,4.01953 0,1.01172 9.96875,0.0352 0.0312,-1.04688 -3.80274,-4.01953 3.79688,-5.9e-4 0,-3.04042 z"
|
||||
id="path11011-6-2-1"
|
||||
style="fill:url(#linearGradient17165);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 532.96447,373.70707 0,-2.7317 10.01627,0 0,2.7317 -4.08834,-2.7e-4 4.09374,4.32989 -0.0312,1.04691 -9.96874,-0.0368 -1e-5,-1.01011 4.06251,-4.32989 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc"
|
||||
id="path11013-5-7-1"
|
||||
d="m 541.73615,378.0468 -3.75,-4 -3.75,4"
|
||||
d="m 542.29119,378.53246 -3.75,-4 -3.75,4"
|
||||
style="fill:none;stroke:url(#linearGradient17162);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
@@ -89449,8 +89473,8 @@
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
|
||||
id="path10830-6-2-8"
|
||||
d="m 542.11634,371.83103 -8.26386,0 -6e-5,0.90043"
|
||||
style="fill:none;stroke:url(#linearGradient17838);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
|
||||
d="m 542.67138,372.31669 -8.26386,0 -6e-5,1.20843"
|
||||
style="display:inline;fill:none;stroke:url(#linearGradient17838);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;enable-background:new"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
</g>
|
||||
<g
|
||||
@@ -89464,16 +89488,16 @@
|
||||
y="-504"
|
||||
transform="matrix(0,1,-1,0,0,0)" />
|
||||
<path
|
||||
style="fill:url(#linearGradient17185);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 501.50977,371.4375 -9.96875,0.0352 0,1.01172 3.69336,3.93554 -3.71485,-0.005 0,3.13033 10.01563,0 0,-3.13033 -3.7168,0.007 3.72266,-3.9375 z"
|
||||
id="path11011-6-8"
|
||||
style="fill:url(#linearGradient17185);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 490.96446,376.29293 0,2.7317 10.01628,0 0,-2.7317 -4.08834,2.7e-4 4.09374,-4.32989 -0.0312,-1.04691 -9.96874,0.0368 -10e-6,1.01011 4.06251,4.32989 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path11013-5-6"
|
||||
d="m 492.23615,371.9532 7.5,0"
|
||||
d="m 492.79119,372.47355 7.5,0"
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
@@ -89481,8 +89505,8 @@
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
|
||||
id="path10830-6-2-8-8"
|
||||
d="m 500.10071,377.17478 -8.26386,0 -6e-5,0.90043"
|
||||
style="fill:none;stroke:url(#linearGradient17872);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
|
||||
d="m 500.65575,377.29722 -8.26386,0 -6e-5,1.29834"
|
||||
style="display:inline;fill:none;stroke:url(#linearGradient17872);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;enable-background:new"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
</g>
|
||||
<g
|
||||
@@ -92656,6 +92680,56 @@
|
||||
style="opacity:0.51999996;fill:url(#radialGradient21448-8-143);fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(335.99871,21.048284)"
|
||||
style="display:inline;enable-background:new"
|
||||
id="ICON_ROTATE-7">
|
||||
<rect
|
||||
y="178"
|
||||
x="110"
|
||||
height="16"
|
||||
width="16"
|
||||
id="rect37989-8"
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
style="display:inline;overflow:visible;visibility:visible;fill:none;stroke:#000000;stroke-width:2.4000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:new"
|
||||
d="m 114.5,192.5 -3,0 0,-3 m 13,0 0,3 -3,0 m -0.25,-13 3.25,0 0,3 m -13,0 0,-3 3,0"
|
||||
id="path37498-7"
|
||||
sodipodi:nodetypes="cccccccccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccccc"
|
||||
id="rect38140-7"
|
||||
d="m 114.5,192.5 -3,0 0,-3 m 13,0 0,3 -3,0 m -0.25,-13 3.25,0 0,3 m -13,0 0,-3 3,0"
|
||||
style="display:inline;overflow:visible;visibility:visible;fill:none;stroke:url(#linearGradient18199);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:new"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
transform="matrix(0.59971056,0,0,0.59971056,116.78278,9.7425599)"
|
||||
style="display:inline;enable-background:new"
|
||||
id="g23145-9">
|
||||
<g
|
||||
id="g23149-4">
|
||||
<path
|
||||
id="path39832-9"
|
||||
style="display:inline;overflow:visible;visibility:visible;fill:none;stroke:#1a1a1a;stroke-width:4.66725159;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m -4.3682386,287.81345 1.5,0 c 0.999089,0 2.07885534,1.30514 2.50490386,2.78207 1.06592652,3.69512 2.80867074,9.82446 5.88525404,9.96406 2.6782554,0 1.6181317,-5.11535 3.1736046,-5.26275 l 0.25,0"
|
||||
sodipodi:nodetypes="cssccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccscc"
|
||||
d="m 9.3647983,295.22328 -0.4793018,0 c -2.2335161,0 0.1796731,4.94901 -3.4398065,5.09984 -4.44796752,0.18536 -5.37272213,-12.59185 -8.0767581,-12.56237 l -2,0"
|
||||
style="display:inline;overflow:visible;visibility:visible;fill:none;stroke:#a8df84;stroke-width:2.93474906;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path39834-2"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
id="path39836-9"
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0.35;fill:none;stroke:url(#radialGradient23167-6);stroke-width:3.53503864;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="M 5.6770841,300.48165 C 0.7393262,300.21066 0.54777814,287.99792 -2.9522219,287.99792"
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
|
Before Width: | Height: | Size: 4.4 MiB After Width: | Height: | Size: 4.4 MiB |
Binary file not shown.
BIN
release/datafiles/blender_icons16/icon16_normalize_fcurves.dat
Normal file
BIN
release/datafiles/blender_icons16/icon16_normalize_fcurves.dat
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
release/datafiles/blender_icons32/icon32_normalize_fcurves.dat
Normal file
BIN
release/datafiles/blender_icons32/icon32_normalize_fcurves.dat
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Submodule release/datafiles/locale updated: 88158191df...c93ed11a47
Submodule release/scripts/addons updated: a746a84f8a...371960484a
Submodule release/scripts/addons_contrib updated: 029103debc...a8515cfdfe
@@ -568,7 +568,7 @@ class pyRandomColorShader(StrokeShader):
|
||||
|
||||
class py2DCurvatureColorShader(StrokeShader):
|
||||
"""
|
||||
Assigns a color (greyscale) to the stroke based on the curvature.
|
||||
Assigns a color (grayscale) to the stroke based on the curvature.
|
||||
A higher curvature will yield a brighter color.
|
||||
"""
|
||||
def shade(self, stroke):
|
||||
@@ -584,7 +584,7 @@ class py2DCurvatureColorShader(StrokeShader):
|
||||
|
||||
class pyTimeColorShader(StrokeShader):
|
||||
"""
|
||||
Assigns a greyscale value that increases for every vertex.
|
||||
Assigns a grayscale value that increases for every vertex.
|
||||
The brightness will increase along the stroke.
|
||||
"""
|
||||
def __init__(self, step=0.01):
|
||||
|
@@ -1170,6 +1170,7 @@ class Seed:
|
||||
|
||||
_seed = Seed()
|
||||
|
||||
|
||||
def get_dashed_pattern(linestyle):
|
||||
"""Extracts the dashed pattern from the various UI options """
|
||||
pattern = []
|
||||
@@ -1185,6 +1186,15 @@ def get_dashed_pattern(linestyle):
|
||||
return pattern
|
||||
|
||||
|
||||
def get_grouped_objects(group):
|
||||
for ob in group.objects:
|
||||
if ob.dupli_type == 'GROUP' and ob.dupli_group is not None:
|
||||
for dupli in get_grouped_objects(ob.dupli_group):
|
||||
yield dupli
|
||||
else:
|
||||
yield ob
|
||||
|
||||
|
||||
integration_types = {
|
||||
'MEAN': IntegrationType.MEAN,
|
||||
'MIN': IntegrationType.MIN,
|
||||
@@ -1267,7 +1277,7 @@ def process(layer_name, lineset_name):
|
||||
# prepare selection criteria by group of objects
|
||||
if lineset.select_by_group:
|
||||
if lineset.group is not None:
|
||||
names = {getQualifiedObjectName(ob): True for ob in lineset.group.objects}
|
||||
names = {getQualifiedObjectName(ob): True for ob in get_grouped_objects(lineset.group)}
|
||||
upred = ObjectNamesUP1D(names, lineset.group_negation == 'EXCLUSIVE')
|
||||
selection_criteria.append(upred)
|
||||
# prepare selection criteria by image border
|
||||
|
@@ -31,8 +31,9 @@ __all__ = (
|
||||
import bpy as _bpy
|
||||
_user_preferences = _bpy.context.user_preferences
|
||||
|
||||
error_duplicates = False
|
||||
error_encoding = False
|
||||
# (name, file, path)
|
||||
error_duplicates = []
|
||||
addons_fake_modules = {}
|
||||
|
||||
|
||||
@@ -57,12 +58,11 @@ def paths():
|
||||
|
||||
|
||||
def modules_refresh(module_cache=addons_fake_modules):
|
||||
global error_duplicates
|
||||
global error_encoding
|
||||
import os
|
||||
|
||||
error_duplicates = False
|
||||
error_encoding = False
|
||||
error_duplicates.clear()
|
||||
|
||||
path_list = paths()
|
||||
|
||||
@@ -168,7 +168,7 @@ def modules_refresh(module_cache=addons_fake_modules):
|
||||
if mod.__file__ != mod_path:
|
||||
print("multiple addons with the same name:\n %r\n %r" %
|
||||
(mod.__file__, mod_path))
|
||||
error_duplicates = True
|
||||
error_duplicates.append((mod.bl_info["name"], mod.__file__, mod_path))
|
||||
|
||||
elif mod.__time__ != os.path.getmtime(mod_path):
|
||||
print("reloading addon:",
|
||||
|
@@ -933,6 +933,9 @@ km = kc.keymaps.new('3D View', space_type='VIEW_3D', region_type='WINDOW', modal
|
||||
|
||||
kmi = km.keymap_items.new('view3d.cursor3d', 'ACTIONMOUSE', 'PRESS')
|
||||
kmi = km.keymap_items.new('view3d.rotate', 'LEFTMOUSE', 'PRESS', alt=True)
|
||||
kmi = km.keymap_items.new('view3d.manipulator', 'LEFTMOUSE', 'PRESS', shift=True)
|
||||
kmi.properties.release_confirm = True
|
||||
kmi.properties.use_planar_constraint = True
|
||||
kmi = km.keymap_items.new('view3d.manipulator', 'LEFTMOUSE', 'PRESS', any=True)
|
||||
kmi.properties.release_confirm = True
|
||||
kmi = km.keymap_items.new('view3d.move', 'MIDDLEMOUSE', 'PRESS', alt=True)
|
||||
|
@@ -62,28 +62,66 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator):
|
||||
m = linestyle.alpha_modifiers[self.name]
|
||||
else:
|
||||
m = linestyle.thickness_modifiers[self.name]
|
||||
# Find the source object
|
||||
# Find the reference object
|
||||
if m.type == 'DISTANCE_FROM_CAMERA':
|
||||
source = scene.camera
|
||||
ref = scene.camera
|
||||
matrix_to_camera = ref.matrix_world.inverted()
|
||||
elif m.type == 'DISTANCE_FROM_OBJECT':
|
||||
if m.target is None:
|
||||
self.report({'ERROR'}, "Target object not specified")
|
||||
return {'CANCELLED'}
|
||||
source = m.target
|
||||
ref = m.target
|
||||
target_location = ref.location
|
||||
else:
|
||||
self.report({'ERROR'}, "Unexpected modifier type: " + m.type)
|
||||
return {'CANCELLED'}
|
||||
# Find selected mesh objects
|
||||
selection = [ob for ob in scene.objects if ob.select and ob.type == 'MESH' and ob.name != source.name]
|
||||
if selection:
|
||||
# Compute the min/max distance between selected mesh objects and the source
|
||||
# Find selected vertices in editmesh
|
||||
ob = bpy.context.active_object
|
||||
if ob.type == 'MESH' and ob.mode == 'EDIT' and ob.name != ref.name:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
selected_verts = [v for v in bpy.context.active_object.data.vertices if v.select]
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
# Compute the min/max distance from the reference to mesh vertices
|
||||
min_dist = sys.float_info.max
|
||||
max_dist = -min_dist
|
||||
for ob in selection:
|
||||
for vert in ob.data.vertices:
|
||||
dist = (ob.matrix_world * vert.co - source.location).length
|
||||
if m.type == 'DISTANCE_FROM_CAMERA':
|
||||
ob_to_cam = matrix_to_camera * ob.matrix_world
|
||||
for vert in selected_verts:
|
||||
# dist in the camera space
|
||||
dist = (ob_to_cam * vert.co).length
|
||||
min_dist = min(dist, min_dist)
|
||||
max_dist = max(dist, max_dist)
|
||||
elif m.type == 'DISTANCE_FROM_OBJECT':
|
||||
for vert in selected_verts:
|
||||
# dist in the world space
|
||||
dist = (ob.matrix_world * vert.co - target_location).length
|
||||
min_dist = min(dist, min_dist)
|
||||
max_dist = max(dist, max_dist)
|
||||
# Fill the Range Min/Max entries with the computed distances
|
||||
m.range_min = min_dist
|
||||
m.range_max = max_dist
|
||||
return {'FINISHED'}
|
||||
# Find selected mesh objects
|
||||
selection = [ob for ob in scene.objects if ob.select and ob.type == 'MESH' and ob.name != ref.name]
|
||||
if selection:
|
||||
# Compute the min/max distance from the reference to mesh vertices
|
||||
min_dist = sys.float_info.max
|
||||
max_dist = -min_dist
|
||||
if m.type == 'DISTANCE_FROM_CAMERA':
|
||||
for ob in selection:
|
||||
ob_to_cam = matrix_to_camera * ob.matrix_world
|
||||
for vert in ob.data.vertices:
|
||||
# dist in the camera space
|
||||
dist = (ob_to_cam * vert.co).length
|
||||
min_dist = min(dist, min_dist)
|
||||
max_dist = max(dist, max_dist)
|
||||
elif m.type == 'DISTANCE_FROM_OBJECT':
|
||||
for ob in selection:
|
||||
for vert in ob.data.vertices:
|
||||
# dist in the world space
|
||||
dist = (ob.matrix_world * vert.co - target_location).length
|
||||
min_dist = min(dist, min_dist)
|
||||
max_dist = max(dist, max_dist)
|
||||
# Fill the Range Min/Max entries with the computed distances
|
||||
m.range_min = min_dist
|
||||
m.range_max = max_dist
|
||||
|
@@ -1008,11 +1008,9 @@ class WM_OT_doc_view(Operator):
|
||||
|
||||
doc_id = doc_id
|
||||
if bpy.app.version_cycle == "release":
|
||||
_prefix = ("https://www.blender.org/api/blender_python_api_%s%s_release" %
|
||||
("_".join(str(v) for v in bpy.app.version[:2]), bpy.app.version_char))
|
||||
_prefix = ("https://docs.blender.org/api/blender_python_api_current")
|
||||
else:
|
||||
_prefix = ("https://www.blender.org/api/blender_python_api_%s" %
|
||||
"_".join(str(v) for v in bpy.app.version))
|
||||
_prefix = ("https://docs.blender.org/api/blender_python_api_master")
|
||||
|
||||
def execute(self, context):
|
||||
url = _wm_doc_get_id(self.doc_id, do_url=True, url_prefix=self._prefix)
|
||||
|
@@ -951,6 +951,23 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
||||
def SURFACE(self, layout, ob, md):
|
||||
layout.label(text="Settings are inside the Physics tab")
|
||||
|
||||
def SURFACE_DEFORM(self, layout, ob, md):
|
||||
col = layout.column()
|
||||
col.active = not md.is_bound
|
||||
|
||||
col.prop(md, "target")
|
||||
col.prop(md, "falloff")
|
||||
|
||||
layout.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.active = md.target is not None
|
||||
|
||||
if md.is_bound:
|
||||
col.operator("object.surfacedeform_bind", text="Unbind")
|
||||
else:
|
||||
col.operator("object.surfacedeform_bind", text="Bind")
|
||||
|
||||
def UV_PROJECT(self, layout, ob, md):
|
||||
split = layout.split()
|
||||
|
||||
@@ -1320,7 +1337,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
||||
row.prop(md, "thickness_vertex_group", text="Factor")
|
||||
|
||||
col.prop(md, "use_crease", text="Crease Edges")
|
||||
col.prop(md, "crease_weight", text="Crease Weight")
|
||||
row = col.row()
|
||||
row.active = md.use_crease
|
||||
row.prop(md, "crease_weight", text="Crease Weight")
|
||||
|
||||
col = split.column()
|
||||
|
||||
|
@@ -469,8 +469,86 @@ class SceneButtonsPanel:
|
||||
bl_context = "scene"
|
||||
|
||||
|
||||
class SCENE_PT_game_physics(SceneButtonsPanel, Panel):
|
||||
bl_label = "Physics"
|
||||
COMPAT_ENGINES = {'BLENDER_GAME'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
layout.prop(gs, "physics_engine", text="Engine")
|
||||
if gs.physics_engine != 'NONE':
|
||||
layout.prop(gs, "physics_gravity", text="Gravity")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Physics Steps:")
|
||||
sub = col.column(align=True)
|
||||
sub.prop(gs, "physics_step_max", text="Max")
|
||||
sub.prop(gs, "physics_step_sub", text="Substeps")
|
||||
col.prop(gs, "fps", text="FPS")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Logic Steps:")
|
||||
col.prop(gs, "logic_step_max", text="Max")
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Physics Deactivation:")
|
||||
sub = col.row(align=True)
|
||||
sub.prop(gs, "deactivation_linear_threshold", text="Linear Threshold")
|
||||
sub.prop(gs, "deactivation_angular_threshold", text="Angular Threshold")
|
||||
sub = col.row()
|
||||
sub.prop(gs, "deactivation_time", text="Time")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(gs, "use_occlusion_culling", text="Occlusion Culling")
|
||||
sub = col.column()
|
||||
sub.active = gs.use_occlusion_culling
|
||||
sub.prop(gs, "occlusion_culling_resolution", text="Resolution")
|
||||
|
||||
else:
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Physics Steps:")
|
||||
col.prop(gs, "fps", text="FPS")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Logic Steps:")
|
||||
col.prop(gs, "logic_step_max", text="Max")
|
||||
|
||||
|
||||
class SCENE_PT_game_physics_obstacles(SceneButtonsPanel, Panel):
|
||||
bl_label = "Obstacle Simulation"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_GAME'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
layout.prop(gs, "obstacle_simulation", text="Type")
|
||||
if gs.obstacle_simulation != 'NONE':
|
||||
layout.prop(gs, "level_height")
|
||||
layout.prop(gs, "show_obstacle_simulation")
|
||||
|
||||
|
||||
class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
|
||||
bl_label = "Navigation mesh"
|
||||
bl_label = "Navigation Mesh"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_GAME'}
|
||||
|
||||
@@ -484,7 +562,7 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
|
||||
|
||||
rd = context.scene.game_settings.recast_data
|
||||
|
||||
layout.operator("mesh.navmesh_make", text="Build navigation mesh")
|
||||
layout.operator("mesh.navmesh_make", text="Build Navigation Mesh")
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Rasterization:")
|
||||
@@ -656,83 +734,6 @@ class WORLD_PT_game_mist(WorldButtonsPanel, Panel):
|
||||
layout.prop(world.mist_settings, "intensity", text="Minimum Intensity")
|
||||
|
||||
|
||||
class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
|
||||
bl_label = "Physics"
|
||||
COMPAT_ENGINES = {'BLENDER_GAME'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
layout.prop(gs, "physics_engine", text="Engine")
|
||||
if gs.physics_engine != 'NONE':
|
||||
layout.prop(gs, "physics_gravity", text="Gravity")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Physics Steps:")
|
||||
sub = col.column(align=True)
|
||||
sub.prop(gs, "physics_step_max", text="Max")
|
||||
sub.prop(gs, "physics_step_sub", text="Substeps")
|
||||
col.prop(gs, "fps", text="FPS")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Logic Steps:")
|
||||
col.prop(gs, "logic_step_max", text="Max")
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Physics Deactivation:")
|
||||
sub = col.row(align=True)
|
||||
sub.prop(gs, "deactivation_linear_threshold", text="Linear Threshold")
|
||||
sub.prop(gs, "deactivation_angular_threshold", text="Angular Threshold")
|
||||
sub = col.row()
|
||||
sub.prop(gs, "deactivation_time", text="Time")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(gs, "use_occlusion_culling", text="Occlusion Culling")
|
||||
sub = col.column()
|
||||
sub.active = gs.use_occlusion_culling
|
||||
sub.prop(gs, "occlusion_culling_resolution", text="Resolution")
|
||||
|
||||
else:
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Physics Steps:")
|
||||
col.prop(gs, "fps", text="FPS")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Logic Steps:")
|
||||
col.prop(gs, "logic_step_max", text="Max")
|
||||
|
||||
|
||||
class WORLD_PT_game_physics_obstacles(WorldButtonsPanel, Panel):
|
||||
bl_label = "Obstacle Simulation"
|
||||
COMPAT_ENGINES = {'BLENDER_GAME'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
layout.prop(gs, "obstacle_simulation", text="Type")
|
||||
if gs.obstacle_simulation != 'NONE':
|
||||
layout.prop(gs, "level_height")
|
||||
layout.prop(gs, "show_obstacle_simulation")
|
||||
|
||||
|
||||
class DataButtonsPanel:
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
|
@@ -152,6 +152,33 @@ class OBJECT_PT_relations(ObjectButtonsPanel, Panel):
|
||||
sub.active = (parent is not None)
|
||||
|
||||
|
||||
class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
|
||||
bl_label = "Relations Extras"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if context.scene.render.engine != 'BLENDER_GAME':
|
||||
col = split.column()
|
||||
col.label(text="Tracking Axes:")
|
||||
col.prop(ob, "track_axis", text="Axis")
|
||||
col.prop(ob, "up_axis", text="Up Axis")
|
||||
|
||||
col = split.column()
|
||||
col.prop(ob, "use_slow_parent")
|
||||
row = col.row()
|
||||
row.active = ((ob.parent is not None) and (ob.use_slow_parent))
|
||||
row.prop(ob, "slow_parent_offset", text="Offset")
|
||||
|
||||
layout.prop(ob, "use_extra_recalc_object")
|
||||
layout.prop(ob, "use_extra_recalc_data")
|
||||
|
||||
|
||||
class GROUP_MT_specials(Menu):
|
||||
bl_label = "Group Specials"
|
||||
|
||||
@@ -296,33 +323,6 @@ class OBJECT_PT_duplication(ObjectButtonsPanel, Panel):
|
||||
layout.prop(ob, "dupli_group", text="Group")
|
||||
|
||||
|
||||
class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
|
||||
bl_label = "Relations Extras"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if context.scene.render.engine != 'BLENDER_GAME':
|
||||
col = split.column()
|
||||
col.label(text="Tracking Axes:")
|
||||
col.prop(ob, "track_axis", text="Axis")
|
||||
col.prop(ob, "up_axis", text="Up Axis")
|
||||
|
||||
col = split.column()
|
||||
col.prop(ob, "use_slow_parent")
|
||||
row = col.row()
|
||||
row.active = ((ob.parent is not None) and (ob.use_slow_parent))
|
||||
row.prop(ob, "slow_parent_offset", text="Offset")
|
||||
|
||||
layout.prop(ob, "use_extra_recalc_object")
|
||||
layout.prop(ob, "use_extra_recalc_data")
|
||||
|
||||
|
||||
from bl_ui.properties_animviz import (
|
||||
MotionPathButtonsPanel,
|
||||
OnionSkinButtonsPanel,
|
||||
|
@@ -274,6 +274,8 @@ def basic_force_field_settings_ui(self, context, field):
|
||||
col.prop(field, "use_global_coords", text="Global")
|
||||
elif field.type == 'HARMONIC':
|
||||
col.prop(field, "use_multiple_springs")
|
||||
if field.type == 'FORCE':
|
||||
col.prop(field, "use_gravity_falloff", text="Gravitation")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
|
@@ -377,7 +377,7 @@ class RENDER_PT_stamp(RenderButtonsPanel, Panel):
|
||||
sub.active = rd.use_stamp_note
|
||||
sub.prop(rd, "stamp_note_text", text="")
|
||||
if rd.use_sequencer:
|
||||
layout.label("Sequencer")
|
||||
layout.label("Sequencer:")
|
||||
layout.prop(rd, "use_stamp_strip_meta")
|
||||
|
||||
|
||||
|
@@ -42,10 +42,11 @@ class GRAPH_HT_header(Header):
|
||||
|
||||
dopesheet_filter(layout, context)
|
||||
|
||||
layout.prop(st, "use_normalization", text="Normalize")
|
||||
row = layout.row()
|
||||
row.active = st.use_normalization
|
||||
row.prop(st, "use_auto_normalization", text="Auto")
|
||||
row = layout.row(align=True)
|
||||
row.prop(st, "use_normalization", icon='NORMALIZE_FCURVES', text="Normalize", toggle=True)
|
||||
sub = row.row(align=True)
|
||||
sub.active = st.use_normalization
|
||||
sub.prop(st, "use_auto_normalization", icon='FILE_REFRESH', text="", toggle=True)
|
||||
|
||||
row = layout.row(align=True)
|
||||
|
||||
|
@@ -652,17 +652,39 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
|
||||
col.prop(strip, "rotation_start", text="Rotation")
|
||||
|
||||
elif strip.type == 'MULTICAM':
|
||||
layout.prop(strip, "multicam_source")
|
||||
col = layout.column(align=True)
|
||||
strip_channel = strip.channel
|
||||
|
||||
row = layout.row(align=True)
|
||||
sub = row.row(align=True)
|
||||
sub.scale_x = 2.0
|
||||
col.prop(strip, "multicam_source", text="Source Channel")
|
||||
|
||||
sub.operator("screen.animation_play", text="", icon='PAUSE' if context.screen.is_animation_playing else 'PLAY')
|
||||
# The multicam strip needs at least 2 strips to be useful
|
||||
if strip_channel > 2:
|
||||
BT_ROW = 4
|
||||
|
||||
col.label("Cut To:")
|
||||
row = col.row()
|
||||
|
||||
for i in range(1, strip_channel):
|
||||
if (i % BT_ROW) == 1:
|
||||
row = col.row(align=True)
|
||||
|
||||
# Workaround - .enabled has to have a separate UI block to work
|
||||
if i == strip.multicam_source:
|
||||
sub = row.row(align=True)
|
||||
sub.enabled = False
|
||||
sub.operator("sequencer.cut_multicam", text="%d" % i).camera = i
|
||||
else:
|
||||
sub_1 = row.row(align=True)
|
||||
sub_1.enabled = True
|
||||
sub_1.operator("sequencer.cut_multicam", text="%d" % i).camera = i
|
||||
|
||||
if strip.channel > BT_ROW and (strip_channel - 1) % BT_ROW:
|
||||
for i in range(strip.channel, strip_channel + ((BT_ROW + 1 - strip_channel) % BT_ROW)):
|
||||
row.label("")
|
||||
else:
|
||||
col.separator()
|
||||
col.label(text="Two or more channels are needed below this strip", icon="INFO")
|
||||
|
||||
row.label("Cut To")
|
||||
for i in range(1, strip.channel):
|
||||
row.operator("sequencer.cut_multicam", text="%d" % i).camera = i
|
||||
|
||||
elif strip.type == 'TEXT':
|
||||
col = layout.column()
|
||||
|
@@ -49,7 +49,10 @@ class TIME_HT_header(Header):
|
||||
row.prop(scene, "frame_preview_start", text="Start")
|
||||
row.prop(scene, "frame_preview_end", text="End")
|
||||
|
||||
layout.prop(scene, "frame_current", text="")
|
||||
if scene.show_subframe:
|
||||
layout.prop(scene, "frame_float", text="")
|
||||
else:
|
||||
layout.prop(scene, "frame_current", text="")
|
||||
|
||||
layout.separator()
|
||||
|
||||
@@ -135,6 +138,7 @@ class TIME_MT_view(Menu):
|
||||
|
||||
layout.prop(st, "show_frame_indicator")
|
||||
layout.prop(scene, "show_keys_from_selected_only")
|
||||
layout.prop(scene, "show_subframe")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@@ -1243,7 +1243,7 @@ class USERPREF_MT_addons_online_resources(Menu):
|
||||
"wm.url_open", text="API Concepts", icon='URL',
|
||||
).url = bpy.types.WM_OT_doc_view._prefix + "/info_quickstart.html"
|
||||
layout.operator("wm.url_open", text="Add-on Tutorial", icon='URL',
|
||||
).url = "http://www.blender.org/api/blender_python_api_current/info_tutorial_addon.html"
|
||||
).url = bpy.types.WM_OT_doc_view._prefix + "/info_tutorial_addon.html"
|
||||
|
||||
|
||||
class USERPREF_PT_addons(Panel):
|
||||
@@ -1317,11 +1317,18 @@ class USERPREF_PT_addons(Panel):
|
||||
|
||||
# set in addon_utils.modules_refresh()
|
||||
if addon_utils.error_duplicates:
|
||||
self.draw_error(col,
|
||||
"Multiple addons using the same name found!\n"
|
||||
"likely a problem with the script search path.\n"
|
||||
"(see console for details)",
|
||||
)
|
||||
box = col.box()
|
||||
row = box.row()
|
||||
row.label("Multiple addons with the same name found!")
|
||||
row.label(icon='ERROR')
|
||||
box.label("Please delete one of each pair:")
|
||||
for (addon_name, addon_file, addon_path) in addon_utils.error_duplicates:
|
||||
box.separator()
|
||||
sub_col = box.column(align=True)
|
||||
sub_col.label(addon_name + ":")
|
||||
sub_col.label(" " + addon_file)
|
||||
sub_col.label(" " + addon_path)
|
||||
|
||||
|
||||
if addon_utils.error_encoding:
|
||||
self.draw_error(col,
|
||||
|
@@ -1346,9 +1346,9 @@ class VIEW3D_MT_object_clear(Menu):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("object.location_clear", text="Location")
|
||||
layout.operator("object.rotation_clear", text="Rotation")
|
||||
layout.operator("object.scale_clear", text="Scale")
|
||||
layout.operator("object.location_clear", text="Location").clear_delta = False
|
||||
layout.operator("object.rotation_clear", text="Rotation").clear_delta = False
|
||||
layout.operator("object.scale_clear", text="Scale").clear_delta = False
|
||||
layout.operator("object.origin_clear", text="Origin")
|
||||
|
||||
|
||||
@@ -1744,6 +1744,7 @@ class VIEW3D_MT_brush_paint_modes(Menu):
|
||||
layout.prop(brush, "use_paint_weight", text="Weight Paint")
|
||||
layout.prop(brush, "use_paint_image", text="Texture Paint")
|
||||
|
||||
|
||||
# ********** Vertex paint menu **********
|
||||
|
||||
|
||||
@@ -1813,6 +1814,7 @@ class VIEW3D_MT_vertex_group(Menu):
|
||||
layout.operator("object.vertex_group_remove", text="Remove Active Group").all = False
|
||||
layout.operator("object.vertex_group_remove", text="Remove All Groups").all = True
|
||||
|
||||
|
||||
# ********** Weight paint menu **********
|
||||
|
||||
|
||||
@@ -1851,6 +1853,7 @@ class VIEW3D_MT_paint_weight(Menu):
|
||||
|
||||
layout.operator("paint.weight_set")
|
||||
|
||||
|
||||
# ********** Sculpt menu **********
|
||||
|
||||
|
||||
@@ -2004,6 +2007,7 @@ class VIEW3D_MT_particle_specials(Menu):
|
||||
class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu):
|
||||
_operator_name = "particle"
|
||||
|
||||
|
||||
# ********** Pose Menu **********
|
||||
|
||||
|
||||
@@ -2277,6 +2281,7 @@ class VIEW3D_MT_bone_options_disable(Menu, BoneOptions):
|
||||
bl_label = "Disable Bone Options"
|
||||
type = 'DISABLE'
|
||||
|
||||
|
||||
# ********** Edit Menus, suffix from ob.type **********
|
||||
|
||||
|
||||
@@ -2444,6 +2449,7 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
|
||||
with_bullet = bpy.app.build_options.bullet
|
||||
|
||||
layout.operator("mesh.merge")
|
||||
layout.operator("mesh.remove_doubles")
|
||||
layout.operator("mesh.rip_move")
|
||||
layout.operator("mesh.rip_move_fill")
|
||||
layout.operator("mesh.rip_edge_move")
|
||||
@@ -2466,7 +2472,6 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
|
||||
if with_bullet:
|
||||
layout.operator("mesh.convex_hull")
|
||||
layout.operator("mesh.vertices_smooth")
|
||||
layout.operator("mesh.remove_doubles")
|
||||
|
||||
layout.operator("mesh.blend_from_shape")
|
||||
|
||||
@@ -2623,6 +2628,7 @@ class VIEW3D_MT_edit_mesh_clean(Menu):
|
||||
layout.operator("mesh.face_make_planar")
|
||||
layout.operator("mesh.vert_connect_nonplanar")
|
||||
layout.operator("mesh.vert_connect_concave")
|
||||
layout.operator("mesh.remove_doubles")
|
||||
layout.operator("mesh.fill_holes")
|
||||
|
||||
|
||||
|
@@ -113,25 +113,25 @@ static OArchive create_archive(std::ostream *ostream,
|
||||
Alembic::Abc::MetaData &md,
|
||||
bool ogawa)
|
||||
{
|
||||
md.set(Alembic::Abc::kApplicationNameKey, "Blender");
|
||||
md.set(Alembic::Abc::kApplicationNameKey, "Blender");
|
||||
md.set(Alembic::Abc::kUserDescriptionKey, scene_name);
|
||||
|
||||
time_t raw_time;
|
||||
time(&raw_time);
|
||||
char buffer[128];
|
||||
time_t raw_time;
|
||||
time(&raw_time);
|
||||
char buffer[128];
|
||||
|
||||
#if defined _WIN32 || defined _WIN64
|
||||
ctime_s(buffer, 128, &raw_time);
|
||||
ctime_s(buffer, 128, &raw_time);
|
||||
#else
|
||||
ctime_r(&raw_time, buffer);
|
||||
ctime_r(&raw_time, buffer);
|
||||
#endif
|
||||
|
||||
const std::size_t buffer_len = strlen(buffer);
|
||||
if (buffer_len > 0 && buffer[buffer_len - 1] == '\n') {
|
||||
buffer[buffer_len - 1] = '\0';
|
||||
}
|
||||
const std::size_t buffer_len = strlen(buffer);
|
||||
if (buffer_len > 0 && buffer[buffer_len - 1] == '\n') {
|
||||
buffer[buffer_len - 1] = '\0';
|
||||
}
|
||||
|
||||
md.set(Alembic::Abc::kDateWrittenKey, buffer);
|
||||
md.set(Alembic::Abc::kDateWrittenKey, buffer);
|
||||
|
||||
ErrorHandler::Policy policy = ErrorHandler::kThrowPolicy;
|
||||
|
||||
|
@@ -102,7 +102,7 @@ void AbcCurveWriter::do_write()
|
||||
const BPoint *point = nurbs->bp;
|
||||
|
||||
for (int i = 0; i < totpoint; ++i, ++point) {
|
||||
copy_zup_yup(temp_vert.getValue(), point->vec);
|
||||
copy_yup_from_zup(temp_vert.getValue(), point->vec);
|
||||
verts.push_back(temp_vert);
|
||||
weights.push_back(point->vec[3]);
|
||||
widths.push_back(point->radius);
|
||||
@@ -118,7 +118,7 @@ void AbcCurveWriter::do_write()
|
||||
|
||||
/* TODO(kevin): store info about handles, Alembic doesn't have this. */
|
||||
for (int i = 0; i < totpoint; ++i, ++bezier) {
|
||||
copy_zup_yup(temp_vert.getValue(), bezier->vec[1]);
|
||||
copy_yup_from_zup(temp_vert.getValue(), bezier->vec[1]);
|
||||
verts.push_back(temp_vert);
|
||||
widths.push_back(bezier->radius);
|
||||
}
|
||||
@@ -322,7 +322,7 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
|
||||
weight = (*weights)[idx];
|
||||
}
|
||||
|
||||
copy_yup_zup(bp->vec, pos.getValue());
|
||||
copy_zup_from_yup(bp->vec, pos.getValue());
|
||||
bp->vec[3] = weight;
|
||||
bp->f1 = SELECT;
|
||||
bp->radius = radius;
|
||||
@@ -361,7 +361,7 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
|
||||
* object directly and create a new DerivedMesh from that. Also we might need to
|
||||
* create new or delete existing NURBS in the curve.
|
||||
*/
|
||||
DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float time, int /*read_flag*/, const char **/*err_str*/)
|
||||
DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh * /*dm*/, const float time, int /*read_flag*/, const char ** /*err_str*/)
|
||||
{
|
||||
ISampleSelector sample_sel(time);
|
||||
const ICurvesSchema::Sample sample = m_curves_schema.getValue(sample_sel);
|
||||
@@ -389,7 +389,7 @@ DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float t
|
||||
|
||||
for (int i = 0; i < totpoint; ++i, ++point, ++vertex_idx) {
|
||||
const Imath::V3f &pos = (*positions)[vertex_idx];
|
||||
copy_yup_zup(point->vec, pos.getValue());
|
||||
copy_zup_from_yup(point->vec, pos.getValue());
|
||||
}
|
||||
}
|
||||
else if (nurbs->bezt) {
|
||||
@@ -397,7 +397,7 @@ DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float t
|
||||
|
||||
for (int i = 0; i < totpoint; ++i, ++bezier, ++vertex_idx) {
|
||||
const Imath::V3f &pos = (*positions)[vertex_idx];
|
||||
copy_yup_zup(bezier->vec[1], pos.getValue());
|
||||
copy_zup_from_yup(bezier->vec[1], pos.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -327,6 +327,11 @@ static void read_custom_data_ex(const ICompoundProperty &prop,
|
||||
}
|
||||
else if (data_type == CD_MLOOPUV) {
|
||||
IV2fGeomParam uv_param(prop, prop_header.getName());
|
||||
|
||||
if (!uv_param.isIndexed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
IV2fGeomParam::Sample sample;
|
||||
uv_param.getIndexed(sample, iss);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user