Compare commits
409 Commits
info-edito
...
blender-v2
Author | SHA1 | Date | |
---|---|---|---|
8928d99270 | |||
9e707802c2 | |||
09aaee5640 | |||
dc5aaac3a2 | |||
a4dbff33c9 | |||
59cc0bfef5 | |||
9268ff4b21 | |||
7ae9b96ac6 | |||
bc891ad124 | |||
3982a36c10 | |||
f5c0df3601 | |||
81697c772c | |||
6f45c9d6c6 | |||
d1281bf993 | |||
c40e9a1ad2 | |||
21f19224f3 | |||
f6abf9d0ba | |||
e5917d624e | |||
bac2541ffa | |||
3e2909cf9d | |||
1052497aad | |||
567b4fa794 | |||
d7c7ce2a7b | |||
de563552da | |||
3ee1a7978f | |||
a73b390f48 | |||
0e37c98257 | |||
4c1bed0a12 | |||
2f5a027b94 | |||
61335d853d | |||
43d1bfea40 | |||
4cda3e2d87 | |||
dc4afef1da | |||
8553449cf2 | |||
af83535dd0 | |||
a3616980c6 | |||
2f6d7946a4 | |||
c3237cdc13 | |||
417170159a | |||
6036bf7497 | |||
a50c381fac | |||
b90f3928a3 | |||
cae8c68ca6 | |||
79563d2a33 | |||
b6481cbbe5 | |||
5b3538e02a | |||
c3873a5156 | |||
8dbd5ea4c8 | |||
9287434fa1 | |||
2ae9d757b3 | |||
04c5131281 | |||
16718fe4ea | |||
a972729895 | |||
5ddcad4377 | |||
f72e6fcdfa | |||
91ce295796 | |||
13973a5bbf | |||
824c039230 | |||
![]() |
a623c02569 | ||
![]() |
b3adce7766 | ||
30a0459f2c | |||
2ca933f457 | |||
f12ab4e196 | |||
7b8b621c1d | |||
6a86a1f082 | |||
e9548a6184 | |||
20cccb1561 | |||
57b11d8b4e | |||
38357cd004 | |||
d0e0f33f57 | |||
db74c06dd6 | |||
e4e2e3a15d | |||
71e0894e0d | |||
72151f3e36 | |||
83b0603061 | |||
b01fe3bf01 | |||
4c8aa61be2 | |||
a1d05ac2a1 | |||
0c365472b6 | |||
010cf35e7e | |||
2a9abc0f5e | |||
![]() |
e4dce3b3d7 | ||
243b961c29 | |||
42e207b599 | |||
32fb50179f | |||
![]() |
c70a45027d | ||
8f7030e5f3 | |||
405874bd79 | |||
6afe655be0 | |||
c721f93958 | |||
dfed7c48ac | |||
391f7cc406 | |||
b6f3fec259 | |||
49f57e5346 | |||
9a5320aea3 | |||
85dc915413 | |||
4c46f69376 | |||
b8bdca8c0a | |||
ba40d8f331 | |||
3ad84309df | |||
09c387269a | |||
259e9ad00d | |||
d305c10104 | |||
9f916baa70 | |||
754630cee4 | |||
00d8097510 | |||
7377b36660 | |||
17c00d222f | |||
1b8e8326b4 | |||
3ffb0f6983 | |||
6f19787e52 | |||
0596d208a0 | |||
76032b133c | |||
8cdda3d2ad | |||
7103c6ef3b | |||
075950ad66 | |||
93d711ce55 | |||
d91b6099a6 | |||
d5dbe0c566 | |||
c8f95c7829 | |||
26ffade5c1 | |||
1611177ac9 | |||
1c32d67f46 | |||
c63e08863d | |||
528e00dae0 | |||
a123dafdc0 | |||
![]() |
1f50f0676a | ||
4f247ed07a | |||
868bde5920 | |||
02b206780e | |||
8ca11b7084 | |||
8c484d0bda | |||
3815c3a324 | |||
36971ea276 | |||
38fdfe757d | |||
6cba84edf2 | |||
9f0ebb0941 | |||
571e801b27 | |||
942b6e933b | |||
eaeb0a002e | |||
71d79e6ea2 | |||
a68cc528dd | |||
e79e0c7483 | |||
4a457d4f1e | |||
1b6130533f | |||
9d501d23cb | |||
39fc93208a | |||
9298d99b77 | |||
9e18fcbb36 | |||
ef5b7d34a1 | |||
426616da43 | |||
9be59fa752 | |||
93d3015e61 | |||
fe3f504902 | |||
9299936726 | |||
8131eda51e | |||
569d2df634 | |||
6e133ad8b1 | |||
58ab62ed6d | |||
0834eefae0 | |||
34857b2032 | |||
78cc3c828f | |||
04125d8a9c | |||
659dc34823 | |||
eaf14b1ebf | |||
866be3423c | |||
440d647cc1 | |||
cd9c68f0c5 | |||
f1ee24a284 | |||
df1af9b349 | |||
836a1ccf72 | |||
c4f8d924e1 | |||
08e16e0bd1 | |||
969196069a | |||
6cfc5edb86 | |||
99e4c819f7 | |||
ca236408f3 | |||
f887b8b230 | |||
48079e1f11 | |||
bae796f0d5 | |||
![]() |
02bac54fa9 | ||
![]() |
8f9d9ba14e | ||
![]() |
576899b90a | ||
0f841e24b0 | |||
![]() |
ce35151f38 | ||
3659620b47 | |||
f3002ab43b | |||
3a1ade22e5 | |||
b5c629e604 | |||
89de073ea5 | |||
0cdfe887b4 | |||
7de7e47a97 | |||
2213153c27 | |||
ef04aa4a43 | |||
538182511a | |||
3532fe2b8b | |||
3182336666 | |||
5efc8e16e6 | |||
7947eead71 | |||
8cd3bd99f7 | |||
e7aad8fd0e | |||
bf58ec9265 | |||
1c7657befb | |||
333ef6e6f7 | |||
ad7385422e | |||
ad834085b7 | |||
2edc2b4912 | |||
d87bf29399 | |||
990ce0c4f0 | |||
f0743b56ec | |||
350f5c6894 | |||
69062cdd8d | |||
3163d0e205 | |||
aafe528c7d | |||
9c39f021ad | |||
cdc35e63bd | |||
3a0f199aa7 | |||
b0c55d5c94 | |||
759af7f1ee | |||
4bc89d815c | |||
8a9d64b578 | |||
50ca70b275 | |||
ff8c9c5931 | |||
06df30a415 | |||
5f2307d1a7 | |||
3193045c59 | |||
2895cb22a7 | |||
01ff07af56 | |||
6d640504e8 | |||
5ab1897de7 | |||
75aec5eeaa | |||
0c456eb90a | |||
6639350f92 | |||
ce6e30b3dc | |||
69f6ab98e7 | |||
3e3a27d089 | |||
a253b1b7bc | |||
6058b651c4 | |||
98dc9072e5 | |||
6b2d1f63db | |||
275002106c | |||
413817a3d2 | |||
869e4a3420 | |||
84361a0709 | |||
52a5daa404 | |||
db3e3f9c24 | |||
19b27d84ab | |||
480b0b5dfc | |||
7153cee305 | |||
d2d207773e | |||
8ea3f6438d | |||
60e8d86fb1 | |||
1ab828d4bb | |||
7f6e9c595b | |||
b0fbe95a1b | |||
8c9bebfe28 | |||
9f032c3867 | |||
eaba111bd5 | |||
b969f7eb55 | |||
4c3e2518c8 | |||
a437b9bbbe | |||
d07011da71 | |||
acae901a10 | |||
495aa77b53 | |||
e627620efd | |||
7d872629c4 | |||
60bfa969e2 | |||
d89353159f | |||
21ecdacdf1 | |||
0641069778 | |||
5b2d5f9077 | |||
f901bf6f47 | |||
198fd0be43 | |||
f968268c1e | |||
2bc667ec79 | |||
d564beda44 | |||
f1a4e130b3 | |||
36f324fc55 | |||
bb89759624 | |||
825aecaee3 | |||
1dbdcfe9a9 | |||
a6e5558194 | |||
6bd1189e5c | |||
625b2f5dab | |||
20c96cce86 | |||
c85a305c09 | |||
30f53d56b6 | |||
47a388b2a9 | |||
9f6d5d679e | |||
a4116673c7 | |||
7e4be7d348 | |||
8e43a9e9cc | |||
5384b2a6e2 | |||
e8e40b171b | |||
882fe36f0d | |||
855d2955c4 | |||
8ef39d5c88 | |||
5bd8ac9abf | |||
9a9e9b1c4d | |||
904831e62e | |||
1a7dda046b | |||
82466852fe | |||
fbb4be061c | |||
87cc8550e2 | |||
ccf1bb11b6 | |||
9ae35fafb6 | |||
7c3b435c3a | |||
9cc7e32f39 | |||
9f0acc2c9e | |||
300abf241e | |||
9da098536d | |||
3aaf908719 | |||
a67aae98fe | |||
163a196f29 | |||
b895c7337e | |||
a8bd08ffdd | |||
e91f9f664d | |||
d84f559555 | |||
ec50734106 | |||
a8c7f1329b | |||
9b7d506779 | |||
2deeec9e28 | |||
![]() |
9ca3d4cbbd | ||
0bee126977 | |||
c9d653e560 | |||
1ae3056261 | |||
5f17d47629 | |||
edded659c6 | |||
95d871c1a2 | |||
4b90830cac | |||
a1e8ef264f | |||
f5d02f055f | |||
ed0429e7e6 | |||
27c42e05c4 | |||
374ddd022c | |||
8a254b6271 | |||
8193e50fd3 | |||
8c4b4fdd14 | |||
5fd4eca8c0 | |||
6fec06926e | |||
bb92bb5329 | |||
7997646c2d | |||
0ed5605bd5 | |||
76e8dcafa3 | |||
73cdf00ea8 | |||
![]() |
ecdb16d1d8 | ||
022b9676b0 | |||
e9ca9dd5d7 | |||
82a6889d83 | |||
a5213924a8 | |||
42760d922e | |||
6f4a0c23cc | |||
fc26280bcb | |||
75e392ae9f | |||
6825439b36 | |||
f2aa9bec9d | |||
8cb217069e | |||
9997f5ca91 | |||
63e21e7218 | |||
dd84324485 | |||
d2f20aed04 | |||
c0a9fdd93f | |||
e00f3a6565 | |||
6692af3997 | |||
058a358e98 | |||
ba600ff7fa | |||
fd0fbf2564 | |||
beea9421bd | |||
7b397cdfc8 | |||
d48f4b61c9 | |||
9bc5549222 | |||
6bc962d7bc | |||
e6830167e2 | |||
f21020f45f | |||
455c016ba6 | |||
6e7d962118 | |||
210f839e93 | |||
b1d998ec5d | |||
78c288d377 | |||
2307ea88b5 | |||
8138082ab8 | |||
265d620179 | |||
2ff041b7a5 | |||
edd0dbd23b | |||
8604557b75 | |||
a52ec5308f | |||
0cb38b2875 | |||
6f935dbb38 | |||
![]() |
10764d31d4 | ||
69c389fd63 | |||
686b8e8fed | |||
0aae208749 | |||
3689be736b | |||
9a239eea68 | |||
28451a9cec | |||
efa840f99f | |||
518d690628 | |||
35f5d80f3a | |||
0d86bc9f98 | |||
ff47118c73 | |||
0146ab2fd5 | |||
e54df78c82 | |||
909320e3ff | |||
fa34f864a2 | |||
205202361c | |||
fb73cee1ec | |||
8ae6e35923 | |||
ade9fc9245 | |||
5e9132b3b7 |
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -2,7 +2,7 @@
|
|||||||
path = release/scripts/addons
|
path = release/scripts/addons
|
||||||
url = ../blender-addons.git
|
url = ../blender-addons.git
|
||||||
ignore = all
|
ignore = all
|
||||||
branch = master
|
branch = blender-v2.79-release
|
||||||
[submodule "release/scripts/addons_contrib"]
|
[submodule "release/scripts/addons_contrib"]
|
||||||
path = release/scripts/addons_contrib
|
path = release/scripts/addons_contrib
|
||||||
url = ../blender-addons-contrib.git
|
url = ../blender-addons-contrib.git
|
||||||
@@ -12,9 +12,9 @@
|
|||||||
path = release/datafiles/locale
|
path = release/datafiles/locale
|
||||||
url = ../blender-translations.git
|
url = ../blender-translations.git
|
||||||
ignore = all
|
ignore = all
|
||||||
branch = master
|
branch = blender-v2.79-release
|
||||||
[submodule "source/tools"]
|
[submodule "source/tools"]
|
||||||
path = source/tools
|
path = source/tools
|
||||||
url = ../blender-dev-tools.git
|
url = ../blender-dev-tools.git
|
||||||
ignore = all
|
ignore = all
|
||||||
branch = master
|
branch = blender-v2.79-release
|
||||||
|
@@ -285,6 +285,7 @@ endif()
|
|||||||
if(WITH_X11)
|
if(WITH_X11)
|
||||||
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
|
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
|
||||||
option(WITH_X11_XF86VMODE "Enable X11 video mode switching" ON)
|
option(WITH_X11_XF86VMODE "Enable X11 video mode switching" ON)
|
||||||
|
option(WITH_X11_XFIXES "Enable X11 XWayland cursor warping workaround" ON)
|
||||||
option(WITH_X11_ALPHA "Enable X11 transparent background" ON)
|
option(WITH_X11_ALPHA "Enable X11 transparent background" ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -686,6 +687,7 @@ if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
|||||||
set(WITH_X11 OFF)
|
set(WITH_X11 OFF)
|
||||||
set(WITH_X11_XINPUT OFF)
|
set(WITH_X11_XINPUT OFF)
|
||||||
set(WITH_X11_XF86VMODE OFF)
|
set(WITH_X11_XF86VMODE OFF)
|
||||||
|
set(WITH_X11_XFIXES OFF)
|
||||||
set(WITH_X11_ALPHA OFF)
|
set(WITH_X11_ALPHA OFF)
|
||||||
set(WITH_GHOST_XDND OFF)
|
set(WITH_GHOST_XDND OFF)
|
||||||
set(WITH_INPUT_IME OFF)
|
set(WITH_INPUT_IME OFF)
|
||||||
@@ -830,6 +832,14 @@ if(WITH_X11)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_X11_XFIXES)
|
||||||
|
if(X11_Xfixes_LIB)
|
||||||
|
list(APPEND PLATFORM_LINKLIBS ${X11_Xfixes_LIB})
|
||||||
|
else()
|
||||||
|
set(WITH_X11_XFIXES OFF)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_X11_ALPHA)
|
if(WITH_X11_ALPHA)
|
||||||
find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH})
|
find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH})
|
||||||
mark_as_advanced(X11_Xrender_LIB)
|
mark_as_advanced(X11_Xrender_LIB)
|
||||||
@@ -1696,6 +1706,7 @@ if(FIRST_RUN)
|
|||||||
info_cfg_option(WITH_INSTALL_PORTABLE)
|
info_cfg_option(WITH_INSTALL_PORTABLE)
|
||||||
info_cfg_option(WITH_X11_ALPHA)
|
info_cfg_option(WITH_X11_ALPHA)
|
||||||
info_cfg_option(WITH_X11_XF86VMODE)
|
info_cfg_option(WITH_X11_XF86VMODE)
|
||||||
|
info_cfg_option(WITH_X11_XFIXES)
|
||||||
info_cfg_option(WITH_X11_XINPUT)
|
info_cfg_option(WITH_X11_XINPUT)
|
||||||
info_cfg_option(WITH_MEM_JEMALLOC)
|
info_cfg_option(WITH_MEM_JEMALLOC)
|
||||||
info_cfg_option(WITH_MEM_VALGRIND)
|
info_cfg_option(WITH_MEM_VALGRIND)
|
||||||
|
@@ -761,8 +761,8 @@ OIIO_SOURCE=( "https://github.com/OpenImageIO/oiio/archive/Release-$OIIO_VERSION
|
|||||||
OIIO_SOURCE_REPO=( "https://github.com/OpenImageIO/oiio.git" )
|
OIIO_SOURCE_REPO=( "https://github.com/OpenImageIO/oiio.git" )
|
||||||
OIIO_SOURCE_REPO_UID="c9e67275a0b248ead96152f6d2221cc0c0f278a4"
|
OIIO_SOURCE_REPO_UID="c9e67275a0b248ead96152f6d2221cc0c0f278a4"
|
||||||
|
|
||||||
LLVM_SOURCE=( "http://llvm.org/releases/$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.gz" )
|
LLVM_SOURCE=( "http://releases.llvm.org/$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.gz" )
|
||||||
LLVM_CLANG_SOURCE=( "http://llvm.org/releases/$LLVM_VERSION/clang-$LLVM_VERSION.src.tar.gz" "http://llvm.org/releases/$LLVM_VERSION/cfe-$LLVM_VERSION.src.tar.gz" )
|
LLVM_CLANG_SOURCE=( "http://releases.llvm.org/$LLVM_VERSION/clang-$LLVM_VERSION.src.tar.gz" "http://llvm.org/releases/$LLVM_VERSION/cfe-$LLVM_VERSION.src.tar.gz" )
|
||||||
|
|
||||||
OSL_USE_REPO=false
|
OSL_USE_REPO=false
|
||||||
OSL_SOURCE=( "https://github.com/imageworks/OpenShadingLanguage/archive/Release-$OSL_VERSION.tar.gz" )
|
OSL_SOURCE=( "https://github.com/imageworks/OpenShadingLanguage/archive/Release-$OSL_VERSION.tar.gz" )
|
||||||
@@ -1262,7 +1262,11 @@ compile_Boost() {
|
|||||||
#### Build OCIO ####
|
#### Build OCIO ####
|
||||||
_init_ocio() {
|
_init_ocio() {
|
||||||
_src=$SRC/OpenColorIO-$OCIO_VERSION
|
_src=$SRC/OpenColorIO-$OCIO_VERSION
|
||||||
_git=false
|
if [ "$OCIO_USE_REPO" = true ]; then
|
||||||
|
_git=true
|
||||||
|
else
|
||||||
|
_git=false
|
||||||
|
fi
|
||||||
_inst=$INST/ocio-$OCIO_VERSION
|
_inst=$INST/ocio-$OCIO_VERSION
|
||||||
_inst_shortcut=$INST/ocio
|
_inst_shortcut=$INST/ocio
|
||||||
}
|
}
|
||||||
@@ -1599,7 +1603,7 @@ compile_OIIO() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# To be changed each time we make edits that would modify the compiled result!
|
# To be changed each time we make edits that would modify the compiled result!
|
||||||
oiio_magic=16
|
oiio_magic=17
|
||||||
_init_oiio
|
_init_oiio
|
||||||
|
|
||||||
# Clean install if needed!
|
# Clean install if needed!
|
||||||
@@ -1663,6 +1667,9 @@ compile_OIIO() {
|
|||||||
INFO "ILMBASE_HOME=$INST/openexr"
|
INFO "ILMBASE_HOME=$INST/openexr"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ptex is only needed when nicholas bishop is ready
|
||||||
|
cmake_d="$cmake_d -D USE_PTEX=OFF"
|
||||||
|
|
||||||
# Optional tests and cmd tools
|
# Optional tests and cmd tools
|
||||||
cmake_d="$cmake_d -D USE_QT=OFF"
|
cmake_d="$cmake_d -D USE_QT=OFF"
|
||||||
cmake_d="$cmake_d -D USE_PYTHON=OFF"
|
cmake_d="$cmake_d -D USE_PYTHON=OFF"
|
||||||
|
@@ -70,7 +70,7 @@ set(FFMPEG_LIBRARIES
|
|||||||
)
|
)
|
||||||
|
|
||||||
# SndFile libraries
|
# SndFile libraries
|
||||||
set(SNDFILE_LIBRARY "/usr/lib/libsndfile.a;/usr/lib/libFLAC.a" CACHE STRING "" FORCE)
|
set(SNDFILE_LIBRARY "/usr/lib${MULTILIB}/libsndfile.a;/usr/lib${MULTILIB}/libFLAC.a" CACHE STRING "" FORCE)
|
||||||
|
|
||||||
# OpenAL libraries
|
# OpenAL libraries
|
||||||
set(OPENAL_ROOT_DIR "/opt/lib/openal" CACHE STRING "" FORCE)
|
set(OPENAL_ROOT_DIR "/opt/lib/openal" CACHE STRING "" FORCE)
|
||||||
|
@@ -76,6 +76,8 @@ IF(OPENIMAGEIO_FOUND)
|
|||||||
SET(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIR})
|
SET(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIR})
|
||||||
IF(EXISTS ${OPENIMAGEIO_INCLUDE_DIR}/OpenImageIO/pugixml.hpp)
|
IF(EXISTS ${OPENIMAGEIO_INCLUDE_DIR}/OpenImageIO/pugixml.hpp)
|
||||||
SET(OPENIMAGEIO_PUGIXML_FOUND TRUE)
|
SET(OPENIMAGEIO_PUGIXML_FOUND TRUE)
|
||||||
|
ELSE()
|
||||||
|
SET(OPENIMAGEIO_PUGIXML_FOUND FALSE)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(OPENIMAGEIO_PUGIXML_FOUND FALSE)
|
SET(OPENIMAGEIO_PUGIXML_FOUND FALSE)
|
||||||
|
@@ -61,10 +61,8 @@ def replace_line(f, i, text, keep_indent=True):
|
|||||||
|
|
||||||
def source_list(path, filename_check=None):
|
def source_list(path, filename_check=None):
|
||||||
for dirpath, dirnames, filenames in os.walk(path):
|
for dirpath, dirnames, filenames in os.walk(path):
|
||||||
|
|
||||||
# skip '.git'
|
# skip '.git'
|
||||||
if dirpath.startswith("."):
|
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
|
||||||
continue
|
|
||||||
|
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
if filename_check is None or filename_check(filename):
|
if filename_check is None or filename_check(filename):
|
||||||
|
@@ -84,10 +84,8 @@ def init(cmake_path):
|
|||||||
|
|
||||||
def source_list(path, filename_check=None):
|
def source_list(path, filename_check=None):
|
||||||
for dirpath, dirnames, filenames in os.walk(path):
|
for dirpath, dirnames, filenames in os.walk(path):
|
||||||
|
# skip '.git'
|
||||||
# skip '.svn'
|
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
|
||||||
if dirpath.startswith("."):
|
|
||||||
continue
|
|
||||||
|
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
filepath = join(dirpath, filename)
|
filepath = join(dirpath, filename)
|
||||||
|
38
doc/python_api/examples/bpy.types.Operator.6.py
Normal file
38
doc/python_api/examples/bpy.types.Operator.6.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
"""
|
||||||
|
Enum Search Popup
|
||||||
|
+++++++++++++++++
|
||||||
|
|
||||||
|
You may want to have an operator prompt the user to select an item
|
||||||
|
from a search field, this can be done using :class:`bpy.types.Operator.invoke_search_popup`.
|
||||||
|
"""
|
||||||
|
import bpy
|
||||||
|
from bpy.props import EnumProperty
|
||||||
|
|
||||||
|
|
||||||
|
class SearchEnumOperator(bpy.types.Operator):
|
||||||
|
bl_idname = "object.search_enum_operator"
|
||||||
|
bl_label = "Search Enum Operator"
|
||||||
|
bl_property = "my_search"
|
||||||
|
|
||||||
|
my_search = EnumProperty(
|
||||||
|
name="My Search",
|
||||||
|
items=(
|
||||||
|
('FOO', "Foo", ""),
|
||||||
|
('BAR', "Bar", ""),
|
||||||
|
('BAZ', "Baz", ""),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
self.report({'INFO'}, "Selected:" + self.my_search)
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
context.window_manager.invoke_search_popup(self)
|
||||||
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
|
bpy.utils.register_class(SearchEnumOperator)
|
||||||
|
|
||||||
|
# test call
|
||||||
|
bpy.ops.object.search_enum_operator('INVOKE_DEFAULT')
|
File diff suppressed because it is too large
Load Diff
17
extern/carve/carve-capi.cc
vendored
17
extern/carve/carve-capi.cc
vendored
@@ -568,6 +568,22 @@ void cleanupFaceEdgeAttrsCallback(const MeshSet<3> *left,
|
|||||||
&descr->orig_face_edge_mapping);
|
&descr->orig_face_edge_mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void copyVertexAttrsCallback(const carve::mesh::MeshSet<3>::vertex_t *orig_vert,
|
||||||
|
const carve::mesh::MeshSet<3>::vertex_t *new_vert,
|
||||||
|
void *descr_v)
|
||||||
|
{
|
||||||
|
CarveMeshDescr *descr = (CarveMeshDescr *) descr_v;
|
||||||
|
if (!descr->orig_vert_mapping.hasAttribute(orig_vert)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (descr->orig_vert_mapping.hasAttribute(new_vert)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OrigIndex attr = descr->orig_vert_mapping.getAttribute(orig_vert);
|
||||||
|
descr->orig_vert_mapping.setAttribute(new_vert, attr);
|
||||||
|
descr->orig_vert_mapping.removeAttribute(orig_vert);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
|
CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
|
||||||
@@ -751,6 +767,7 @@ bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
|
|||||||
// done properly. The only way to make such situations working is to
|
// done properly. The only way to make such situations working is to
|
||||||
// union intersecting meshes of the same operand.
|
// union intersecting meshes of the same operand.
|
||||||
carve_unionIntersections(&csg, &left, &right,
|
carve_unionIntersections(&csg, &left, &right,
|
||||||
|
copyVertexAttrsCallback,
|
||||||
cleanupFaceEdgeAttrsCallback,
|
cleanupFaceEdgeAttrsCallback,
|
||||||
(void *) output_descr);
|
(void *) output_descr);
|
||||||
|
|
||||||
|
103
extern/carve/carve-util.cc
vendored
103
extern/carve/carve-util.cc
vendored
@@ -141,6 +141,11 @@ void carve_getRescaleMinMax(const MeshSet<3> *left,
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
struct UnionIntersectionContext {
|
||||||
|
VertexAttrsCallback vertex_attr_callback;
|
||||||
|
void *user_data;
|
||||||
|
};
|
||||||
|
|
||||||
void copyMeshes(const std::vector<MeshSet<3>::mesh_t*> &meshes,
|
void copyMeshes(const std::vector<MeshSet<3>::mesh_t*> &meshes,
|
||||||
std::vector<MeshSet<3>::mesh_t*> *new_meshes)
|
std::vector<MeshSet<3>::mesh_t*> *new_meshes)
|
||||||
{
|
{
|
||||||
@@ -154,24 +159,73 @@ void copyMeshes(const std::vector<MeshSet<3>::mesh_t*> &meshes,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshSet<3> *meshSetFromMeshes(const std::vector<MeshSet<3>::mesh_t*> &meshes)
|
struct NewMeshMapping {
|
||||||
|
std::map<const MeshSet<3>::edge_t*, MeshSet<3>::vertex_t*> orig_edge_vert;
|
||||||
|
};
|
||||||
|
|
||||||
|
void prepareNewMeshMapping(const std::vector<MeshSet<3>::mesh_t*> &meshes,
|
||||||
|
NewMeshMapping *mapping)
|
||||||
{
|
{
|
||||||
std::vector<MeshSet<3>::mesh_t*> new_meshes;
|
for (size_t m = 0; m < meshes.size(); ++m) {
|
||||||
|
MeshSet<3>::mesh_t *mesh = meshes[m];
|
||||||
copyMeshes(meshes, &new_meshes);
|
for (size_t f = 0; f < mesh->faces.size(); ++f) {
|
||||||
|
MeshSet<3>::face_t *face = mesh->faces[f];
|
||||||
return new MeshSet<3>(new_meshes);
|
MeshSet<3>::edge_t *edge = face->edge;
|
||||||
|
do {
|
||||||
|
mapping->orig_edge_vert[edge] = edge->vert;
|
||||||
|
edge = edge->next;
|
||||||
|
} while (edge != face->edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshSet<3> *meshSetFromTwoMeshes(const std::vector<MeshSet<3>::mesh_t*> &left_meshes,
|
void runNewMeshSetHooks(UnionIntersectionContext *ctx,
|
||||||
|
NewMeshMapping *mapping,
|
||||||
|
MeshSet<3> *mesh_set)
|
||||||
|
{
|
||||||
|
for (size_t m = 0; m < mesh_set->meshes.size(); ++m) {
|
||||||
|
MeshSet<3>::mesh_t *mesh = mesh_set->meshes[m];
|
||||||
|
for (size_t f = 0; f < mesh->faces.size(); ++f) {
|
||||||
|
MeshSet<3>::face_t *face = mesh->faces[f];
|
||||||
|
MeshSet<3>::edge_t *edge = face->edge;
|
||||||
|
do {
|
||||||
|
const MeshSet<3>::vertex_t *orig_vert = mapping->orig_edge_vert[edge];
|
||||||
|
const MeshSet<3>::vertex_t *new_vert = edge->vert;
|
||||||
|
ctx->vertex_attr_callback(orig_vert, new_vert, ctx->user_data);
|
||||||
|
edge = edge->next;
|
||||||
|
} while (edge != face->edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshSet<3> *newMeshSetFromMeshesWithAttrs(
|
||||||
|
UnionIntersectionContext *ctx,
|
||||||
|
std::vector<MeshSet<3>::mesh_t*> &meshes)
|
||||||
|
{
|
||||||
|
NewMeshMapping mapping;
|
||||||
|
prepareNewMeshMapping(meshes, &mapping);
|
||||||
|
MeshSet<3> *mesh_set = new MeshSet<3>(meshes);
|
||||||
|
runNewMeshSetHooks(ctx, &mapping, mesh_set);
|
||||||
|
return mesh_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MeshSet<3> *meshSetFromMeshes(UnionIntersectionContext *ctx,
|
||||||
|
const std::vector<MeshSet<3>::mesh_t*> &meshes)
|
||||||
|
{
|
||||||
|
std::vector<MeshSet<3>::mesh_t*> new_meshes;
|
||||||
|
copyMeshes(meshes, &new_meshes);
|
||||||
|
return newMeshSetFromMeshesWithAttrs(ctx, new_meshes);
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshSet<3> *meshSetFromTwoMeshes(UnionIntersectionContext *ctx,
|
||||||
|
const std::vector<MeshSet<3>::mesh_t*> &left_meshes,
|
||||||
const std::vector<MeshSet<3>::mesh_t*> &right_meshes)
|
const std::vector<MeshSet<3>::mesh_t*> &right_meshes)
|
||||||
{
|
{
|
||||||
std::vector<MeshSet<3>::mesh_t*> new_meshes;
|
std::vector<MeshSet<3>::mesh_t*> new_meshes;
|
||||||
|
|
||||||
copyMeshes(left_meshes, &new_meshes);
|
copyMeshes(left_meshes, &new_meshes);
|
||||||
copyMeshes(right_meshes, &new_meshes);
|
copyMeshes(right_meshes, &new_meshes);
|
||||||
|
return newMeshSetFromMeshesWithAttrs(ctx, new_meshes);
|
||||||
return new MeshSet<3>(new_meshes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkEdgeFaceIntersections_do(Intersections &intersections,
|
bool checkEdgeFaceIntersections_do(Intersections &intersections,
|
||||||
@@ -349,7 +403,8 @@ void getIntersectedOperandMeshes(std::vector<MeshSet<3>::mesh_t*> *meshes,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshSet<3> *getIntersectedOperand(std::vector<MeshSet<3>::mesh_t*> *meshes,
|
MeshSet<3> *getIntersectedOperand(UnionIntersectionContext *ctx,
|
||||||
|
std::vector<MeshSet<3>::mesh_t*> *meshes,
|
||||||
const MeshSet<3>::aabb_t &otherAABB,
|
const MeshSet<3>::aabb_t &otherAABB,
|
||||||
RTreeCache *rtree_cache,
|
RTreeCache *rtree_cache,
|
||||||
IntersectCache *intersect_cache)
|
IntersectCache *intersect_cache)
|
||||||
@@ -360,13 +415,14 @@ MeshSet<3> *getIntersectedOperand(std::vector<MeshSet<3>::mesh_t*> *meshes,
|
|||||||
if (operandMeshes.size() == 0)
|
if (operandMeshes.size() == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return meshSetFromMeshes(operandMeshes);
|
return meshSetFromMeshes(ctx, operandMeshes);
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
|
MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
|
||||||
MeshSet<3> *poly,
|
MeshSet<3> *poly,
|
||||||
const MeshSet<3> *other_poly,
|
const MeshSet<3> *other_poly,
|
||||||
const MeshSet<3>::aabb_t &otherAABB,
|
const MeshSet<3>::aabb_t &otherAABB,
|
||||||
|
VertexAttrsCallback vertex_attr_callback,
|
||||||
UnionIntersectionsCallback callback,
|
UnionIntersectionsCallback callback,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
@@ -380,7 +436,12 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
|
|||||||
RTreeCache rtree_cache;
|
RTreeCache rtree_cache;
|
||||||
IntersectCache intersect_cache;
|
IntersectCache intersect_cache;
|
||||||
|
|
||||||
MeshSet<3> *left = getIntersectedOperand(&orig_meshes,
|
UnionIntersectionContext ctx;
|
||||||
|
ctx.vertex_attr_callback = vertex_attr_callback;
|
||||||
|
ctx.user_data = user_data;
|
||||||
|
|
||||||
|
MeshSet<3> *left = getIntersectedOperand(&ctx,
|
||||||
|
&orig_meshes,
|
||||||
otherAABB,
|
otherAABB,
|
||||||
&rtree_cache,
|
&rtree_cache,
|
||||||
&intersect_cache);
|
&intersect_cache);
|
||||||
@@ -391,7 +452,8 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (orig_meshes.size()) {
|
while (orig_meshes.size()) {
|
||||||
MeshSet<3> *right = getIntersectedOperand(&orig_meshes,
|
MeshSet<3> *right = getIntersectedOperand(&ctx,
|
||||||
|
&orig_meshes,
|
||||||
otherAABB,
|
otherAABB,
|
||||||
&rtree_cache,
|
&rtree_cache,
|
||||||
&intersect_cache);
|
&intersect_cache);
|
||||||
@@ -422,7 +484,9 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
|
|||||||
catch (carve::exception e) {
|
catch (carve::exception e) {
|
||||||
std::cerr << "CSG failed, exception " << e.str() << std::endl;
|
std::cerr << "CSG failed, exception " << e.str() << std::endl;
|
||||||
|
|
||||||
MeshSet<3> *result = meshSetFromTwoMeshes(left->meshes, right->meshes);
|
MeshSet<3> *result = meshSetFromTwoMeshes(&ctx,
|
||||||
|
left->meshes,
|
||||||
|
right->meshes);
|
||||||
|
|
||||||
callback(result, other_poly, user_data);
|
callback(result, other_poly, user_data);
|
||||||
|
|
||||||
@@ -448,7 +512,9 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
|
|||||||
|
|
||||||
// Append all meshes which doesn't have intersection with another operand as-is.
|
// Append all meshes which doesn't have intersection with another operand as-is.
|
||||||
if (orig_meshes.size()) {
|
if (orig_meshes.size()) {
|
||||||
MeshSet<3> *result = meshSetFromTwoMeshes(left->meshes, orig_meshes);
|
MeshSet<3> *result = meshSetFromTwoMeshes(&ctx,
|
||||||
|
left->meshes,
|
||||||
|
orig_meshes);
|
||||||
|
|
||||||
delete left;
|
delete left;
|
||||||
left = result;
|
left = result;
|
||||||
@@ -464,6 +530,7 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
|
|||||||
void carve_unionIntersections(carve::csg::CSG *csg,
|
void carve_unionIntersections(carve::csg::CSG *csg,
|
||||||
MeshSet<3> **left_r,
|
MeshSet<3> **left_r,
|
||||||
MeshSet<3> **right_r,
|
MeshSet<3> **right_r,
|
||||||
|
VertexAttrsCallback vertex_attr_callback,
|
||||||
UnionIntersectionsCallback callback,
|
UnionIntersectionsCallback callback,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
@@ -477,9 +544,9 @@ void carve_unionIntersections(carve::csg::CSG *csg,
|
|||||||
MeshSet<3>::aabb_t rightAABB = right->getAABB();;
|
MeshSet<3>::aabb_t rightAABB = right->getAABB();;
|
||||||
|
|
||||||
left = unionIntersectingMeshes(csg, left, right, rightAABB,
|
left = unionIntersectingMeshes(csg, left, right, rightAABB,
|
||||||
callback, user_data);
|
vertex_attr_callback, callback, user_data);
|
||||||
right = unionIntersectingMeshes(csg, right, left, leftAABB,
|
right = unionIntersectingMeshes(csg, right, left, leftAABB,
|
||||||
callback, user_data);
|
vertex_attr_callback, callback, user_data);
|
||||||
|
|
||||||
if (left != *left_r) {
|
if (left != *left_r) {
|
||||||
delete *left_r;
|
delete *left_r;
|
||||||
|
12
extern/carve/carve-util.h
vendored
12
extern/carve/carve-util.h
vendored
@@ -70,6 +70,10 @@ void carve_getRescaleMinMax(const carve::mesh::MeshSet<3> *left,
|
|||||||
carve::geom3d::Vector *min,
|
carve::geom3d::Vector *min,
|
||||||
carve::geom3d::Vector *max);
|
carve::geom3d::Vector *max);
|
||||||
|
|
||||||
|
typedef void (*VertexAttrsCallback) (const carve::mesh::MeshSet<3>::vertex_t *orig_vert,
|
||||||
|
const carve::mesh::MeshSet<3>::vertex_t *new_vert,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
typedef void (*UnionIntersectionsCallback) (const carve::mesh::MeshSet<3> *left,
|
typedef void (*UnionIntersectionsCallback) (const carve::mesh::MeshSet<3> *left,
|
||||||
const carve::mesh::MeshSet<3> *right,
|
const carve::mesh::MeshSet<3> *right,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
@@ -77,6 +81,7 @@ typedef void (*UnionIntersectionsCallback) (const carve::mesh::MeshSet<3> *left,
|
|||||||
void carve_unionIntersections(carve::csg::CSG *csg,
|
void carve_unionIntersections(carve::csg::CSG *csg,
|
||||||
carve::mesh::MeshSet<3> **left_r,
|
carve::mesh::MeshSet<3> **left_r,
|
||||||
carve::mesh::MeshSet<3> **right_r,
|
carve::mesh::MeshSet<3> **right_r,
|
||||||
|
VertexAttrsCallback vertex_attr_callback,
|
||||||
UnionIntersectionsCallback callback,
|
UnionIntersectionsCallback callback,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
@@ -148,6 +153,13 @@ namespace carve {
|
|||||||
void setAttribute(const meshset_t::vertex_t *v, const attr_t &attr) {
|
void setAttribute(const meshset_t::vertex_t *v, const attr_t &attr) {
|
||||||
attrs[v] = attr;
|
attrs[v] = attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeAttribute(const meshset_t::vertex_t *v) {
|
||||||
|
typename attrmap_t::iterator it = attrs.find(v);
|
||||||
|
if (it != attrs.end()) {
|
||||||
|
attrs.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename attr_t>
|
template<typename attr_t>
|
||||||
|
@@ -107,6 +107,8 @@ ATOMIC_INLINE unsigned int atomic_fetch_and_add_u(unsigned int *p, unsigned int
|
|||||||
ATOMIC_INLINE unsigned int atomic_fetch_and_sub_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);
|
ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsigned int _new);
|
||||||
|
|
||||||
|
ATOMIC_INLINE void *atomic_cas_ptr(void **v, void *old, void *_new);
|
||||||
|
|
||||||
/* WARNING! Float 'atomics' are really faked ones, those are actually closer to some kind of spinlock-sync'ed operation,
|
/* 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
|
* which means they are only efficient if collisions are highly unlikely (i.e. if probability of two threads
|
||||||
* working on the same pointer at the same time is very low). */
|
* working on the same pointer at the same time is very low). */
|
||||||
|
@@ -168,6 +168,18 @@ ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsig
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* Pointer operations. */
|
||||||
|
|
||||||
|
ATOMIC_INLINE void *atomic_cas_ptr(void **v, void *old, void *_new)
|
||||||
|
{
|
||||||
|
#if (LG_SIZEOF_PTR == 8)
|
||||||
|
return (void *)atomic_cas_uint64((uint64_t *)v, *(uint64_t *)&old, *(uint64_t *)&_new);
|
||||||
|
#elif (LG_SIZEOF_PTR == 4)
|
||||||
|
return (void *)atomic_cas_uint32((uint32_t *)v, *(uint32_t *)&old, *(uint32_t *)&_new);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* float operations. */
|
/* float operations. */
|
||||||
|
|
||||||
|
@@ -89,7 +89,7 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause(bool keep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_PitchReader> pitch, boost::shared_ptr<AUD_ResampleReader> resampler, boost::shared_ptr<AUD_ChannelMapperReader> mapper, bool keep) :
|
AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_PitchReader> pitch, boost::shared_ptr<AUD_ResampleReader> resampler, boost::shared_ptr<AUD_ChannelMapperReader> mapper, bool keep) :
|
||||||
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(1.0f), m_old_volume(1.0f), m_loopcount(0),
|
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(0.0f), m_old_volume(0.0f), m_loopcount(0),
|
||||||
m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
|
m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
|
||||||
m_distance_reference(1.0f), m_attenuation(1.0f), m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
|
m_distance_reference(1.0f), m_attenuation(1.0f), m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
|
||||||
m_flags(AUD_RENDER_CONE), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING), m_device(device)
|
m_flags(AUD_RENDER_CONE), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING), m_device(device)
|
||||||
|
@@ -205,6 +205,10 @@ if(WITH_CYCLES_DEBUG)
|
|||||||
add_definitions(-DWITH_CYCLES_DEBUG)
|
add_definitions(-DWITH_CYCLES_DEBUG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT OPENIMAGEIO_PUGIXML_FOUND)
|
||||||
|
add_definitions(-DWITH_SYSTEM_PUGIXML)
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
SYSTEM
|
SYSTEM
|
||||||
${BOOST_INCLUDE_DIR}
|
${BOOST_INCLUDE_DIR}
|
||||||
|
@@ -70,9 +70,9 @@ struct XMLReadState : public XMLReader {
|
|||||||
|
|
||||||
/* Attribute Reading */
|
/* Attribute Reading */
|
||||||
|
|
||||||
static bool xml_read_int(int *value, pugi::xml_node node, const char *name)
|
static bool xml_read_int(int *value, xml_node node, const char *name)
|
||||||
{
|
{
|
||||||
pugi::xml_attribute attr = node.attribute(name);
|
xml_attribute attr = node.attribute(name);
|
||||||
|
|
||||||
if(attr) {
|
if(attr) {
|
||||||
*value = atoi(attr.value());
|
*value = atoi(attr.value());
|
||||||
@@ -82,9 +82,9 @@ static bool xml_read_int(int *value, pugi::xml_node node, const char *name)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool xml_read_int_array(vector<int>& value, pugi::xml_node node, const char *name)
|
static bool xml_read_int_array(vector<int>& value, xml_node node, const char *name)
|
||||||
{
|
{
|
||||||
pugi::xml_attribute attr = node.attribute(name);
|
xml_attribute attr = node.attribute(name);
|
||||||
|
|
||||||
if(attr) {
|
if(attr) {
|
||||||
vector<string> tokens;
|
vector<string> tokens;
|
||||||
@@ -99,9 +99,9 @@ static bool xml_read_int_array(vector<int>& value, pugi::xml_node node, const ch
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool xml_read_float(float *value, pugi::xml_node node, const char *name)
|
static bool xml_read_float(float *value, xml_node node, const char *name)
|
||||||
{
|
{
|
||||||
pugi::xml_attribute attr = node.attribute(name);
|
xml_attribute attr = node.attribute(name);
|
||||||
|
|
||||||
if(attr) {
|
if(attr) {
|
||||||
*value = (float)atof(attr.value());
|
*value = (float)atof(attr.value());
|
||||||
@@ -111,9 +111,9 @@ static bool xml_read_float(float *value, pugi::xml_node node, const char *name)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool xml_read_float_array(vector<float>& value, pugi::xml_node node, const char *name)
|
static bool xml_read_float_array(vector<float>& value, xml_node node, const char *name)
|
||||||
{
|
{
|
||||||
pugi::xml_attribute attr = node.attribute(name);
|
xml_attribute attr = node.attribute(name);
|
||||||
|
|
||||||
if(attr) {
|
if(attr) {
|
||||||
vector<string> tokens;
|
vector<string> tokens;
|
||||||
@@ -128,7 +128,7 @@ static bool xml_read_float_array(vector<float>& value, pugi::xml_node node, cons
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool xml_read_float3(float3 *value, pugi::xml_node node, const char *name)
|
static bool xml_read_float3(float3 *value, xml_node node, const char *name)
|
||||||
{
|
{
|
||||||
vector<float> array;
|
vector<float> array;
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ static bool xml_read_float3(float3 *value, pugi::xml_node node, const char *name
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool xml_read_float3_array(vector<float3>& value, pugi::xml_node node, const char *name)
|
static bool xml_read_float3_array(vector<float3>& value, xml_node node, const char *name)
|
||||||
{
|
{
|
||||||
vector<float> array;
|
vector<float> array;
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ static bool xml_read_float3_array(vector<float3>& value, pugi::xml_node node, co
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool xml_read_float4(float4 *value, pugi::xml_node node, const char *name)
|
static bool xml_read_float4(float4 *value, xml_node node, const char *name)
|
||||||
{
|
{
|
||||||
vector<float> array;
|
vector<float> array;
|
||||||
|
|
||||||
@@ -166,9 +166,9 @@ static bool xml_read_float4(float4 *value, pugi::xml_node node, const char *name
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool xml_read_string(string *str, pugi::xml_node node, const char *name)
|
static bool xml_read_string(string *str, xml_node node, const char *name)
|
||||||
{
|
{
|
||||||
pugi::xml_attribute attr = node.attribute(name);
|
xml_attribute attr = node.attribute(name);
|
||||||
|
|
||||||
if(attr) {
|
if(attr) {
|
||||||
*str = attr.value();
|
*str = attr.value();
|
||||||
@@ -178,9 +178,9 @@ static bool xml_read_string(string *str, pugi::xml_node node, const char *name)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool xml_equal_string(pugi::xml_node node, const char *name, const char *value)
|
static bool xml_equal_string(xml_node node, const char *name, const char *value)
|
||||||
{
|
{
|
||||||
pugi::xml_attribute attr = node.attribute(name);
|
xml_attribute attr = node.attribute(name);
|
||||||
|
|
||||||
if(attr)
|
if(attr)
|
||||||
return string_iequals(attr.value(), value);
|
return string_iequals(attr.value(), value);
|
||||||
@@ -190,7 +190,7 @@ static bool xml_equal_string(pugi::xml_node node, const char *name, const char *
|
|||||||
|
|
||||||
/* Camera */
|
/* Camera */
|
||||||
|
|
||||||
static void xml_read_camera(XMLReadState& state, pugi::xml_node node)
|
static void xml_read_camera(XMLReadState& state, xml_node node)
|
||||||
{
|
{
|
||||||
Camera *cam = state.scene->camera;
|
Camera *cam = state.scene->camera;
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ static void xml_read_camera(XMLReadState& state, pugi::xml_node node)
|
|||||||
|
|
||||||
/* Shader */
|
/* Shader */
|
||||||
|
|
||||||
static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml_node graph_node)
|
static void xml_read_shader_graph(XMLReadState& state, Shader *shader, xml_node graph_node)
|
||||||
{
|
{
|
||||||
xml_read_node(state, shader, graph_node);
|
xml_read_node(state, shader, graph_node);
|
||||||
|
|
||||||
@@ -220,7 +220,7 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml
|
|||||||
XMLReader graph_reader;
|
XMLReader graph_reader;
|
||||||
graph_reader.node_map[ustring("output")] = graph->output();
|
graph_reader.node_map[ustring("output")] = graph->output();
|
||||||
|
|
||||||
for(pugi::xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
|
for(xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
|
||||||
ustring node_name(node.name());
|
ustring node_name(node.name());
|
||||||
|
|
||||||
if(node_name == "connect") {
|
if(node_name == "connect") {
|
||||||
@@ -349,7 +349,7 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml
|
|||||||
shader->tag_update(state.scene);
|
shader->tag_update(state.scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xml_read_shader(XMLReadState& state, pugi::xml_node node)
|
static void xml_read_shader(XMLReadState& state, xml_node node)
|
||||||
{
|
{
|
||||||
Shader *shader = new Shader();
|
Shader *shader = new Shader();
|
||||||
xml_read_shader_graph(state, shader, node);
|
xml_read_shader_graph(state, shader, node);
|
||||||
@@ -358,7 +358,7 @@ static void xml_read_shader(XMLReadState& state, pugi::xml_node node)
|
|||||||
|
|
||||||
/* Background */
|
/* Background */
|
||||||
|
|
||||||
static void xml_read_background(XMLReadState& state, pugi::xml_node node)
|
static void xml_read_background(XMLReadState& state, xml_node node)
|
||||||
{
|
{
|
||||||
/* Background Settings */
|
/* Background Settings */
|
||||||
xml_read_node(state, state.scene->background, node);
|
xml_read_node(state, state.scene->background, node);
|
||||||
@@ -385,7 +385,7 @@ static Mesh *xml_add_mesh(Scene *scene, const Transform& tfm)
|
|||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
|
static void xml_read_mesh(const XMLReadState& state, xml_node node)
|
||||||
{
|
{
|
||||||
/* add mesh */
|
/* add mesh */
|
||||||
Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
|
Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
|
||||||
@@ -531,7 +531,7 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
|
|||||||
|
|
||||||
/* Light */
|
/* Light */
|
||||||
|
|
||||||
static void xml_read_light(XMLReadState& state, pugi::xml_node node)
|
static void xml_read_light(XMLReadState& state, xml_node node)
|
||||||
{
|
{
|
||||||
Light *light = new Light();
|
Light *light = new Light();
|
||||||
|
|
||||||
@@ -543,7 +543,7 @@ static void xml_read_light(XMLReadState& state, pugi::xml_node node)
|
|||||||
|
|
||||||
/* Transform */
|
/* Transform */
|
||||||
|
|
||||||
static void xml_read_transform(pugi::xml_node node, Transform& tfm)
|
static void xml_read_transform(xml_node node, Transform& tfm)
|
||||||
{
|
{
|
||||||
if(node.attribute("matrix")) {
|
if(node.attribute("matrix")) {
|
||||||
vector<float> matrix;
|
vector<float> matrix;
|
||||||
@@ -572,7 +572,7 @@ static void xml_read_transform(pugi::xml_node node, Transform& tfm)
|
|||||||
|
|
||||||
/* State */
|
/* State */
|
||||||
|
|
||||||
static void xml_read_state(XMLReadState& state, pugi::xml_node node)
|
static void xml_read_state(XMLReadState& state, xml_node node)
|
||||||
{
|
{
|
||||||
/* read shader */
|
/* read shader */
|
||||||
string shadername;
|
string shadername;
|
||||||
@@ -605,9 +605,9 @@ static void xml_read_state(XMLReadState& state, pugi::xml_node node)
|
|||||||
|
|
||||||
static void xml_read_include(XMLReadState& state, const string& src);
|
static void xml_read_include(XMLReadState& state, const string& src);
|
||||||
|
|
||||||
static void xml_read_scene(XMLReadState& state, pugi::xml_node scene_node)
|
static void xml_read_scene(XMLReadState& state, xml_node scene_node)
|
||||||
{
|
{
|
||||||
for(pugi::xml_node node = scene_node.first_child(); node; node = node.next_sibling()) {
|
for(xml_node node = scene_node.first_child(); node; node = node.next_sibling()) {
|
||||||
if(string_iequals(node.name(), "film")) {
|
if(string_iequals(node.name(), "film")) {
|
||||||
xml_read_node(state, state.scene->film, node);
|
xml_read_node(state, state.scene->film, node);
|
||||||
}
|
}
|
||||||
@@ -657,8 +657,8 @@ static void xml_read_scene(XMLReadState& state, pugi::xml_node scene_node)
|
|||||||
static void xml_read_include(XMLReadState& state, const string& src)
|
static void xml_read_include(XMLReadState& state, const string& src)
|
||||||
{
|
{
|
||||||
/* open XML document */
|
/* open XML document */
|
||||||
pugi::xml_document doc;
|
xml_document doc;
|
||||||
pugi::xml_parse_result parse_result;
|
xml_parse_result parse_result;
|
||||||
|
|
||||||
string path = path_join(state.base, src);
|
string path = path_join(state.base, src);
|
||||||
parse_result = doc.load_file(path.c_str());
|
parse_result = doc.load_file(path.c_str());
|
||||||
@@ -667,7 +667,7 @@ static void xml_read_include(XMLReadState& state, const string& src)
|
|||||||
XMLReadState substate = state;
|
XMLReadState substate = state;
|
||||||
substate.base = path_dirname(path);
|
substate.base = path_dirname(path);
|
||||||
|
|
||||||
pugi::xml_node cycles = doc.child("cycles");
|
xml_node cycles = doc.child("cycles");
|
||||||
xml_read_scene(substate, cycles);
|
xml_read_scene(substate, cycles);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -1366,37 +1366,49 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||||||
|
|
||||||
devices = bpy.props.CollectionProperty(type=CyclesDeviceSettings)
|
devices = bpy.props.CollectionProperty(type=CyclesDeviceSettings)
|
||||||
|
|
||||||
def get_devices(self):
|
def find_existing_device_entry(self, device):
|
||||||
import _cycles
|
for device_entry in self.devices:
|
||||||
# Layout of the device tuples: (Name, Type, Persistent ID)
|
if device_entry.id == device[2] and device_entry.type == device[1]:
|
||||||
device_list = _cycles.available_devices()
|
return device_entry
|
||||||
|
return None
|
||||||
|
|
||||||
cuda_devices = []
|
def update_device_entries(self, device_list):
|
||||||
opencl_devices = []
|
|
||||||
for device in device_list:
|
for device in device_list:
|
||||||
if not device[1] in {'CUDA', 'OPENCL'}:
|
if not device[1] in {'CUDA', 'OPENCL', 'CPU'}:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
entry = None
|
entry = None
|
||||||
# Try to find existing Device entry
|
# Try to find existing Device entry
|
||||||
for dev in self.devices:
|
entry = self.find_existing_device_entry(device)
|
||||||
if dev.id == device[2] and dev.type == device[1]:
|
|
||||||
entry = dev
|
|
||||||
break
|
|
||||||
# Create new entry if no existing one was found
|
# Create new entry if no existing one was found
|
||||||
if not entry:
|
if not entry:
|
||||||
entry = self.devices.add()
|
entry = self.devices.add()
|
||||||
entry.id = device[2]
|
entry.id = device[2]
|
||||||
entry.name = device[0]
|
entry.name = device[0]
|
||||||
entry.type = device[1]
|
entry.type = device[1]
|
||||||
|
elif entry.name != device[0]:
|
||||||
|
# Update name in case it changed
|
||||||
|
entry.name = device[0]
|
||||||
|
|
||||||
# Sort entries into lists
|
def get_devices(self):
|
||||||
|
import _cycles
|
||||||
|
# Layout of the device tuples: (Name, Type, Persistent ID)
|
||||||
|
device_list = _cycles.available_devices()
|
||||||
|
# Make sure device entries are up to date and not referenced before
|
||||||
|
# we know we don't add new devices. This way we guarantee to not
|
||||||
|
# hold pointers to a resized array.
|
||||||
|
self.update_device_entries(device_list)
|
||||||
|
# Sort entries into lists
|
||||||
|
cuda_devices = []
|
||||||
|
opencl_devices = []
|
||||||
|
for device in device_list:
|
||||||
|
entry = self.find_existing_device_entry(device)
|
||||||
if entry.type == 'CUDA':
|
if entry.type == 'CUDA':
|
||||||
cuda_devices.append(entry)
|
cuda_devices.append(entry)
|
||||||
elif entry.type == 'OPENCL':
|
elif entry.type == 'OPENCL':
|
||||||
opencl_devices.append(entry)
|
opencl_devices.append(entry)
|
||||||
return cuda_devices, opencl_devices
|
|
||||||
|
|
||||||
|
return cuda_devices, opencl_devices
|
||||||
|
|
||||||
def get_num_gpu_devices(self):
|
def get_num_gpu_devices(self):
|
||||||
import _cycles
|
import _cycles
|
||||||
|
@@ -544,7 +544,11 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings& b_render,
|
|||||||
|
|
||||||
if(tfm != cam->matrix) {
|
if(tfm != cam->matrix) {
|
||||||
VLOG(1) << "Camera " << b_ob.name() << " motion detected.";
|
VLOG(1) << "Camera " << b_ob.name() << " motion detected.";
|
||||||
if(motion_time == -1.0f) {
|
if(motion_time == 0.0f) {
|
||||||
|
/* When motion blur is not centered in frame, cam->matrix gets reset. */
|
||||||
|
cam->matrix = tfm;
|
||||||
|
}
|
||||||
|
else if(motion_time == -1.0f) {
|
||||||
cam->motion.pre = tfm;
|
cam->motion.pre = tfm;
|
||||||
cam->use_motion = true;
|
cam->use_motion = true;
|
||||||
}
|
}
|
||||||
@@ -573,7 +577,10 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings& b_render,
|
|||||||
float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
|
float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
|
||||||
if(fov != cam->fov) {
|
if(fov != cam->fov) {
|
||||||
VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
|
VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
|
||||||
if(motion_time == -1.0f) {
|
if(motion_time == 0.0f) {
|
||||||
|
cam->fov = fov;
|
||||||
|
}
|
||||||
|
else if(motion_time == -1.0f) {
|
||||||
cam->fov_pre = fov;
|
cam->fov_pre = fov;
|
||||||
cam->use_perspective_motion = true;
|
cam->use_perspective_motion = true;
|
||||||
}
|
}
|
||||||
|
@@ -1076,7 +1076,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* free derived mesh */
|
/* free derived mesh */
|
||||||
b_data.meshes.remove(b_mesh, false);
|
b_data.meshes.remove(b_mesh, false, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mesh->geometry_flags = requested_geometry_flags;
|
mesh->geometry_flags = requested_geometry_flags;
|
||||||
@@ -1296,7 +1296,7 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob,
|
|||||||
sync_curves(mesh, b_mesh, b_ob, true, time_index);
|
sync_curves(mesh, b_mesh, b_ob, true, time_index);
|
||||||
|
|
||||||
/* free derived mesh */
|
/* free derived mesh */
|
||||||
b_data.meshes.remove(b_mesh, false);
|
b_data.meshes.remove(b_mesh, false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -242,21 +242,23 @@ void BVH4::pack_unaligned_node(int idx,
|
|||||||
* so kernel might safely assume there are always 4 child nodes.
|
* so kernel might safely assume there are always 4 child nodes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
data[1][i] = 1.0f;
|
const float inf = FLT_MAX / 1000.0f;
|
||||||
|
|
||||||
|
data[1][i] = inf;
|
||||||
data[2][i] = 0.0f;
|
data[2][i] = 0.0f;
|
||||||
data[3][i] = 0.0f;
|
data[3][i] = 0.0f;
|
||||||
|
|
||||||
data[4][i] = 0.0f;
|
data[4][i] = 0.0f;
|
||||||
data[5][i] = 0.0f;
|
data[5][i] = inf;
|
||||||
data[6][i] = 0.0f;
|
data[6][i] = 0.0f;
|
||||||
|
|
||||||
data[7][i] = 0.0f;
|
data[7][i] = 0.0f;
|
||||||
data[8][i] = 0.0f;
|
data[8][i] = 0.0f;
|
||||||
data[9][i] = 0.0f;
|
data[9][i] = inf;
|
||||||
|
|
||||||
data[10][i] = -FLT_MAX;
|
data[10][i] = -inf;
|
||||||
data[11][i] = -FLT_MAX;
|
data[11][i] = -inf;
|
||||||
data[12][i] = -FLT_MAX;
|
data[12][i] = -inf;
|
||||||
|
|
||||||
data[13][i] = __int_as_float(0);
|
data[13][i] = __int_as_float(0);
|
||||||
}
|
}
|
||||||
|
@@ -129,7 +129,7 @@ void BVHBuild::add_reference_triangles(BoundBox& root, BoundBox& center, Mesh *m
|
|||||||
if(attr_mP == NULL) {
|
if(attr_mP == NULL) {
|
||||||
BoundBox bounds = BoundBox::empty;
|
BoundBox bounds = BoundBox::empty;
|
||||||
t.bounds_grow(verts, bounds);
|
t.bounds_grow(verts, bounds);
|
||||||
if(bounds.valid()) {
|
if(bounds.valid() && t.valid(verts)) {
|
||||||
references.push_back(BVHReference(bounds,
|
references.push_back(BVHReference(bounds,
|
||||||
j,
|
j,
|
||||||
i,
|
i,
|
||||||
@@ -1040,7 +1040,6 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
|
|||||||
*/
|
*/
|
||||||
start_index = spatial_free_index;
|
start_index = spatial_free_index;
|
||||||
spatial_free_index += range.size();
|
spatial_free_index += range.size();
|
||||||
|
|
||||||
/* Extend an array when needed. */
|
/* Extend an array when needed. */
|
||||||
const size_t range_end = start_index + range.size();
|
const size_t range_end = start_index + range.size();
|
||||||
if(prim_type.size() < range_end) {
|
if(prim_type.size() < range_end) {
|
||||||
@@ -1066,8 +1065,6 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
|
|||||||
prim_time.resize(range_end);
|
prim_time.resize(range_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spatial_spin_lock.unlock();
|
|
||||||
|
|
||||||
/* Perform actual data copy. */
|
/* Perform actual data copy. */
|
||||||
if(new_leaf_data_size > 0) {
|
if(new_leaf_data_size > 0) {
|
||||||
memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
|
memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
|
||||||
@@ -1077,6 +1074,7 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
|
|||||||
memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
|
memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
spatial_spin_lock.unlock();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* For the regular BVH builder we simply copy new data starting at the
|
/* For the regular BVH builder we simply copy new data starting at the
|
||||||
|
@@ -34,6 +34,7 @@ CCL_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
bool Device::need_types_update = true;
|
bool Device::need_types_update = true;
|
||||||
bool Device::need_devices_update = true;
|
bool Device::need_devices_update = true;
|
||||||
|
thread_mutex Device::device_mutex;
|
||||||
vector<DeviceType> Device::types;
|
vector<DeviceType> Device::types;
|
||||||
vector<DeviceInfo> Device::devices;
|
vector<DeviceInfo> Device::devices;
|
||||||
|
|
||||||
@@ -296,53 +297,49 @@ string Device::string_from_type(DeviceType type)
|
|||||||
|
|
||||||
vector<DeviceType>& Device::available_types()
|
vector<DeviceType>& Device::available_types()
|
||||||
{
|
{
|
||||||
|
thread_scoped_lock lock(device_mutex);
|
||||||
if(need_types_update) {
|
if(need_types_update) {
|
||||||
types.clear();
|
types.clear();
|
||||||
types.push_back(DEVICE_CPU);
|
types.push_back(DEVICE_CPU);
|
||||||
|
|
||||||
#ifdef WITH_CUDA
|
#ifdef WITH_CUDA
|
||||||
if(device_cuda_init())
|
if(device_cuda_init()) {
|
||||||
types.push_back(DEVICE_CUDA);
|
types.push_back(DEVICE_CUDA);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_OPENCL
|
#ifdef WITH_OPENCL
|
||||||
if(device_opencl_init())
|
if(device_opencl_init()) {
|
||||||
types.push_back(DEVICE_OPENCL);
|
types.push_back(DEVICE_OPENCL);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_NETWORK
|
#ifdef WITH_NETWORK
|
||||||
types.push_back(DEVICE_NETWORK);
|
types.push_back(DEVICE_NETWORK);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
need_types_update = false;
|
need_types_update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<DeviceInfo>& Device::available_devices()
|
vector<DeviceInfo>& Device::available_devices()
|
||||||
{
|
{
|
||||||
|
thread_scoped_lock lock(device_mutex);
|
||||||
if(need_devices_update) {
|
if(need_devices_update) {
|
||||||
devices.clear();
|
devices.clear();
|
||||||
#ifdef WITH_CUDA
|
|
||||||
if(device_cuda_init())
|
|
||||||
device_cuda_info(devices);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WITH_OPENCL
|
#ifdef WITH_OPENCL
|
||||||
if(device_opencl_init())
|
if(device_opencl_init()) {
|
||||||
device_opencl_info(devices);
|
device_opencl_info(devices);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_CUDA
|
||||||
|
if(device_cuda_init()) {
|
||||||
|
device_cuda_info(devices);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
device_cpu_info(devices);
|
device_cpu_info(devices);
|
||||||
|
|
||||||
#ifdef WITH_NETWORK
|
#ifdef WITH_NETWORK
|
||||||
device_network_info(devices);
|
device_network_info(devices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
need_devices_update = false;
|
need_devices_update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,12 +347,6 @@ string Device::device_capabilities()
|
|||||||
{
|
{
|
||||||
string capabilities = "CPU device capabilities: ";
|
string capabilities = "CPU device capabilities: ";
|
||||||
capabilities += device_cpu_capabilities() + "\n";
|
capabilities += device_cpu_capabilities() + "\n";
|
||||||
#ifdef WITH_CUDA
|
|
||||||
if(device_cuda_init()) {
|
|
||||||
capabilities += "\nCUDA device capabilities:\n";
|
|
||||||
capabilities += device_cuda_capabilities();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WITH_OPENCL
|
#ifdef WITH_OPENCL
|
||||||
if(device_opencl_init()) {
|
if(device_opencl_init()) {
|
||||||
@@ -364,6 +355,13 @@ string Device::device_capabilities()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_CUDA
|
||||||
|
if(device_cuda_init()) {
|
||||||
|
capabilities += "\nCUDA device capabilities:\n";
|
||||||
|
capabilities += device_cuda_capabilities();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return capabilities;
|
return capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -351,6 +351,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
/* Indicted whether device types and devices lists were initialized. */
|
/* Indicted whether device types and devices lists were initialized. */
|
||||||
static bool need_types_update, need_devices_update;
|
static bool need_types_update, need_devices_update;
|
||||||
|
static thread_mutex device_mutex;
|
||||||
static vector<DeviceType> types;
|
static vector<DeviceType> types;
|
||||||
static vector<DeviceInfo> devices;
|
static vector<DeviceInfo> devices;
|
||||||
};
|
};
|
||||||
|
@@ -119,7 +119,7 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(strstr(architecture_name, logged_architecture) != 0) {
|
if(strcmp(architecture_name, logged_architecture) != 0) {
|
||||||
VLOG(1) << "Will be using " << architecture_name << " kernels.";
|
VLOG(1) << "Will be using " << architecture_name << " kernels.";
|
||||||
logged_architecture = architecture_name;
|
logged_architecture = architecture_name;
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "util/util_foreach.h"
|
#include "util/util_foreach.h"
|
||||||
#include "util/util_logging.h"
|
#include "util/util_logging.h"
|
||||||
|
#include "util/util_set.h"
|
||||||
|
|
||||||
CCL_NAMESPACE_BEGIN
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@@ -79,7 +80,9 @@ void device_opencl_info(vector<DeviceInfo>& devices)
|
|||||||
OpenCLInfo::get_usable_devices(&usable_devices);
|
OpenCLInfo::get_usable_devices(&usable_devices);
|
||||||
/* Devices are numbered consecutively across platforms. */
|
/* Devices are numbered consecutively across platforms. */
|
||||||
int num_devices = 0;
|
int num_devices = 0;
|
||||||
|
set<string> unique_ids;
|
||||||
foreach(OpenCLPlatformDevice& platform_device, usable_devices) {
|
foreach(OpenCLPlatformDevice& platform_device, usable_devices) {
|
||||||
|
/* Compute unique ID for persistent user preferences. */
|
||||||
const string& platform_name = platform_device.platform_name;
|
const string& platform_name = platform_device.platform_name;
|
||||||
const cl_device_type device_type = platform_device.device_type;
|
const cl_device_type device_type = platform_device.device_type;
|
||||||
const string& device_name = platform_device.device_name;
|
const string& device_name = platform_device.device_name;
|
||||||
@@ -87,7 +90,15 @@ void device_opencl_info(vector<DeviceInfo>& devices)
|
|||||||
if(hardware_id == "") {
|
if(hardware_id == "") {
|
||||||
hardware_id = string_printf("ID_%d", num_devices);
|
hardware_id = string_printf("ID_%d", num_devices);
|
||||||
}
|
}
|
||||||
|
string id = string("OPENCL_") + platform_name + "_" + device_name + "_" + hardware_id;
|
||||||
|
|
||||||
|
/* Hardware ID might not be unique, add device number in that case. */
|
||||||
|
if(unique_ids.find(id) != unique_ids.end()) {
|
||||||
|
id += string_printf("_ID_%d", num_devices);
|
||||||
|
}
|
||||||
|
unique_ids.insert(id);
|
||||||
|
|
||||||
|
/* Create DeviceInfo. */
|
||||||
DeviceInfo info;
|
DeviceInfo info;
|
||||||
info.type = DEVICE_OPENCL;
|
info.type = DEVICE_OPENCL;
|
||||||
info.description = string_remove_trademark(string(device_name));
|
info.description = string_remove_trademark(string(device_name));
|
||||||
@@ -98,7 +109,7 @@ void device_opencl_info(vector<DeviceInfo>& devices)
|
|||||||
info.pack_images = true;
|
info.pack_images = true;
|
||||||
info.use_split_kernel = OpenCLInfo::kernel_use_split(platform_name,
|
info.use_split_kernel = OpenCLInfo::kernel_use_split(platform_name,
|
||||||
device_type);
|
device_type);
|
||||||
info.id = string("OPENCL_") + platform_name + "_" + device_name + "_" + hardware_id;
|
info.id = id;
|
||||||
devices.push_back(info);
|
devices.push_back(info);
|
||||||
num_devices++;
|
num_devices++;
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,7 @@ static const char *xml_write_boolean(bool value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<int VECTOR_SIZE, typename T>
|
template<int VECTOR_SIZE, typename T>
|
||||||
static void xml_read_float_array(T& value, pugi::xml_attribute attr)
|
static void xml_read_float_array(T& value, xml_attribute attr)
|
||||||
{
|
{
|
||||||
vector<string> tokens;
|
vector<string> tokens;
|
||||||
string_split(tokens, attr.value());
|
string_split(tokens, attr.value());
|
||||||
@@ -51,9 +51,9 @@ static void xml_read_float_array(T& value, pugi::xml_attribute attr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xml_read_node(XMLReader& reader, Node *node, pugi::xml_node xml_node)
|
void xml_read_node(XMLReader& reader, Node *node, xml_node xml_node)
|
||||||
{
|
{
|
||||||
pugi::xml_attribute name_attr = xml_node.attribute("name");
|
xml_attribute name_attr = xml_node.attribute("name");
|
||||||
if(name_attr) {
|
if(name_attr) {
|
||||||
node->name = ustring(name_attr.value());
|
node->name = ustring(name_attr.value());
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ void xml_read_node(XMLReader& reader, Node *node, pugi::xml_node xml_node)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pugi::xml_attribute attr = xml_node.attribute(socket.name.c_str());
|
xml_attribute attr = xml_node.attribute(socket.name.c_str());
|
||||||
|
|
||||||
if(!attr) {
|
if(!attr) {
|
||||||
continue;
|
continue;
|
||||||
@@ -254,9 +254,9 @@ void xml_read_node(XMLReader& reader, Node *node, pugi::xml_node xml_node)
|
|||||||
reader.node_map[node->name] = node;
|
reader.node_map[node->name] = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
pugi::xml_node xml_write_node(Node *node, pugi::xml_node xml_root)
|
xml_node xml_write_node(Node *node, xml_node xml_root)
|
||||||
{
|
{
|
||||||
pugi::xml_node xml_node = xml_root.append_child(node->type->name.c_str());
|
xml_node xml_node = xml_root.append_child(node->type->name.c_str());
|
||||||
|
|
||||||
xml_node.append_attribute("name") = node->name.c_str();
|
xml_node.append_attribute("name") = node->name.c_str();
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@ pugi::xml_node xml_write_node(Node *node, pugi::xml_node xml_root)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pugi::xml_attribute attr = xml_node.append_attribute(socket.name.c_str());
|
xml_attribute attr = xml_node.append_attribute(socket.name.c_str());
|
||||||
|
|
||||||
switch(socket.type)
|
switch(socket.type)
|
||||||
{
|
{
|
||||||
|
@@ -28,8 +28,8 @@ struct XMLReader {
|
|||||||
map<ustring, Node*> node_map;
|
map<ustring, Node*> node_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
void xml_read_node(XMLReader& reader, Node *node, pugi::xml_node xml_node);
|
void xml_read_node(XMLReader& reader, Node *node, xml_node xml_node);
|
||||||
pugi::xml_node xml_write_node(Node *node, pugi::xml_node xml_root);
|
xml_node xml_write_node(Node *node, xml_node xml_root);
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
|
||||||
|
@@ -320,7 +320,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
|||||||
set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}")
|
set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}")
|
||||||
|
|
||||||
# warn for other versions
|
# warn for other versions
|
||||||
if(CUDA_VERSION MATCHES "80")
|
if(CUDA_VERSION MATCHES "80" OR CUDA_VERSION MATCHES "90")
|
||||||
else()
|
else()
|
||||||
message(WARNING
|
message(WARNING
|
||||||
"CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
|
"CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
|
||||||
@@ -398,13 +398,17 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
|||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
foreach(arch ${CYCLES_CUDA_BINARIES_ARCH})
|
foreach(arch ${CYCLES_CUDA_BINARIES_ARCH})
|
||||||
# Compile regular kernel
|
if(CUDA_VERSION MATCHES "90" AND ${arch} MATCHES "sm_2.")
|
||||||
CYCLES_CUDA_KERNEL_ADD(${arch} kernel "" "${cuda_sources}" FALSE)
|
message(STATUS "CUDA binaries for ${arch} disabled, not supported by CUDA 9.")
|
||||||
CYCLES_CUDA_KERNEL_ADD(${arch} filter "" "${cuda_filter_sources}" FALSE)
|
else()
|
||||||
|
# Compile regular kernel
|
||||||
|
CYCLES_CUDA_KERNEL_ADD(${arch} kernel "" "${cuda_sources}" FALSE)
|
||||||
|
CYCLES_CUDA_KERNEL_ADD(${arch} filter "" "${cuda_filter_sources}" FALSE)
|
||||||
|
|
||||||
if(WITH_CYCLES_CUDA_SPLIT_KERNEL_BINARIES)
|
if(WITH_CYCLES_CUDA_SPLIT_KERNEL_BINARIES)
|
||||||
# Compile split kernel
|
# Compile split kernel
|
||||||
CYCLES_CUDA_KERNEL_ADD(${arch} kernel_split "-D__SPLIT__" ${cuda_sources} FALSE)
|
CYCLES_CUDA_KERNEL_ADD(${arch} kernel_split "-D__SPLIT__" ${cuda_sources} FALSE)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
@@ -409,8 +409,6 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, cons
|
|||||||
float alpha2 = alpha_x * alpha_y;
|
float alpha2 = alpha_x * alpha_y;
|
||||||
float D, G1o, G1i;
|
float D, G1o, G1i;
|
||||||
|
|
||||||
bool is_principled_clearcoat = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID);
|
|
||||||
|
|
||||||
if(alpha_x == alpha_y) {
|
if(alpha_x == alpha_y) {
|
||||||
/* isotropic
|
/* isotropic
|
||||||
* eq. 20: (F*G*D)/(4*in*on)
|
* eq. 20: (F*G*D)/(4*in*on)
|
||||||
@@ -420,7 +418,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, cons
|
|||||||
float cosThetaM4 = cosThetaM2 * cosThetaM2;
|
float cosThetaM4 = cosThetaM2 * cosThetaM2;
|
||||||
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
|
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
|
||||||
|
|
||||||
if(is_principled_clearcoat) {
|
if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
|
||||||
/* use GTR1 for clearcoat */
|
/* use GTR1 for clearcoat */
|
||||||
D = D_GTR1(cosThetaM, bsdf->alpha_x);
|
D = D_GTR1(cosThetaM, bsdf->alpha_x);
|
||||||
|
|
||||||
@@ -479,7 +477,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, cons
|
|||||||
float common = D * 0.25f / cosNO;
|
float common = D * 0.25f / cosNO;
|
||||||
|
|
||||||
float3 F = reflection_color(bsdf, omega_in, m);
|
float3 F = reflection_color(bsdf, omega_in, m);
|
||||||
if(is_principled_clearcoat) {
|
if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
|
||||||
F *= 0.25f * bsdf->extra->clearcoat;
|
F *= 0.25f * bsdf->extra->clearcoat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,8 +603,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
|
|||||||
|
|
||||||
/* if fresnel is used, calculate the color with reflection_color(...) */
|
/* if fresnel is used, calculate the color with reflection_color(...) */
|
||||||
if(use_fresnel) {
|
if(use_fresnel) {
|
||||||
*pdf = 1.0f;
|
*eval *= reflection_color(bsdf, *omega_in, m);
|
||||||
*eval = reflection_color(bsdf, *omega_in, m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
label = LABEL_REFLECT | LABEL_SINGULAR;
|
label = LABEL_REFLECT | LABEL_SINGULAR;
|
||||||
@@ -617,8 +614,6 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
|
|||||||
float alpha2 = alpha_x * alpha_y;
|
float alpha2 = alpha_x * alpha_y;
|
||||||
float D, G1i;
|
float D, G1i;
|
||||||
|
|
||||||
bool is_principled_clearcoat = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID);
|
|
||||||
|
|
||||||
if(alpha_x == alpha_y) {
|
if(alpha_x == alpha_y) {
|
||||||
/* isotropic */
|
/* isotropic */
|
||||||
float cosThetaM2 = cosThetaM * cosThetaM;
|
float cosThetaM2 = cosThetaM * cosThetaM;
|
||||||
@@ -628,7 +623,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
|
|||||||
/* eval BRDF*cosNI */
|
/* eval BRDF*cosNI */
|
||||||
float cosNI = dot(N, *omega_in);
|
float cosNI = dot(N, *omega_in);
|
||||||
|
|
||||||
if(is_principled_clearcoat) {
|
if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
|
||||||
/* use GTR1 for clearcoat */
|
/* use GTR1 for clearcoat */
|
||||||
D = D_GTR1(cosThetaM, bsdf->alpha_x);
|
D = D_GTR1(cosThetaM, bsdf->alpha_x);
|
||||||
|
|
||||||
@@ -644,7 +639,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* eq. 34: now calculate G1(i,m) */
|
/* eq. 34: now calculate G1(i,m) */
|
||||||
G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
|
G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* anisotropic distribution */
|
/* anisotropic distribution */
|
||||||
@@ -677,13 +672,14 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
|
|||||||
*pdf = common;
|
*pdf = common;
|
||||||
|
|
||||||
float3 F = reflection_color(bsdf, *omega_in, m);
|
float3 F = reflection_color(bsdf, *omega_in, m);
|
||||||
if(is_principled_clearcoat) {
|
|
||||||
F *= 0.25f * bsdf->extra->clearcoat;
|
|
||||||
}
|
|
||||||
|
|
||||||
*eval = G1i * common * F;
|
*eval = G1i * common * F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
|
||||||
|
*eval *= 0.25f * bsdf->extra->clearcoat;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __RAY_DIFFERENTIALS__
|
#ifdef __RAY_DIFFERENTIALS__
|
||||||
*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
|
*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
|
||||||
*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
|
*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
|
||||||
|
@@ -348,8 +348,9 @@ ccl_device_inline Bssrdf *bssrdf_alloc(ShaderData *sd, float3 weight)
|
|||||||
{
|
{
|
||||||
Bssrdf *bssrdf = (Bssrdf*)closure_alloc(sd, sizeof(Bssrdf), CLOSURE_NONE_ID, weight);
|
Bssrdf *bssrdf = (Bssrdf*)closure_alloc(sd, sizeof(Bssrdf), CLOSURE_NONE_ID, weight);
|
||||||
|
|
||||||
if(!bssrdf)
|
if(bssrdf == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
float sample_weight = fabsf(average(weight));
|
float sample_weight = fabsf(average(weight));
|
||||||
bssrdf->sample_weight = sample_weight;
|
bssrdf->sample_weight = sample_weight;
|
||||||
|
@@ -125,7 +125,9 @@ ccl_device void kernel_filter_detect_outliers(int x, int y,
|
|||||||
for(int y1 = max(y-2, rect.y); y1 < min(y+3, rect.w); y1++) {
|
for(int y1 = max(y-2, rect.y); y1 < min(y+3, rect.w); y1++) {
|
||||||
for(int x1 = max(x-2, rect.x); x1 < min(x+3, rect.z); x1++) {
|
for(int x1 = max(x-2, rect.x); x1 < min(x+3, rect.z); x1++) {
|
||||||
int idx = (y1-rect.y)*buffer_w + (x1-rect.x);
|
int idx = (y1-rect.y)*buffer_w + (x1-rect.x);
|
||||||
float L = average(make_float3(image[idx], image[idx+pass_stride], image[idx+2*pass_stride]));
|
float3 color = make_float3(image[idx], image[idx+pass_stride], image[idx+2*pass_stride]);
|
||||||
|
color = max(color, make_float3(0.0f, 0.0f, 0.0f));
|
||||||
|
float L = average(color);
|
||||||
|
|
||||||
/* Find the position of L. */
|
/* Find the position of L. */
|
||||||
int i;
|
int i;
|
||||||
@@ -143,10 +145,11 @@ ccl_device void kernel_filter_detect_outliers(int x, int y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int idx = (y-rect.y)*buffer_w + (x-rect.x);
|
int idx = (y-rect.y)*buffer_w + (x-rect.x);
|
||||||
float L = average(make_float3(image[idx], image[idx+pass_stride], image[idx+2*pass_stride]));
|
float3 color = make_float3(image[idx], image[idx+pass_stride], image[idx+2*pass_stride]);
|
||||||
|
color = max(color, make_float3(0.0f, 0.0f, 0.0f));
|
||||||
|
float L = average(color);
|
||||||
|
|
||||||
float ref = 2.0f*values[(int)(n*0.75f)];
|
float ref = 2.0f*values[(int)(n*0.75f)];
|
||||||
float fac = 1.0f;
|
|
||||||
if(L > ref) {
|
if(L > ref) {
|
||||||
/* The pixel appears to be an outlier.
|
/* The pixel appears to be an outlier.
|
||||||
* However, it may just be a legitimate highlight. Therefore, it is checked how likely it is that the pixel
|
* However, it may just be a legitimate highlight. Therefore, it is checked how likely it is that the pixel
|
||||||
@@ -159,15 +162,16 @@ ccl_device void kernel_filter_detect_outliers(int x, int y,
|
|||||||
/* The pixel is an outlier, so negate the depth value to mark it as one.
|
/* The pixel is an outlier, so negate the depth value to mark it as one.
|
||||||
* Also, scale its brightness down to the outlier threshold to avoid trouble with the NLM weights. */
|
* Also, scale its brightness down to the outlier threshold to avoid trouble with the NLM weights. */
|
||||||
depth[idx] = -depth[idx];
|
depth[idx] = -depth[idx];
|
||||||
fac = ref/L;
|
float fac = ref/L;
|
||||||
|
color *= fac;
|
||||||
variance[idx ] *= fac*fac;
|
variance[idx ] *= fac*fac;
|
||||||
variance[idx + pass_stride] *= fac*fac;
|
variance[idx + pass_stride] *= fac*fac;
|
||||||
variance[idx+2*pass_stride] *= fac*fac;
|
variance[idx+2*pass_stride] *= fac*fac;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out[idx ] = fac*image[idx];
|
out[idx ] = color.x;
|
||||||
out[idx + pass_stride] = fac*image[idx + pass_stride];
|
out[idx + pass_stride] = color.y;
|
||||||
out[idx+2*pass_stride] = fac*image[idx+2*pass_stride];
|
out[idx+2*pass_stride] = color.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Combine A/B buffers.
|
/* Combine A/B buffers.
|
||||||
|
@@ -169,6 +169,10 @@ ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, const
|
|||||||
Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
|
Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
|
||||||
*N = normalize(transform_direction_transposed(&tfm, *N));
|
*N = normalize(transform_direction_transposed(&tfm, *N));
|
||||||
}
|
}
|
||||||
|
else if(sd->type == PRIMITIVE_LAMP) {
|
||||||
|
Transform tfm = lamp_fetch_transform(kg, sd->lamp, false);
|
||||||
|
*N = normalize(transform_direction_transposed(&tfm, *N));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -668,6 +668,10 @@ ccl_device_inline float path_radiance_sum_shadow(const PathRadiance *L)
|
|||||||
{
|
{
|
||||||
float path_total = average(L->path_total);
|
float path_total = average(L->path_total);
|
||||||
float path_total_shaded = average(L->path_total_shaded);
|
float path_total_shaded = average(L->path_total_shaded);
|
||||||
|
if(UNLIKELY(!isfinite_safe(path_total))) {
|
||||||
|
kernel_assert(!"Non-finite total radiance along the path");
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
if(path_total != 0.0f) {
|
if(path_total != 0.0f) {
|
||||||
return path_total_shaded / path_total;
|
return path_total_shaded / path_total;
|
||||||
}
|
}
|
||||||
|
@@ -156,6 +156,16 @@ template<typename T> struct texture_image {
|
|||||||
return make_float4(f, f, f, 1.0f);
|
return make_float4(f, f, f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ccl_always_inline float4 read(const T *data,
|
||||||
|
int x, int y,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
if(x < 0 || y < 0 || x >= width || y >= height) {
|
||||||
|
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
return read(data[y * width + x]);
|
||||||
|
}
|
||||||
|
|
||||||
ccl_always_inline int wrap_periodic(int x, int width)
|
ccl_always_inline int wrap_periodic(int x, int width)
|
||||||
{
|
{
|
||||||
x %= width;
|
x %= width;
|
||||||
@@ -219,10 +229,9 @@ template<typename T> struct texture_image {
|
|||||||
niy = wrap_periodic(iy+1, height);
|
niy = wrap_periodic(iy+1, height);
|
||||||
break;
|
break;
|
||||||
case EXTENSION_CLIP:
|
case EXTENSION_CLIP:
|
||||||
if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
|
nix = ix + 1;
|
||||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
niy = iy + 1;
|
||||||
}
|
break;
|
||||||
ATTR_FALLTHROUGH;
|
|
||||||
case EXTENSION_EXTEND:
|
case EXTENSION_EXTEND:
|
||||||
nix = wrap_clamp(ix+1, width);
|
nix = wrap_clamp(ix+1, width);
|
||||||
niy = wrap_clamp(iy+1, height);
|
niy = wrap_clamp(iy+1, height);
|
||||||
@@ -235,10 +244,10 @@ template<typename T> struct texture_image {
|
|||||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 r = (1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width]);
|
float4 r = (1.0f - ty) * (1.0f - tx) * read(data, ix, iy, width, height);
|
||||||
r += (1.0f - ty)*tx*read(data[nix + iy*width]);
|
r += (1.0f - ty) * tx * read(data, nix, iy, width, height);
|
||||||
r += ty*(1.0f - tx)*read(data[ix + niy*width]);
|
r += ty * (1.0f - tx) * read(data, ix, niy, width, height);
|
||||||
r += ty*tx*read(data[nix + niy*width]);
|
r += ty * tx * read(data, nix, niy, width, height);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -262,10 +271,13 @@ template<typename T> struct texture_image {
|
|||||||
nniy = wrap_periodic(iy+2, height);
|
nniy = wrap_periodic(iy+2, height);
|
||||||
break;
|
break;
|
||||||
case EXTENSION_CLIP:
|
case EXTENSION_CLIP:
|
||||||
if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
|
pix = ix - 1;
|
||||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
piy = iy - 1;
|
||||||
}
|
nix = ix + 1;
|
||||||
ATTR_FALLTHROUGH;
|
niy = iy + 1;
|
||||||
|
nnix = ix + 2;
|
||||||
|
nniy = iy + 2;
|
||||||
|
break;
|
||||||
case EXTENSION_EXTEND:
|
case EXTENSION_EXTEND:
|
||||||
pix = wrap_clamp(ix-1, width);
|
pix = wrap_clamp(ix-1, width);
|
||||||
piy = wrap_clamp(iy-1, height);
|
piy = wrap_clamp(iy-1, height);
|
||||||
@@ -285,15 +297,13 @@ template<typename T> struct texture_image {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int xc[4] = {pix, ix, nix, nnix};
|
const int xc[4] = {pix, ix, nix, nnix};
|
||||||
const int yc[4] = {width * piy,
|
const int yc[4] = {piy, iy, niy, nniy};
|
||||||
width * iy,
|
|
||||||
width * niy,
|
|
||||||
width * nniy};
|
|
||||||
float u[4], v[4];
|
float u[4], v[4];
|
||||||
/* Some helper macro to keep code reasonable size,
|
/* Some helper macro to keep code reasonable size,
|
||||||
* let compiler to inline all the matrix multiplications.
|
* let compiler to inline all the matrix multiplications.
|
||||||
*/
|
*/
|
||||||
#define DATA(x, y) (read(data[xc[x] + yc[y]]))
|
#define DATA(x, y) (read(data, xc[x], yc[y], width, height))
|
||||||
#define TERM(col) \
|
#define TERM(col) \
|
||||||
(v[col] * (u[0] * DATA(0, col) + \
|
(v[col] * (u[0] * DATA(0, col) + \
|
||||||
u[1] * DATA(1, col) + \
|
u[1] * DATA(1, col) + \
|
||||||
|
@@ -187,7 +187,7 @@ ccl_device_inline float path_state_terminate_probability(KernelGlobals *kg, ccl_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* probalistic termination */
|
/* probalistic termination */
|
||||||
return average(throughput); /* todo: try using max here */
|
return min(average(throughput), 1.0f); /* todo: try using max here */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO(DingTo): Find more meaningful name for this */
|
/* TODO(DingTo): Find more meaningful name for this */
|
||||||
|
@@ -57,6 +57,7 @@ ccl_device_noinline void shader_setup_from_ray(KernelGlobals *kg,
|
|||||||
#ifdef __INSTANCING__
|
#ifdef __INSTANCING__
|
||||||
sd->object = (isect->object == PRIM_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
|
sd->object = (isect->object == PRIM_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
|
||||||
#endif
|
#endif
|
||||||
|
sd->lamp = LAMP_NONE;
|
||||||
|
|
||||||
sd->type = isect->type;
|
sd->type = isect->type;
|
||||||
sd->flag = 0;
|
sd->flag = 0;
|
||||||
@@ -265,6 +266,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg,
|
|||||||
#ifdef __INSTANCING__
|
#ifdef __INSTANCING__
|
||||||
sd->object = object;
|
sd->object = object;
|
||||||
#endif
|
#endif
|
||||||
|
sd->lamp = LAMP_NONE;
|
||||||
/* currently no access to bvh prim index for strand sd->prim*/
|
/* currently no access to bvh prim index for strand sd->prim*/
|
||||||
sd->prim = prim;
|
sd->prim = prim;
|
||||||
#ifdef __UV__
|
#ifdef __UV__
|
||||||
@@ -286,6 +288,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg,
|
|||||||
else if(lamp != LAMP_NONE) {
|
else if(lamp != LAMP_NONE) {
|
||||||
sd->ob_tfm = lamp_fetch_transform(kg, lamp, false);
|
sd->ob_tfm = lamp_fetch_transform(kg, lamp, false);
|
||||||
sd->ob_itfm = lamp_fetch_transform(kg, lamp, true);
|
sd->ob_itfm = lamp_fetch_transform(kg, lamp, true);
|
||||||
|
sd->lamp = lamp;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,6 +396,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
|
|||||||
#ifdef __INSTANCING__
|
#ifdef __INSTANCING__
|
||||||
sd->object = PRIM_NONE;
|
sd->object = PRIM_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
sd->lamp = LAMP_NONE;
|
||||||
sd->prim = PRIM_NONE;
|
sd->prim = PRIM_NONE;
|
||||||
#ifdef __UV__
|
#ifdef __UV__
|
||||||
sd->u = 0.0f;
|
sd->u = 0.0f;
|
||||||
@@ -435,6 +439,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *s
|
|||||||
#ifdef __INSTANCING__
|
#ifdef __INSTANCING__
|
||||||
sd->object = PRIM_NONE; /* todo: fill this for texture coordinates */
|
sd->object = PRIM_NONE; /* todo: fill this for texture coordinates */
|
||||||
#endif
|
#endif
|
||||||
|
sd->lamp = LAMP_NONE;
|
||||||
sd->prim = PRIM_NONE;
|
sd->prim = PRIM_NONE;
|
||||||
sd->type = PRIMITIVE_NONE;
|
sd->type = PRIMITIVE_NONE;
|
||||||
|
|
||||||
|
@@ -16,6 +16,42 @@
|
|||||||
|
|
||||||
CCL_NAMESPACE_BEGIN
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
#ifdef __VOLUME__
|
||||||
|
typedef struct VolumeState {
|
||||||
|
# ifdef __SPLIT_KERNEL__
|
||||||
|
# else
|
||||||
|
PathState ps;
|
||||||
|
# endif
|
||||||
|
} VolumeState;
|
||||||
|
|
||||||
|
/* Get PathState ready for use for volume stack evaluation. */
|
||||||
|
# ifdef __SPLIT_KERNEL__
|
||||||
|
ccl_addr_space
|
||||||
|
# endif
|
||||||
|
ccl_device_inline PathState *shadow_blocked_volume_path_state(
|
||||||
|
KernelGlobals *kg,
|
||||||
|
VolumeState *volume_state,
|
||||||
|
ccl_addr_space PathState *state,
|
||||||
|
ShaderData *sd,
|
||||||
|
Ray *ray)
|
||||||
|
{
|
||||||
|
# ifdef __SPLIT_KERNEL__
|
||||||
|
ccl_addr_space PathState *ps =
|
||||||
|
&kernel_split_state.state_shadow[ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0)];
|
||||||
|
# else
|
||||||
|
PathState *ps = &volume_state->ps;
|
||||||
|
# endif
|
||||||
|
*ps = *state;
|
||||||
|
/* We are checking for shadow on the "other" side of the surface, so need
|
||||||
|
* to discard volume we are currently at.
|
||||||
|
*/
|
||||||
|
if(dot(sd->Ng, ray->D) < 0.0f) {
|
||||||
|
kernel_volume_stack_enter_exit(kg, sd, ps->volume_stack);
|
||||||
|
}
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
#endif /* __VOLUME__ */
|
||||||
|
|
||||||
/* Attenuate throughput accordingly to the given intersection event.
|
/* Attenuate throughput accordingly to the given intersection event.
|
||||||
* Returns true if the throughput is zero and traversal can be aborted.
|
* Returns true if the throughput is zero and traversal can be aborted.
|
||||||
*/
|
*/
|
||||||
|
@@ -935,6 +935,8 @@ typedef ccl_addr_space struct ShaderData {
|
|||||||
float v;
|
float v;
|
||||||
/* object id if there is one, ~0 otherwise */
|
/* object id if there is one, ~0 otherwise */
|
||||||
int object;
|
int object;
|
||||||
|
/* lamp id if there is one, ~0 otherwise */
|
||||||
|
int lamp;
|
||||||
|
|
||||||
/* motion blur sample time */
|
/* motion blur sample time */
|
||||||
float time;
|
float time;
|
||||||
|
@@ -73,9 +73,15 @@
|
|||||||
|
|
||||||
/* tunable parameters */
|
/* tunable parameters */
|
||||||
# define CUDA_THREADS_BLOCK_WIDTH 16
|
# define CUDA_THREADS_BLOCK_WIDTH 16
|
||||||
# define CUDA_KERNEL_MAX_REGISTERS 48
|
/* CUDA 9.0 seems to cause slowdowns on high-end Pascal cards unless we increase the number of registers */
|
||||||
|
# if __CUDACC_VER_MAJOR__ == 9 && __CUDA_ARCH__ >= 600
|
||||||
|
# define CUDA_KERNEL_MAX_REGISTERS 64
|
||||||
|
# else
|
||||||
|
# define CUDA_KERNEL_MAX_REGISTERS 48
|
||||||
|
# endif
|
||||||
# define CUDA_KERNEL_BRANCHED_MAX_REGISTERS 63
|
# define CUDA_KERNEL_BRANCHED_MAX_REGISTERS 63
|
||||||
|
|
||||||
|
|
||||||
/* unknown architecture */
|
/* unknown architecture */
|
||||||
#else
|
#else
|
||||||
# error "Unknown or unsupported CUDA architecture, can't determine launch bounds"
|
# error "Unknown or unsupported CUDA architecture, can't determine launch bounds"
|
||||||
|
@@ -242,7 +242,11 @@ static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, O
|
|||||||
/* optimization: it's possible to not use a prepare function at all and
|
/* optimization: it's possible to not use a prepare function at all and
|
||||||
* only initialize the actual class when accessing the closure component
|
* only initialize the actual class when accessing the closure component
|
||||||
* data, but then we need to map the id to the class somehow */
|
* data, but then we need to map the id to the class somehow */
|
||||||
|
#if OSL_LIBRARY_VERSION_CODE >= 10900
|
||||||
|
ss->register_closure(name, id, params, prepare, NULL);
|
||||||
|
#else
|
||||||
ss->register_closure(name, id, params, prepare, NULL, 16);
|
ss->register_closure(name, id, params, prepare, NULL, 16);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSLShader::register_closures(OSLShadingSystem *ss_)
|
void OSLShader::register_closures(OSLShadingSystem *ss_)
|
||||||
|
@@ -67,8 +67,17 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
|||||||
/* note we read this extra node before weight check, so offset is added */
|
/* note we read this extra node before weight check, so offset is added */
|
||||||
uint4 data_node = read_node(kg, offset);
|
uint4 data_node = read_node(kg, offset);
|
||||||
|
|
||||||
if(mix_weight == 0.0f)
|
if(mix_weight == 0.0f) {
|
||||||
|
if(type == CLOSURE_BSDF_PRINCIPLED_ID) {
|
||||||
|
/* Read all principled BSDF extra data to get the right offset. */
|
||||||
|
read_node(kg, offset);
|
||||||
|
read_node(kg, offset);
|
||||||
|
read_node(kg, offset);
|
||||||
|
read_node(kg, offset);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N;
|
float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N;
|
||||||
|
|
||||||
|
@@ -46,7 +46,10 @@ ccl_device float svm_gradient(float3 p, NodeGradientType type)
|
|||||||
return atan2f(y, x) / M_2PI_F + 0.5f;
|
return atan2f(y, x) / M_2PI_F + 0.5f;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float r = fmaxf(1.0f - sqrtf(x*x + y*y + z*z), 0.0f);
|
/* Bias a little bit for the case where p is a unit length vector,
|
||||||
|
* to get exactly zero instead of a small random value depending
|
||||||
|
* on float precision. */
|
||||||
|
float r = fmaxf(0.999999f - sqrtf(x*x + y*y + z*z), 0.0f);
|
||||||
|
|
||||||
if(type == NODE_BLEND_QUADRATIC_SPHERE)
|
if(type == NODE_BLEND_QUADRATIC_SPHERE)
|
||||||
return r*r;
|
return r*r;
|
||||||
|
@@ -1040,6 +1040,9 @@ int ShaderGraph::get_num_closures()
|
|||||||
else if(CLOSURE_IS_PRINCIPLED(closure_type)) {
|
else if(CLOSURE_IS_PRINCIPLED(closure_type)) {
|
||||||
num_closures += 8;
|
num_closures += 8;
|
||||||
}
|
}
|
||||||
|
else if(CLOSURE_IS_VOLUME(closure_type)) {
|
||||||
|
num_closures += VOLUME_STACK_SIZE;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
++num_closures;
|
++num_closures;
|
||||||
}
|
}
|
||||||
|
@@ -528,6 +528,10 @@ bool ImageManager::file_load_image(Image *img,
|
|||||||
vector<StorageType> pixels_storage;
|
vector<StorageType> pixels_storage;
|
||||||
StorageType *pixels;
|
StorageType *pixels;
|
||||||
const size_t max_size = max(max(width, height), depth);
|
const size_t max_size = max(max(width, height), depth);
|
||||||
|
if(max_size == 0) {
|
||||||
|
/* Don't bother with invalid images. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if(texture_limit > 0 && max_size > texture_limit) {
|
if(texture_limit > 0 && max_size > texture_limit) {
|
||||||
pixels_storage.resize(((size_t)width)*height*depth*4);
|
pixels_storage.resize(((size_t)width)*height*depth*4);
|
||||||
pixels = &pixels_storage[0];
|
pixels = &pixels_storage[0];
|
||||||
@@ -535,6 +539,10 @@ bool ImageManager::file_load_image(Image *img,
|
|||||||
else {
|
else {
|
||||||
pixels = (StorageType*)tex_img.resize(width, height, depth);
|
pixels = (StorageType*)tex_img.resize(width, height, depth);
|
||||||
}
|
}
|
||||||
|
if(pixels == NULL) {
|
||||||
|
/* Could be that we've run out of memory. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool cmyk = false;
|
bool cmyk = false;
|
||||||
const size_t num_pixels = ((size_t)width) * height * depth;
|
const size_t num_pixels = ((size_t)width) * height * depth;
|
||||||
if(in) {
|
if(in) {
|
||||||
|
@@ -348,6 +348,9 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
|
|||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
Mesh::Triangle t = mesh->get_triangle(i);
|
Mesh::Triangle t = mesh->get_triangle(i);
|
||||||
|
if(!t.valid(&mesh->verts[0])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
float3 p1 = mesh->verts[t.v[0]];
|
float3 p1 = mesh->verts[t.v[0]];
|
||||||
float3 p2 = mesh->verts[t.v[1]];
|
float3 p2 = mesh->verts[t.v[1]];
|
||||||
float3 p3 = mesh->verts[t.v[2]];
|
float3 p3 = mesh->verts[t.v[2]];
|
||||||
|
@@ -107,6 +107,13 @@ void Mesh::Triangle::verts_for_step(const float3 *verts,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Mesh::Triangle::valid(const float3 *verts) const
|
||||||
|
{
|
||||||
|
return isfinite3_safe(verts[v[0]]) &&
|
||||||
|
isfinite3_safe(verts[v[1]]) &&
|
||||||
|
isfinite3_safe(verts[v[2]]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Curve */
|
/* Curve */
|
||||||
|
|
||||||
void Mesh::Curve::bounds_grow(const int k, const float3 *curve_keys, const float *curve_radius, BoundBox& bounds) const
|
void Mesh::Curve::bounds_grow(const int k, const float3 *curve_keys, const float *curve_radius, BoundBox& bounds) const
|
||||||
|
@@ -70,6 +70,8 @@ public:
|
|||||||
size_t num_steps,
|
size_t num_steps,
|
||||||
size_t step,
|
size_t step,
|
||||||
float3 r_verts[3]) const;
|
float3 r_verts[3]) const;
|
||||||
|
|
||||||
|
bool valid(const float3 *verts) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
Triangle get_triangle(size_t i) const
|
Triangle get_triangle(size_t i) const
|
||||||
|
@@ -988,6 +988,8 @@ public:
|
|||||||
|
|
||||||
/* ideally we could beter detect this, but we can't query this now */
|
/* ideally we could beter detect this, but we can't query this now */
|
||||||
bool has_spatial_varying() { return true; }
|
bool has_spatial_varying() { return true; }
|
||||||
|
bool has_volume_support() { return true; }
|
||||||
|
|
||||||
virtual bool equals(const ShaderNode& /*other*/) { return false; }
|
virtual bool equals(const ShaderNode& /*other*/) { return false; }
|
||||||
|
|
||||||
string filepath;
|
string filepath;
|
||||||
|
@@ -33,7 +33,9 @@
|
|||||||
|
|
||||||
CCL_NAMESPACE_BEGIN
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
thread_mutex ShaderManager::lookup_table_mutex;
|
||||||
vector<float> ShaderManager::beckmann_table;
|
vector<float> ShaderManager::beckmann_table;
|
||||||
|
bool ShaderManager::beckmann_table_ready = false;
|
||||||
|
|
||||||
/* Beckmann sampling precomputed table, see bsdf_microfacet.h */
|
/* Beckmann sampling precomputed table, see bsdf_microfacet.h */
|
||||||
|
|
||||||
@@ -489,10 +491,11 @@ void ShaderManager::device_update_common(Device *device,
|
|||||||
|
|
||||||
/* beckmann lookup table */
|
/* beckmann lookup table */
|
||||||
if(beckmann_table_offset == TABLE_OFFSET_INVALID) {
|
if(beckmann_table_offset == TABLE_OFFSET_INVALID) {
|
||||||
if(beckmann_table.size() == 0) {
|
if(!beckmann_table_ready) {
|
||||||
thread_scoped_lock lock(lookup_table_mutex);
|
thread_scoped_lock lock(lookup_table_mutex);
|
||||||
if(beckmann_table.size() == 0) {
|
if(!beckmann_table_ready) {
|
||||||
beckmann_table_build(beckmann_table);
|
beckmann_table_build(beckmann_table);
|
||||||
|
beckmann_table_ready = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table);
|
beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table);
|
||||||
|
@@ -204,8 +204,9 @@ protected:
|
|||||||
typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
|
typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
|
||||||
AttributeIDMap unique_attribute_id;
|
AttributeIDMap unique_attribute_id;
|
||||||
|
|
||||||
thread_mutex lookup_table_mutex;
|
static thread_mutex lookup_table_mutex;
|
||||||
static vector<float> beckmann_table;
|
static vector<float> beckmann_table;
|
||||||
|
static bool beckmann_table_ready;
|
||||||
|
|
||||||
size_t beckmann_table_offset;
|
size_t beckmann_table_offset;
|
||||||
|
|
||||||
|
@@ -223,7 +223,7 @@ ccl_device_inline bool isfinite_safe(float f)
|
|||||||
{
|
{
|
||||||
/* By IEEE 754 rule, 2*Inf equals Inf */
|
/* By IEEE 754 rule, 2*Inf equals Inf */
|
||||||
unsigned int x = __float_as_uint(f);
|
unsigned int x = __float_as_uint(f);
|
||||||
return (f == f) && (x == 0 || (f != 2.0f*f)) && !((x << 1) > 0xff000000u);
|
return (f == f) && (x == 0 || x == (1u << 31) || (f != 2.0f*f)) && !((x << 1) > 0xff000000u);
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device_inline float ensure_finite(float v)
|
ccl_device_inline float ensure_finite(float v)
|
||||||
|
@@ -35,6 +35,9 @@
|
|||||||
|
|
||||||
#if defined(i386) || defined(_M_IX86)
|
#if defined(i386) || defined(_M_IX86)
|
||||||
|
|
||||||
|
/* We require minimum SSE2 support on x86, so auto enable. */
|
||||||
|
# define __KERNEL_SSE2__
|
||||||
|
|
||||||
# ifdef WITH_KERNEL_SSE2
|
# ifdef WITH_KERNEL_SSE2
|
||||||
# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
|
# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
|
||||||
# endif
|
# endif
|
||||||
|
@@ -25,7 +25,17 @@ CCL_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
OIIO_NAMESPACE_USING
|
OIIO_NAMESPACE_USING
|
||||||
|
|
||||||
|
#ifdef WITH_SYSTEM_PUGIXML
|
||||||
|
# define PUGIXML_NAMESPACE pugi
|
||||||
|
#else
|
||||||
|
# define PUGIXML_NAMESPACE OIIO_NAMESPACE::pugi
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using PUGIXML_NAMESPACE::xml_attribute;
|
||||||
|
using PUGIXML_NAMESPACE::xml_document;
|
||||||
|
using PUGIXML_NAMESPACE::xml_node;
|
||||||
|
using PUGIXML_NAMESPACE::xml_parse_result;
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
|
||||||
#endif /* __UTIL_XML_H__ */
|
#endif /* __UTIL_XML_H__ */
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
#define __EIGEN3_EIGENVALUES_C_API_CC__
|
#define __EIGEN3_EIGENVALUES_C_API_CC__
|
||||||
|
|
||||||
/* Eigen gives annoying huge amount of warnings here, silence them! */
|
/* Eigen gives annoying huge amount of warnings here, silence them! */
|
||||||
#ifdef __GNUC__
|
#if defined(__GNUC__) && !defined(__clang__)
|
||||||
# pragma GCC diagnostic ignored "-Wlogical-op"
|
# pragma GCC diagnostic ignored "-Wlogical-op"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
#define __EIGEN3_SVD_C_API_CC__
|
#define __EIGEN3_SVD_C_API_CC__
|
||||||
|
|
||||||
/* Eigen gives annoying huge amount of warnings here, silence them! */
|
/* Eigen gives annoying huge amount of warnings here, silence them! */
|
||||||
#ifdef __GNUC__
|
#if defined(__GNUC__) && !defined(__clang__)
|
||||||
# pragma GCC diagnostic ignored "-Wlogical-op"
|
# pragma GCC diagnostic ignored "-Wlogical-op"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -107,6 +107,14 @@ add_definitions(
|
|||||||
-DNEWDIRVELMOTEST=0
|
-DNEWDIRVELMOTEST=0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
# We need BLI_gzopen on win32 for unicode paths
|
||||||
|
add_definitions(
|
||||||
|
-DLBM_GZIP_OVERRIDE_H="${CMAKE_SOURCE_DIR}/source/blender/blenlib/BLI_fileops.h"
|
||||||
|
-D LBM_GZIP_OPEN_FN="\(gzFile\)BLI_gzopen"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_OPENMP)
|
if(WITH_OPENMP)
|
||||||
add_definitions(-DPARALLEL=1)
|
add_definitions(-DPARALLEL=1)
|
||||||
else()
|
else()
|
||||||
|
@@ -22,7 +22,11 @@
|
|||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#ifdef LBM_GZIP_OVERRIDE_H
|
||||||
|
# include LBM_GZIP_OVERRIDE_H
|
||||||
|
#else
|
||||||
|
# define LBM_GZIP_OPEN_FN(a, b) gzopen(a, b)
|
||||||
|
#endif
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Constructor
|
* Constructor
|
||||||
@@ -141,7 +145,8 @@ int ntlBlenderDumper::renderScene( void )
|
|||||||
std::ostringstream bvelfilename;
|
std::ostringstream bvelfilename;
|
||||||
bvelfilename << boutfilename.str();
|
bvelfilename << boutfilename.str();
|
||||||
bvelfilename << ".bvel.gz";
|
bvelfilename << ".bvel.gz";
|
||||||
gzf = gzopen(bvelfilename.str().c_str(), "wb9");
|
/* wraps gzopen */
|
||||||
|
gzf = LBM_GZIP_OPEN_FN(bvelfilename.str().c_str(), "wb9");
|
||||||
if(gzf) {
|
if(gzf) {
|
||||||
int numVerts;
|
int numVerts;
|
||||||
if(sizeof(numVerts)!=4) { errMsg("ntlBlenderDumper::renderScene","Invalid int size"); return 1; }
|
if(sizeof(numVerts)!=4) { errMsg("ntlBlenderDumper::renderScene","Invalid int size"); return 1; }
|
||||||
@@ -162,7 +167,8 @@ int ntlBlenderDumper::renderScene( void )
|
|||||||
|
|
||||||
// compress all bobj's
|
// compress all bobj's
|
||||||
boutfilename << ".bobj.gz";
|
boutfilename << ".bobj.gz";
|
||||||
gzf = gzopen(boutfilename.str().c_str(), "wb1"); // wb9 is slow for large meshes!
|
/* wraps gzopen */
|
||||||
|
gzf = LBM_GZIP_OPEN_FN(boutfilename.str().c_str(), "wb1"); // wb9 is slow for large meshes!
|
||||||
if (!gzf) {
|
if (!gzf) {
|
||||||
errMsg("ntlBlenderDumper::renderScene","Unable to open output '" + boutfilename.str() + "' ");
|
errMsg("ntlBlenderDumper::renderScene","Unable to open output '" + boutfilename.str() + "' ");
|
||||||
return 1; }
|
return 1; }
|
||||||
|
@@ -223,6 +223,13 @@ elseif(WITH_X11)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_X11_XFIXES)
|
||||||
|
add_definitions(-DWITH_X11_XFIXES)
|
||||||
|
list(APPEND INC_SYS
|
||||||
|
${X11_Xfixes_INCLUDE_PATH}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_X11_ALPHA)
|
if(WITH_X11_ALPHA)
|
||||||
add_definitions(-DWITH_X11_ALPHA)
|
add_definitions(-DWITH_X11_ALPHA)
|
||||||
endif()
|
endif()
|
||||||
|
@@ -1515,7 +1515,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
|||||||
GHOST_TInt32 x, y;
|
GHOST_TInt32 x, y;
|
||||||
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
|
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
|
||||||
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventRotate, x, y,
|
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventRotate, x, y,
|
||||||
[event rotation] * 5.0, 0));
|
[event rotation] * -5.0, 0));
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return GHOST_kFailure;
|
return GHOST_kFailure;
|
||||||
|
@@ -61,6 +61,12 @@
|
|||||||
#include <X11/XF86keysym.h>
|
#include <X11/XF86keysym.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_X11_XFIXES
|
||||||
|
# include <X11/extensions/Xfixes.h>
|
||||||
|
/* Workaround for XWayland grab glitch: T53004. */
|
||||||
|
#define WITH_XWAYLAND_HACK
|
||||||
|
#endif
|
||||||
|
|
||||||
/* for XIWarpPointer */
|
/* for XIWarpPointer */
|
||||||
#ifdef WITH_X11_XINPUT
|
#ifdef WITH_X11_XINPUT
|
||||||
# include <X11/extensions/XInput2.h>
|
# include <X11/extensions/XInput2.h>
|
||||||
@@ -95,6 +101,10 @@ static GHOST_TKey convertXKey(KeySym key);
|
|||||||
static char *txt_cut_buffer = NULL;
|
static char *txt_cut_buffer = NULL;
|
||||||
static char *txt_select_buffer = NULL;
|
static char *txt_select_buffer = NULL;
|
||||||
|
|
||||||
|
#ifdef WITH_XWAYLAND_HACK
|
||||||
|
static bool use_xwayland_hack = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
GHOST_SystemX11::
|
GHOST_SystemX11::
|
||||||
@@ -176,7 +186,11 @@ GHOST_SystemX11(
|
|||||||
if (use_xkb) {
|
if (use_xkb) {
|
||||||
XkbSetDetectableAutoRepeat(m_display, true, NULL);
|
XkbSetDetectableAutoRepeat(m_display, true, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_XWAYLAND_HACK
|
||||||
|
use_xwayland_hack = getenv("WAYLAND_DISPLAY") != NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_X11_XINPUT
|
#ifdef WITH_X11_XINPUT
|
||||||
/* detect if we have xinput (for reuse) */
|
/* detect if we have xinput (for reuse) */
|
||||||
{
|
{
|
||||||
@@ -1472,23 +1486,21 @@ getButtons(
|
|||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GHOST_TSuccess getCursorPosition_impl(
|
||||||
GHOST_TSuccess
|
Display *display,
|
||||||
GHOST_SystemX11::
|
GHOST_TInt32& x,
|
||||||
getCursorPosition(
|
GHOST_TInt32& y,
|
||||||
GHOST_TInt32& x,
|
Window *child_return)
|
||||||
GHOST_TInt32& y) const
|
|
||||||
{
|
{
|
||||||
|
|
||||||
Window root_return, child_return;
|
|
||||||
int rx, ry, wx, wy;
|
int rx, ry, wx, wy;
|
||||||
unsigned int mask_return;
|
unsigned int mask_return;
|
||||||
|
Window root_return;
|
||||||
|
|
||||||
if (XQueryPointer(
|
if (XQueryPointer(
|
||||||
m_display,
|
display,
|
||||||
RootWindow(m_display, DefaultScreen(m_display)),
|
RootWindow(display, DefaultScreen(display)),
|
||||||
&root_return,
|
&root_return,
|
||||||
&child_return,
|
child_return,
|
||||||
&rx, &ry,
|
&rx, &ry,
|
||||||
&wx, &wy,
|
&wx, &wy,
|
||||||
&mask_return
|
&mask_return
|
||||||
@@ -1498,10 +1510,20 @@ getCursorPosition(
|
|||||||
else {
|
else {
|
||||||
x = rx;
|
x = rx;
|
||||||
y = ry;
|
y = ry;
|
||||||
}
|
}
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GHOST_TSuccess
|
||||||
|
GHOST_SystemX11::
|
||||||
|
getCursorPosition(
|
||||||
|
GHOST_TInt32& x,
|
||||||
|
GHOST_TInt32& y) const
|
||||||
|
{
|
||||||
|
Window child_return;
|
||||||
|
return getCursorPosition_impl(m_display, x, y, &child_return);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GHOST_TSuccess
|
GHOST_TSuccess
|
||||||
GHOST_SystemX11::
|
GHOST_SystemX11::
|
||||||
@@ -1515,13 +1537,29 @@ setCursorPosition(
|
|||||||
* current pointer position. */
|
* current pointer position. */
|
||||||
|
|
||||||
int cx, cy;
|
int cx, cy;
|
||||||
|
|
||||||
|
#ifdef WITH_XWAYLAND_HACK
|
||||||
|
Window child_return = None;
|
||||||
|
if (getCursorPosition_impl(m_display, cx, cy, &child_return) == GHOST_kFailure) {
|
||||||
|
return GHOST_kFailure;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (getCursorPosition(cx, cy) == GHOST_kFailure) {
|
if (getCursorPosition(cx, cy) == GHOST_kFailure) {
|
||||||
return GHOST_kFailure;
|
return GHOST_kFailure;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int relx = x - cx;
|
int relx = x - cx;
|
||||||
int rely = y - cy;
|
int rely = y - cy;
|
||||||
|
|
||||||
|
#ifdef WITH_XWAYLAND_HACK
|
||||||
|
if (use_xwayland_hack) {
|
||||||
|
if (child_return != None) {
|
||||||
|
XFixesHideCursor(m_display, child_return);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_X11_XINPUT
|
#ifdef WITH_X11_XINPUT
|
||||||
if ((m_xinput_version.present) &&
|
if ((m_xinput_version.present) &&
|
||||||
(m_xinput_version.major_version >= 2))
|
(m_xinput_version.major_version >= 2))
|
||||||
@@ -1538,6 +1576,14 @@ setCursorPosition(
|
|||||||
XWarpPointer(m_display, None, None, 0, 0, 0, 0, relx, rely);
|
XWarpPointer(m_display, None, None, 0, 0, 0, 0, relx, rely);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_XWAYLAND_HACK
|
||||||
|
if (use_xwayland_hack) {
|
||||||
|
if (child_return != None) {
|
||||||
|
XFixesShowCursor(m_display, child_return);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
XSync(m_display, 0); /* Sync to process all requests */
|
XSync(m_display, 0); /* Sync to process all requests */
|
||||||
|
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
|
@@ -1530,7 +1530,6 @@ setWindowCursorGrab(
|
|||||||
else {
|
else {
|
||||||
if (m_cursorGrab == GHOST_kGrabHide) {
|
if (m_cursorGrab == GHOST_kGrabHide) {
|
||||||
m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
|
m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
|
||||||
setWindowCursorVisibility(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_cursorGrab != GHOST_kGrabNormal) {
|
if (m_cursorGrab != GHOST_kGrabNormal) {
|
||||||
@@ -1554,6 +1553,11 @@ setWindowCursorGrab(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Perform this last so to workaround XWayland bug, see: T53004. */
|
||||||
|
if (m_cursorGrab == GHOST_kGrabHide) {
|
||||||
|
setWindowCursorVisibility(true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
|
/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
|
||||||
setCursorGrabAccum(0, 0);
|
setCursorGrabAccum(0, 0);
|
||||||
m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
|
m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
|
||||||
|
@@ -38,6 +38,7 @@ set(SRC
|
|||||||
./intern/mallocn_lockfree_impl.c
|
./intern/mallocn_lockfree_impl.c
|
||||||
|
|
||||||
MEM_guardedalloc.h
|
MEM_guardedalloc.h
|
||||||
|
./intern/mallocn_inline.h
|
||||||
./intern/mallocn_intern.h
|
./intern/mallocn_intern.h
|
||||||
|
|
||||||
# only so the header is known by cmake
|
# only so the header is known by cmake
|
||||||
|
@@ -113,12 +113,26 @@ extern "C" {
|
|||||||
* pointer to it is stored ! */
|
* pointer to it is stored ! */
|
||||||
extern void *(*MEM_callocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
extern void *(*MEM_callocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a block of memory of size (len * size), with tag name
|
||||||
|
* str, aborting in case of integer overflows to prevent vulnerabilities.
|
||||||
|
* The memory is cleared. The name must be static, because only a
|
||||||
|
* pointer to it is stored ! */
|
||||||
|
extern void *(*MEM_calloc_arrayN)(size_t len, size_t size, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a block of memory of size len, with tag name str. The
|
* Allocate a block of memory of size len, with tag name str. The
|
||||||
* name must be a static, because only a pointer to it is stored !
|
* name must be a static, because only a pointer to it is stored !
|
||||||
* */
|
* */
|
||||||
extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a block of memory of size (len * size), with tag name str,
|
||||||
|
* aborting in case of integer overflow to prevent vulnerabilities. The
|
||||||
|
* name must be a static, because only a pointer to it is stored !
|
||||||
|
* */
|
||||||
|
extern void *(*MEM_malloc_arrayN)(size_t len, size_t size, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate an aligned block of memory of size len, with tag name str. The
|
* Allocate an aligned block of memory of size len, with tag name str. The
|
||||||
* name must be a static, because only a pointer to it is stored !
|
* name must be a static, because only a pointer to it is stored !
|
||||||
|
@@ -43,7 +43,9 @@ void *(*MEM_dupallocN)(const void *vmemh) = MEM_lockfree_dupallocN;
|
|||||||
void *(*MEM_reallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_reallocN_id;
|
void *(*MEM_reallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_reallocN_id;
|
||||||
void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_recallocN_id;
|
void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_recallocN_id;
|
||||||
void *(*MEM_callocN)(size_t len, const char *str) = MEM_lockfree_callocN;
|
void *(*MEM_callocN)(size_t len, const char *str) = MEM_lockfree_callocN;
|
||||||
|
void *(*MEM_calloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockfree_calloc_arrayN;
|
||||||
void *(*MEM_mallocN)(size_t len, const char *str) = MEM_lockfree_mallocN;
|
void *(*MEM_mallocN)(size_t len, const char *str) = MEM_lockfree_mallocN;
|
||||||
|
void *(*MEM_malloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockfree_malloc_arrayN;
|
||||||
void *(*MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str) = MEM_lockfree_mallocN_aligned;
|
void *(*MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str) = MEM_lockfree_mallocN_aligned;
|
||||||
void *(*MEM_mapallocN)(size_t len, const char *str) = MEM_lockfree_mapallocN;
|
void *(*MEM_mapallocN)(size_t len, const char *str) = MEM_lockfree_mapallocN;
|
||||||
void (*MEM_printmemlist_pydict)(void) = MEM_lockfree_printmemlist_pydict;
|
void (*MEM_printmemlist_pydict)(void) = MEM_lockfree_printmemlist_pydict;
|
||||||
@@ -107,7 +109,9 @@ void MEM_use_guarded_allocator(void)
|
|||||||
MEM_reallocN_id = MEM_guarded_reallocN_id;
|
MEM_reallocN_id = MEM_guarded_reallocN_id;
|
||||||
MEM_recallocN_id = MEM_guarded_recallocN_id;
|
MEM_recallocN_id = MEM_guarded_recallocN_id;
|
||||||
MEM_callocN = MEM_guarded_callocN;
|
MEM_callocN = MEM_guarded_callocN;
|
||||||
|
MEM_calloc_arrayN = MEM_guarded_calloc_arrayN;
|
||||||
MEM_mallocN = MEM_guarded_mallocN;
|
MEM_mallocN = MEM_guarded_mallocN;
|
||||||
|
MEM_malloc_arrayN = MEM_guarded_malloc_arrayN;
|
||||||
MEM_mallocN_aligned = MEM_guarded_mallocN_aligned;
|
MEM_mallocN_aligned = MEM_guarded_mallocN_aligned;
|
||||||
MEM_mapallocN = MEM_guarded_mapallocN;
|
MEM_mapallocN = MEM_guarded_mapallocN;
|
||||||
MEM_printmemlist_pydict = MEM_guarded_printmemlist_pydict;
|
MEM_printmemlist_pydict = MEM_guarded_printmemlist_pydict;
|
||||||
|
@@ -542,6 +542,21 @@ void *MEM_guarded_mallocN(size_t len, const char *str)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *MEM_guarded_malloc_arrayN(size_t len, size_t size, const char *str)
|
||||||
|
{
|
||||||
|
size_t total_size;
|
||||||
|
if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
|
||||||
|
print_error("Malloc array aborted due to integer overflow: "
|
||||||
|
"len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
|
||||||
|
SIZET_ARG(len), SIZET_ARG(size), str,
|
||||||
|
(unsigned int) mem_in_use);
|
||||||
|
abort();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MEM_guarded_mallocN(total_size, str);
|
||||||
|
}
|
||||||
|
|
||||||
void *MEM_guarded_mallocN_aligned(size_t len, size_t alignment, const char *str)
|
void *MEM_guarded_mallocN_aligned(size_t len, size_t alignment, const char *str)
|
||||||
{
|
{
|
||||||
MemHead *memh;
|
MemHead *memh;
|
||||||
@@ -612,6 +627,21 @@ void *MEM_guarded_callocN(size_t len, const char *str)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *MEM_guarded_calloc_arrayN(size_t len, size_t size, const char *str)
|
||||||
|
{
|
||||||
|
size_t total_size;
|
||||||
|
if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
|
||||||
|
print_error("Calloc array aborted due to integer overflow: "
|
||||||
|
"len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
|
||||||
|
SIZET_ARG(len), SIZET_ARG(size), str,
|
||||||
|
(unsigned int) mem_in_use);
|
||||||
|
abort();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MEM_guarded_callocN(total_size, str);
|
||||||
|
}
|
||||||
|
|
||||||
/* note; mmap returns zero'd memory */
|
/* note; mmap returns zero'd memory */
|
||||||
void *MEM_guarded_mapallocN(size_t len, const char *str)
|
void *MEM_guarded_mapallocN(size_t len, const char *str)
|
||||||
{
|
{
|
||||||
|
56
intern/guardedalloc/intern/mallocn_inline.h
Normal file
56
intern/guardedalloc/intern/mallocn_inline.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Adapted from jemalloc, to protect against buffer overflow vulnerabilities.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002-2017 Jason Evans <jasone@canonware.com>.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
|
||||||
|
* Copyright (C) 2009-2017 Facebook, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice(s),
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file guardedalloc/intern/mallocn_inline.h
|
||||||
|
* \ingroup MEM
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MALLOCN_INLINE_H__
|
||||||
|
#define __MALLOCN_INLINE_H__
|
||||||
|
|
||||||
|
MEM_INLINE bool MEM_size_safe_multiply(size_t a, size_t b, size_t *result)
|
||||||
|
{
|
||||||
|
/* A size_t with its high-half bits all set to 1. */
|
||||||
|
const size_t high_bits = SIZE_MAX << (sizeof(size_t) * 8 / 2);
|
||||||
|
*result = a * b;
|
||||||
|
|
||||||
|
if (UNLIKELY(*result == 0)) {
|
||||||
|
return (a == 0 || b == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We got a non-zero size, but we don't know if we overflowed to get
|
||||||
|
* there. To avoid having to do a divide, we'll be clever and note that
|
||||||
|
* if both A and B can be represented in N/2 bits, then their product
|
||||||
|
* can be represented in N bits (without the possibility of overflow).
|
||||||
|
*/
|
||||||
|
return ((high_bits & (a | b)) == 0 || (*result / b == a));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __MALLOCN_INLINE_H__ */
|
||||||
|
|
@@ -112,6 +112,8 @@
|
|||||||
/* Real pointer returned by the malloc or aligned_alloc. */
|
/* Real pointer returned by the malloc or aligned_alloc. */
|
||||||
#define MEMHEAD_REAL_PTR(memh) ((char *)memh - MEMHEAD_ALIGN_PADDING(memh->alignment))
|
#define MEMHEAD_REAL_PTR(memh) ((char *)memh - MEMHEAD_ALIGN_PADDING(memh->alignment))
|
||||||
|
|
||||||
|
#include "mallocn_inline.h"
|
||||||
|
|
||||||
void *aligned_malloc(size_t size, size_t alignment);
|
void *aligned_malloc(size_t size, size_t alignment);
|
||||||
void aligned_free(void *ptr);
|
void aligned_free(void *ptr);
|
||||||
|
|
||||||
@@ -122,7 +124,9 @@ void *MEM_lockfree_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RES
|
|||||||
void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
|
void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
|
||||||
void *MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
|
void *MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
|
||||||
void *MEM_lockfree_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
void *MEM_lockfree_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||||
|
void *MEM_lockfree_calloc_arrayN(size_t len, size_t size, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
|
||||||
void *MEM_lockfree_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
void *MEM_lockfree_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||||
|
void *MEM_lockfree_malloc_arrayN(size_t len, size_t size, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
|
||||||
void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
|
void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
|
||||||
void *MEM_lockfree_mapallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
void *MEM_lockfree_mapallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||||
void MEM_lockfree_printmemlist_pydict(void);
|
void MEM_lockfree_printmemlist_pydict(void);
|
||||||
@@ -149,7 +153,9 @@ void *MEM_guarded_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESU
|
|||||||
void *MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
|
void *MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
|
||||||
void *MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
|
void *MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
|
||||||
void *MEM_guarded_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
void *MEM_guarded_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||||
|
void *MEM_guarded_calloc_arrayN(size_t len, size_t size, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
|
||||||
void *MEM_guarded_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
void *MEM_guarded_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||||
|
void *MEM_guarded_malloc_arrayN(size_t len, size_t size, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
|
||||||
void *MEM_guarded_mallocN_aligned(size_t len, size_t alignment, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
|
void *MEM_guarded_mallocN_aligned(size_t len, size_t alignment, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
|
||||||
void *MEM_guarded_mapallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
void *MEM_guarded_mapallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||||
void MEM_guarded_printmemlist_pydict(void);
|
void MEM_guarded_printmemlist_pydict(void);
|
||||||
|
@@ -298,6 +298,21 @@ void *MEM_lockfree_callocN(size_t len, const char *str)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *MEM_lockfree_calloc_arrayN(size_t len, size_t size, const char *str)
|
||||||
|
{
|
||||||
|
size_t total_size;
|
||||||
|
if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
|
||||||
|
print_error("Calloc array aborted due to integer overflow: "
|
||||||
|
"len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
|
||||||
|
SIZET_ARG(len), SIZET_ARG(size), str,
|
||||||
|
(unsigned int) mem_in_use);
|
||||||
|
abort();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MEM_lockfree_callocN(total_size, str);
|
||||||
|
}
|
||||||
|
|
||||||
void *MEM_lockfree_mallocN(size_t len, const char *str)
|
void *MEM_lockfree_mallocN(size_t len, const char *str)
|
||||||
{
|
{
|
||||||
MemHead *memh;
|
MemHead *memh;
|
||||||
@@ -323,6 +338,21 @@ void *MEM_lockfree_mallocN(size_t len, const char *str)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *MEM_lockfree_malloc_arrayN(size_t len, size_t size, const char *str)
|
||||||
|
{
|
||||||
|
size_t total_size;
|
||||||
|
if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
|
||||||
|
print_error("Malloc array aborted due to integer overflow: "
|
||||||
|
"len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
|
||||||
|
SIZET_ARG(len), SIZET_ARG(size), str,
|
||||||
|
(unsigned int) mem_in_use);
|
||||||
|
abort();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MEM_lockfree_mallocN(total_size, str);
|
||||||
|
}
|
||||||
|
|
||||||
void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str)
|
void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str)
|
||||||
{
|
{
|
||||||
MemHeadAligned *memh;
|
MemHeadAligned *memh;
|
||||||
|
@@ -1817,47 +1817,134 @@ static void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int i
|
|||||||
assert(iNrTrianglesIn == t);
|
assert(iNrTrianglesIn == t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DegenEpilogue(STSpace psTspace[], STriInfo pTriInfos[], int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn, const int iTotTris)
|
typedef struct VertReverseLookupContext {
|
||||||
|
tbool bIsInitialized;
|
||||||
|
int * pLookup;
|
||||||
|
int iMaxVertIndex;
|
||||||
|
} VertReverseLookupContext;
|
||||||
|
|
||||||
|
static void GenerateReverseLookup(
|
||||||
|
const int piTriListIn[],
|
||||||
|
const int iNrTrianglesIn,
|
||||||
|
VertReverseLookupContext *pLookupCtx)
|
||||||
|
{
|
||||||
|
int t;
|
||||||
|
// Figure out what size of lookup array we need.
|
||||||
|
pLookupCtx->iMaxVertIndex = -1;
|
||||||
|
for (t=0; t<3*iNrTrianglesIn; t++)
|
||||||
|
{
|
||||||
|
int iVertIndex = piTriListIn[t];
|
||||||
|
if (iVertIndex > pLookupCtx->iMaxVertIndex) {
|
||||||
|
pLookupCtx->iMaxVertIndex = iVertIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Allocate memory.
|
||||||
|
if (pLookupCtx->iMaxVertIndex < 1)
|
||||||
|
{
|
||||||
|
// Nothing to allocate, all triangles are degenerate.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pLookupCtx->pLookup = malloc(sizeof(int) * (pLookupCtx->iMaxVertIndex + 1));
|
||||||
|
if (pLookupCtx->pLookup == NULL)
|
||||||
|
{
|
||||||
|
// Most likely run out of memory.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Fill in lookup.
|
||||||
|
for (t=0; t<=pLookupCtx->iMaxVertIndex; t++) {
|
||||||
|
pLookupCtx->pLookup[t] = -1;
|
||||||
|
}
|
||||||
|
for (t=0; t<3*iNrTrianglesIn; t++)
|
||||||
|
{
|
||||||
|
int iVertIndex = piTriListIn[t];
|
||||||
|
if (pLookupCtx->pLookup[iVertIndex] != -1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pLookupCtx->pLookup[iVertIndex] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LookupVertexIndexFromGoodTriangle(
|
||||||
|
VertReverseLookupContext *pLookupCtx,
|
||||||
|
int piTriListIn[],
|
||||||
|
const int iNrTrianglesIn,
|
||||||
|
const int iVertexIndex)
|
||||||
|
{
|
||||||
|
// Allocate lookup on demand.
|
||||||
|
if (!pLookupCtx->bIsInitialized)
|
||||||
|
{
|
||||||
|
GenerateReverseLookup(piTriListIn,
|
||||||
|
iNrTrianglesIn,
|
||||||
|
pLookupCtx);
|
||||||
|
pLookupCtx->bIsInitialized = TTRUE;
|
||||||
|
}
|
||||||
|
// Make sure vertex index is in the mapping.
|
||||||
|
if (iVertexIndex > pLookupCtx->iMaxVertIndex)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (pLookupCtx->pLookup == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Perform actual lookup.
|
||||||
|
return pLookupCtx->pLookup[iVertexIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeReverseLookup(VertReverseLookupContext *pLookupCtx)
|
||||||
|
{
|
||||||
|
if (!pLookupCtx->bIsInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pLookupCtx->pLookup != NULL) {
|
||||||
|
free(pLookupCtx->pLookup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DegenEpilogue(STSpace psTspace[],
|
||||||
|
STriInfo pTriInfos[],
|
||||||
|
int piTriListIn[],
|
||||||
|
const SMikkTSpaceContext * pContext,
|
||||||
|
const int iNrTrianglesIn,
|
||||||
|
const int iTotTris)
|
||||||
{
|
{
|
||||||
int t=0, i=0;
|
int t=0, i=0;
|
||||||
|
VertReverseLookupContext lookupCtx = { TFALSE };
|
||||||
// deal with degenerate triangles
|
// deal with degenerate triangles
|
||||||
// punishment for degenerate triangles is O(N^2)
|
// punishment for degenerate triangles is O(iNrTrianglesIn) extra memory.
|
||||||
for (t=iNrTrianglesIn; t<iTotTris; t++)
|
for (t=iNrTrianglesIn; t<iTotTris; t++)
|
||||||
{
|
{
|
||||||
// degenerate triangles on a quad with one good triangle are skipped
|
// degenerate triangles on a quad with one good triangle are skipped
|
||||||
// here but processed in the next loop
|
// here but processed in the next loop
|
||||||
const tbool bSkip = (pTriInfos[t].iFlag&QUAD_ONE_DEGEN_TRI)!=0 ? TTRUE : TFALSE;
|
const tbool bSkip = (pTriInfos[t].iFlag&QUAD_ONE_DEGEN_TRI)!=0 ? TTRUE : TFALSE;
|
||||||
|
if (bSkip) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!bSkip)
|
for (i=0; i<3; i++)
|
||||||
{
|
{
|
||||||
for (i=0; i<3; i++)
|
const int index1 = piTriListIn[t*3+i];
|
||||||
|
int j = LookupVertexIndexFromGoodTriangle(&lookupCtx,
|
||||||
|
piTriListIn,
|
||||||
|
iNrTrianglesIn,
|
||||||
|
index1);
|
||||||
|
if (j < 0)
|
||||||
{
|
{
|
||||||
const int index1 = piTriListIn[t*3+i];
|
// Matching vertex from good triangle is not found.
|
||||||
// search through the good triangles
|
continue;
|
||||||
tbool bNotFound = TTRUE;
|
|
||||||
int j=0;
|
|
||||||
while (bNotFound && j<(3*iNrTrianglesIn))
|
|
||||||
{
|
|
||||||
const int index2 = piTriListIn[j];
|
|
||||||
if (index1==index2) bNotFound=TFALSE;
|
|
||||||
else ++j;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bNotFound)
|
|
||||||
{
|
|
||||||
const int iTri = j/3;
|
|
||||||
const int iVert = j%3;
|
|
||||||
const int iSrcVert=pTriInfos[iTri].vert_num[iVert];
|
|
||||||
const int iSrcOffs=pTriInfos[iTri].iTSpacesOffs;
|
|
||||||
const int iDstVert=pTriInfos[t].vert_num[i];
|
|
||||||
const int iDstOffs=pTriInfos[t].iTSpacesOffs;
|
|
||||||
|
|
||||||
// copy tspace
|
|
||||||
psTspace[iDstOffs+iDstVert] = psTspace[iSrcOffs+iSrcVert];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int iTri = j/3;
|
||||||
|
const int iVert = j%3;
|
||||||
|
const int iSrcVert=pTriInfos[iTri].vert_num[iVert];
|
||||||
|
const int iSrcOffs=pTriInfos[iTri].iTSpacesOffs;
|
||||||
|
const int iDstVert=pTriInfos[t].vert_num[i];
|
||||||
|
const int iDstOffs=pTriInfos[t].iTSpacesOffs;
|
||||||
|
// copy tspace
|
||||||
|
psTspace[iDstOffs+iDstVert] = psTspace[iSrcOffs+iSrcVert];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FreeReverseLookup(&lookupCtx);
|
||||||
|
|
||||||
// deal with degenerate quads with one good triangle
|
// deal with degenerate quads with one good triangle
|
||||||
for (t=0; t<iNrTrianglesIn; t++)
|
for (t=0; t<iNrTrianglesIn; t++)
|
||||||
|
@@ -45,7 +45,11 @@ void OpenVDBWriter::insert(const openvdb::GridBase::Ptr &grid)
|
|||||||
|
|
||||||
void OpenVDBWriter::insert(const openvdb::GridBase &grid)
|
void OpenVDBWriter::insert(const openvdb::GridBase &grid)
|
||||||
{
|
{
|
||||||
|
#if (OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER == 3)
|
||||||
m_grids->push_back(grid.copyGrid());
|
m_grids->push_back(grid.copyGrid());
|
||||||
|
#else
|
||||||
|
m_grids->push_back(grid.copyGridWithNewTree());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenVDBWriter::insertFloatMeta(const openvdb::Name &name, const float value)
|
void OpenVDBWriter::insertFloatMeta(const openvdb::Name &name, const float value)
|
||||||
|
Submodule release/datafiles/locale updated: c93ed11a47...1bbc9bdabe
Submodule release/scripts/addons updated: 371960484a...bd60e89fa0
@@ -77,7 +77,7 @@ def ui_draw_filter_register(
|
|||||||
return UILayout_Fake(ret)
|
return UILayout_Fake(ret)
|
||||||
return dummy_func
|
return dummy_func
|
||||||
|
|
||||||
elif attr in {"operator", "operator_menu_enum", "operator_enum"}:
|
elif attr in {"operator", "operator_menu_enum", "operator_enum", "operator_menu_hold"}:
|
||||||
if ui_ignore_operator is None:
|
if ui_ignore_operator is None:
|
||||||
return UILayout.__getattribute__(self, attr)
|
return UILayout.__getattribute__(self, attr)
|
||||||
|
|
||||||
@@ -85,10 +85,14 @@ def ui_draw_filter_register(
|
|||||||
|
|
||||||
def dummy_func(*args, **kw):
|
def dummy_func(*args, **kw):
|
||||||
# print("wrapped", attr)
|
# print("wrapped", attr)
|
||||||
if not ui_ignore_operator(args[0]):
|
ui_test = ui_ignore_operator(args[0])
|
||||||
|
if ui_test is False:
|
||||||
ret = real_func(*args, **kw)
|
ret = real_func(*args, **kw)
|
||||||
else:
|
else:
|
||||||
# UILayout.__getattribute__(self, "label")()
|
if ui_test is None:
|
||||||
|
UILayout.__getattribute__(self, "label")("")
|
||||||
|
else:
|
||||||
|
assert(ui_test is True)
|
||||||
# may need to be set
|
# may need to be set
|
||||||
ret = OperatorProperties_Fake()
|
ret = OperatorProperties_Fake()
|
||||||
return ret
|
return ret
|
||||||
@@ -102,9 +106,14 @@ def ui_draw_filter_register(
|
|||||||
|
|
||||||
def dummy_func(*args, **kw):
|
def dummy_func(*args, **kw):
|
||||||
# print("wrapped", attr)
|
# print("wrapped", attr)
|
||||||
if not ui_ignore_property(args[0].__class__.__name__, args[1]):
|
ui_test = ui_ignore_property(args[0].__class__.__name__, args[1])
|
||||||
|
if ui_test is False:
|
||||||
ret = real_func(*args, **kw)
|
ret = real_func(*args, **kw)
|
||||||
else:
|
else:
|
||||||
|
if ui_test is None:
|
||||||
|
UILayout.__getattribute__(self, "label")("")
|
||||||
|
else:
|
||||||
|
assert(ui_test is True)
|
||||||
ret = None
|
ret = None
|
||||||
return ret
|
return ret
|
||||||
return dummy_func
|
return dummy_func
|
||||||
@@ -117,9 +126,14 @@ def ui_draw_filter_register(
|
|||||||
|
|
||||||
def dummy_func(*args, **kw):
|
def dummy_func(*args, **kw):
|
||||||
# print("wrapped", attr)
|
# print("wrapped", attr)
|
||||||
if not ui_ignore_menu(args[0]):
|
ui_test = ui_ignore_menu(args[0])
|
||||||
|
if ui_test is False:
|
||||||
ret = real_func(*args, **kw)
|
ret = real_func(*args, **kw)
|
||||||
else:
|
else:
|
||||||
|
if ui_test is None:
|
||||||
|
UILayout.__getattribute__(self, "label")("")
|
||||||
|
else:
|
||||||
|
assert(ui_test is True)
|
||||||
ret = None
|
ret = None
|
||||||
return ret
|
return ret
|
||||||
return dummy_func
|
return dummy_func
|
||||||
@@ -132,10 +146,14 @@ def ui_draw_filter_register(
|
|||||||
|
|
||||||
def dummy_func(*args, **kw):
|
def dummy_func(*args, **kw):
|
||||||
# print("wrapped", attr)
|
# print("wrapped", attr)
|
||||||
if not ui_ignore_label(args[0] if args else kw.get("text", "")):
|
ui_test = ui_ignore_label(args[0] if args else kw.get("text", ""))
|
||||||
|
if ui_test is False:
|
||||||
ret = real_func(*args, **kw)
|
ret = real_func(*args, **kw)
|
||||||
else:
|
else:
|
||||||
# ret = real_func()
|
if ui_test is None:
|
||||||
|
real_func("")
|
||||||
|
else:
|
||||||
|
assert(ui_test is True)
|
||||||
ret = None
|
ret = None
|
||||||
return ret
|
return ret
|
||||||
return dummy_func
|
return dummy_func
|
||||||
|
@@ -278,7 +278,7 @@ def do_previews(do_objects, do_groups, do_scenes, do_data_intern):
|
|||||||
bbox[1].z = v.z
|
bbox[1].z = v.z
|
||||||
|
|
||||||
def objects_bbox_calc(camera, objects, offset_matrix):
|
def objects_bbox_calc(camera, objects, offset_matrix):
|
||||||
bbox = (Vector((1e9, 1e9, 1e9)), Vector((-1e9, -1e9, -1e9)))
|
bbox = (Vector((1e24, 1e24, 1e24)), Vector((-1e24, -1e24, -1e24)))
|
||||||
for obname, libpath in objects:
|
for obname, libpath in objects:
|
||||||
ob = bpy.data.objects[obname, libpath]
|
ob = bpy.data.objects[obname, libpath]
|
||||||
object_bbox_merge(bbox, ob, camera, offset_matrix)
|
object_bbox_merge(bbox, ob, camera, offset_matrix)
|
||||||
@@ -305,6 +305,17 @@ def do_previews(do_objects, do_groups, do_scenes, do_data_intern):
|
|||||||
cos = objects_bbox_calc(camera, objects, offset_matrix)
|
cos = objects_bbox_calc(camera, objects, offset_matrix)
|
||||||
loc, ortho_scale = camera.camera_fit_coords(scene, cos)
|
loc, ortho_scale = camera.camera_fit_coords(scene, cos)
|
||||||
camera.location = loc
|
camera.location = loc
|
||||||
|
# Set camera clipping accordingly to computed bbox.
|
||||||
|
min_dist = 1e24
|
||||||
|
max_dist = -1e24
|
||||||
|
for co in zip(*(iter(cos),) * 3):
|
||||||
|
dist = (Vector(co) - loc).length
|
||||||
|
if dist < min_dist:
|
||||||
|
min_dist = dist
|
||||||
|
if dist > max_dist:
|
||||||
|
max_dist = dist
|
||||||
|
camera.data.clip_start = min_dist / 2
|
||||||
|
camera.data.clip_end = max_dist * 2
|
||||||
if lamp:
|
if lamp:
|
||||||
loc, ortho_scale = lamp.camera_fit_coords(scene, cos)
|
loc, ortho_scale = lamp.camera_fit_coords(scene, cos)
|
||||||
lamp.location = loc
|
lamp.location = loc
|
||||||
|
@@ -28,6 +28,7 @@ __all__ = (
|
|||||||
"basename",
|
"basename",
|
||||||
"clean_name",
|
"clean_name",
|
||||||
"display_name",
|
"display_name",
|
||||||
|
"display_name_to_filepath",
|
||||||
"display_name_from_filepath",
|
"display_name_from_filepath",
|
||||||
"ensure_ext",
|
"ensure_ext",
|
||||||
"extensions_image",
|
"extensions_image",
|
||||||
@@ -193,6 +194,12 @@ def _clean_utf8(name):
|
|||||||
return name.encode("utf8", "replace").decode("utf8")
|
return name.encode("utf8", "replace").decode("utf8")
|
||||||
|
|
||||||
|
|
||||||
|
_display_name_literals = {
|
||||||
|
":": "_colon_",
|
||||||
|
"+": "_plus_",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def display_name(name):
|
def display_name(name):
|
||||||
"""
|
"""
|
||||||
Creates a display string from name to be used menus and the user interface.
|
Creates a display string from name to be used menus and the user interface.
|
||||||
@@ -201,8 +208,8 @@ def display_name(name):
|
|||||||
filenames and module names.
|
filenames and module names.
|
||||||
"""
|
"""
|
||||||
# string replacements
|
# string replacements
|
||||||
name = name.replace("_colon_", ":")
|
for disp_value, file_value in _display_name_literals.items():
|
||||||
name = name.replace("_plus_", "+")
|
name = name.replace(file_value, disp_value)
|
||||||
|
|
||||||
# strip to allow underscore prefix
|
# strip to allow underscore prefix
|
||||||
# (when paths can't start with numbers for eg).
|
# (when paths can't start with numbers for eg).
|
||||||
@@ -214,6 +221,15 @@ def display_name(name):
|
|||||||
name = _clean_utf8(name)
|
name = _clean_utf8(name)
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
def display_name_to_filepath(name):
|
||||||
|
"""
|
||||||
|
Performs the reverse of display_name using literal versions of characters
|
||||||
|
which aren't supported in a filepath.
|
||||||
|
"""
|
||||||
|
for disp_value, file_value in _display_name_literals.items():
|
||||||
|
name = name.replace(disp_value, file_value)
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
def display_name_from_filepath(name):
|
def display_name_from_filepath(name):
|
||||||
"""
|
"""
|
||||||
|
@@ -399,27 +399,26 @@ def app_template_paths(subdir=None):
|
|||||||
:return: app template paths.
|
:return: app template paths.
|
||||||
:rtype: generator
|
:rtype: generator
|
||||||
"""
|
"""
|
||||||
|
# Note: keep in sync with: Blender's BKE_appdir_app_template_any
|
||||||
|
|
||||||
# note: LOCAL, USER, SYSTEM order matches script resolution order.
|
|
||||||
subdir_tuple = (subdir,) if subdir is not None else ()
|
subdir_tuple = (subdir,) if subdir is not None else ()
|
||||||
|
|
||||||
path = _os.path.join(*(
|
# Avoid adding 'bl_app_templates_system' twice.
|
||||||
resource_path('LOCAL'), "scripts", "startup",
|
# Either we have a portable build or an installed system build.
|
||||||
"bl_app_templates_user", *subdir_tuple))
|
for resource_type, module_name in (
|
||||||
if _os.path.isdir(path):
|
('USER', "bl_app_templates_user"),
|
||||||
yield path
|
('LOCAL', "bl_app_templates_system"),
|
||||||
else:
|
('SYSTEM', "bl_app_templates_system"),
|
||||||
path = _os.path.join(*(
|
):
|
||||||
resource_path('USER'), "scripts", "startup",
|
path = resource_path(resource_type)
|
||||||
"bl_app_templates_user", *subdir_tuple))
|
if path:
|
||||||
if _os.path.isdir(path):
|
path = _os.path.join(
|
||||||
yield path
|
*(path, "scripts", "startup", module_name, *subdir_tuple))
|
||||||
|
if _os.path.isdir(path):
|
||||||
path = _os.path.join(*(
|
yield path
|
||||||
resource_path('SYSTEM'), "scripts", "startup",
|
# Only load LOCAL or SYSTEM (never both).
|
||||||
"bl_app_templates_system", *subdir_tuple))
|
if resource_type == 'LOCAL':
|
||||||
if _os.path.isdir(path):
|
break
|
||||||
yield path
|
|
||||||
|
|
||||||
|
|
||||||
def preset_paths(subdir):
|
def preset_paths(subdir):
|
||||||
|
@@ -230,6 +230,7 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout):
|
|||||||
"`": 'ACCENT_GRAVE',
|
"`": 'ACCENT_GRAVE',
|
||||||
"*": 'NUMPAD_ASTERIX',
|
"*": 'NUMPAD_ASTERIX',
|
||||||
"/": 'NUMPAD_SLASH',
|
"/": 'NUMPAD_SLASH',
|
||||||
|
'+': 'NUMPAD_PLUS',
|
||||||
"RMB": 'RIGHTMOUSE',
|
"RMB": 'RIGHTMOUSE',
|
||||||
"LMB": 'LEFTMOUSE',
|
"LMB": 'LEFTMOUSE',
|
||||||
"MMB": 'MIDDLEMOUSE',
|
"MMB": 'MIDDLEMOUSE',
|
||||||
|
@@ -110,7 +110,7 @@
|
|||||||
inner="#39424bcc"
|
inner="#39424bcc"
|
||||||
inner_sel="#667686bf"
|
inner_sel="#667686bf"
|
||||||
item="#191919ff"
|
item="#191919ff"
|
||||||
text="#000000"
|
text="#b8b8b8"
|
||||||
text_sel="#ffffff"
|
text_sel="#ffffff"
|
||||||
show_shaded="TRUE"
|
show_shaded="TRUE"
|
||||||
shadetop="25"
|
shadetop="25"
|
||||||
|
@@ -110,7 +110,7 @@
|
|||||||
inner="#4b4b4bff"
|
inner="#4b4b4bff"
|
||||||
inner_sel="#646464ff"
|
inner_sel="#646464ff"
|
||||||
item="#191919ff"
|
item="#191919ff"
|
||||||
text="#000000"
|
text="#b8b8b8"
|
||||||
text_sel="#ffffff"
|
text_sel="#ffffff"
|
||||||
show_shaded="TRUE"
|
show_shaded="TRUE"
|
||||||
shadetop="0"
|
shadetop="0"
|
||||||
|
@@ -110,7 +110,7 @@
|
|||||||
inner="#303030ff"
|
inner="#303030ff"
|
||||||
inner_sel="#678db2ff"
|
inner_sel="#678db2ff"
|
||||||
item="#191919ff"
|
item="#191919ff"
|
||||||
text="#272727"
|
text="#e6f1ff"
|
||||||
text_sel="#ffffff"
|
text_sel="#ffffff"
|
||||||
show_shaded="FALSE"
|
show_shaded="FALSE"
|
||||||
shadetop="0"
|
shadetop="0"
|
||||||
|
@@ -137,6 +137,9 @@ class ANIM_OT_keying_set_export(Operator):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.report({'WARN'}, "Could not find scene using Compositor Node Tree - %s" % (ksp.id))
|
self.report({'WARN'}, "Could not find scene using Compositor Node Tree - %s" % (ksp.id))
|
||||||
|
elif ksp.id.bl_rna.name == "Key":
|
||||||
|
# "keys" conflicts with a Python keyword, hence the simple solution won't work
|
||||||
|
id_bpy_path = "bpy.data.shape_keys[\"%s\"]" % (ksp.id.name)
|
||||||
else:
|
else:
|
||||||
idtype_list = ksp.id.bl_rna.name.lower() + "s"
|
idtype_list = ksp.id.bl_rna.name.lower() + "s"
|
||||||
id_bpy_path = "bpy.data.%s[\"%s\"]" % (idtype_list, ksp.id.name)
|
id_bpy_path = "bpy.data.%s[\"%s\"]" % (idtype_list, ksp.id.name)
|
||||||
|
@@ -298,7 +298,7 @@ class CLIP_OT_bundles_to_mesh(Operator):
|
|||||||
|
|
||||||
mesh = bpy.data.meshes.new(name="Tracks")
|
mesh = bpy.data.meshes.new(name="Tracks")
|
||||||
for track in tracking_object.tracks:
|
for track in tracking_object.tracks:
|
||||||
if track.has_bundle:
|
if track.has_bundle and track.select == True:
|
||||||
new_verts.append(track.bundle)
|
new_verts.append(track.bundle)
|
||||||
|
|
||||||
if new_verts:
|
if new_verts:
|
||||||
|
@@ -78,10 +78,10 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator):
|
|||||||
self.report({'ERROR'}, "Unexpected modifier type: " + m.type)
|
self.report({'ERROR'}, "Unexpected modifier type: " + m.type)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
# Find selected vertices in editmesh
|
# Find selected vertices in editmesh
|
||||||
ob = bpy.context.active_object
|
ob = context.active_object
|
||||||
if ob.type == 'MESH' and ob.mode == 'EDIT' and ob.name != ref.name:
|
if ob.type == 'MESH' and ob.mode == 'EDIT' and ob.name != ref.name:
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
selected_verts = [v for v in bpy.context.active_object.data.vertices if v.select]
|
selected_verts = [v for v in ob.data.vertices if v.select]
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
# Compute the min/max distance from the reference to mesh vertices
|
# Compute the min/max distance from the reference to mesh vertices
|
||||||
min_dist = sys.float_info.max
|
min_dist = sys.float_info.max
|
||||||
|
@@ -179,7 +179,7 @@ class MeshSelectNext(Operator):
|
|||||||
|
|
||||||
|
|
||||||
class MeshSelectPrev(Operator):
|
class MeshSelectPrev(Operator):
|
||||||
"""Select the next element (using selection order)"""
|
"""Select the previous element (using selection order)"""
|
||||||
bl_idname = "mesh.select_prev_item"
|
bl_idname = "mesh.select_prev_item"
|
||||||
bl_label = "Select Previous Element"
|
bl_label = "Select Previous Element"
|
||||||
bl_options = {'REGISTER', 'UNDO'}
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
@@ -23,7 +23,7 @@ from bpy.types import Operator
|
|||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
|
|
||||||
|
|
||||||
def GlobalBB_LQ(bb_world):
|
def worldspace_bounds_from_object_bounds(bb_world):
|
||||||
|
|
||||||
# Initialize the variables with the 8th vertex
|
# Initialize the variables with the 8th vertex
|
||||||
left, right, front, back, down, up = (
|
left, right, front, back, down, up = (
|
||||||
@@ -65,29 +65,29 @@ def GlobalBB_LQ(bb_world):
|
|||||||
return (Vector((left, front, up)), Vector((right, back, down)))
|
return (Vector((left, front, up)), Vector((right, back, down)))
|
||||||
|
|
||||||
|
|
||||||
def GlobalBB_HQ(obj):
|
def worldspace_bounds_from_object_data(scene, obj):
|
||||||
|
|
||||||
matrix_world = obj.matrix_world.copy()
|
matrix_world = obj.matrix_world.copy()
|
||||||
|
|
||||||
# Initialize the variables with the last vertex
|
# Initialize the variables with the last vertex
|
||||||
|
|
||||||
me = obj.to_mesh(scene=bpy.context.scene, apply_modifiers=True, settings='PREVIEW')
|
me = obj.to_mesh(scene=scene, apply_modifiers=True, settings='PREVIEW')
|
||||||
verts = me.vertices
|
verts = me.vertices
|
||||||
|
|
||||||
val = matrix_world * verts[-1].co
|
val = matrix_world * (verts[-1].co if verts else Vector((0.0, 0.0, 0.0)))
|
||||||
|
|
||||||
left, right, front, back, down, up = (val[0],
|
left, right, front, back, down, up = (
|
||||||
val[0],
|
val[0],
|
||||||
val[1],
|
val[0],
|
||||||
val[1],
|
val[1],
|
||||||
val[2],
|
val[1],
|
||||||
val[2],
|
val[2],
|
||||||
)
|
val[2],
|
||||||
|
)
|
||||||
|
|
||||||
# Test against all other verts
|
# Test against all other verts
|
||||||
for i in range(len(verts) - 1):
|
for v in verts:
|
||||||
|
vco = matrix_world * v.co
|
||||||
vco = matrix_world * verts[i].co
|
|
||||||
|
|
||||||
# X Range
|
# X Range
|
||||||
val = vco[0]
|
val = vco[0]
|
||||||
@@ -131,6 +131,11 @@ def align_objects(context,
|
|||||||
|
|
||||||
cursor = (space if space and space.type == 'VIEW_3D' else scene).cursor_location
|
cursor = (space if space and space.type == 'VIEW_3D' else scene).cursor_location
|
||||||
|
|
||||||
|
# We are accessing runtime data such as evaluated bounding box, so we need to
|
||||||
|
# be sure it is properly updated and valid (bounding box might be lost on operator
|
||||||
|
# redo).
|
||||||
|
scene.update()
|
||||||
|
|
||||||
Left_Front_Up_SEL = [0.0, 0.0, 0.0]
|
Left_Front_Up_SEL = [0.0, 0.0, 0.0]
|
||||||
Right_Back_Down_SEL = [0.0, 0.0, 0.0]
|
Right_Back_Down_SEL = [0.0, 0.0, 0.0]
|
||||||
|
|
||||||
@@ -149,9 +154,9 @@ def align_objects(context,
|
|||||||
for obj, bb_world in objects:
|
for obj, bb_world in objects:
|
||||||
|
|
||||||
if bb_quality and obj.type == 'MESH':
|
if bb_quality and obj.type == 'MESH':
|
||||||
GBB = GlobalBB_HQ(obj)
|
GBB = worldspace_bounds_from_object_data(scene, obj)
|
||||||
else:
|
else:
|
||||||
GBB = GlobalBB_LQ(bb_world)
|
GBB = worldspace_bounds_from_object_bounds(bb_world)
|
||||||
|
|
||||||
Left_Front_Up = GBB[0]
|
Left_Front_Up = GBB[0]
|
||||||
Right_Back_Down = GBB[1]
|
Right_Back_Down = GBB[1]
|
||||||
@@ -213,9 +218,9 @@ def align_objects(context,
|
|||||||
bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
|
bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
|
||||||
|
|
||||||
if bb_quality and obj.type == 'MESH':
|
if bb_quality and obj.type == 'MESH':
|
||||||
GBB = GlobalBB_HQ(obj)
|
GBB = worldspace_bounds_from_object_data(scene, obj)
|
||||||
else:
|
else:
|
||||||
GBB = GlobalBB_LQ(bb_world)
|
GBB = worldspace_bounds_from_object_bounds(bb_world)
|
||||||
|
|
||||||
Left_Front_Up = GBB[0]
|
Left_Front_Up = GBB[0]
|
||||||
Right_Back_Down = GBB[1]
|
Right_Back_Down = GBB[1]
|
||||||
|
@@ -65,8 +65,10 @@ class AddPresetBase:
|
|||||||
setattr(cls, attr, trans)
|
setattr(cls, attr, trans)
|
||||||
return trans
|
return trans
|
||||||
|
|
||||||
|
name = name.lower().strip()
|
||||||
|
name = bpy.path.display_name_to_filepath(name)
|
||||||
trans = maketrans_init()
|
trans = maketrans_init()
|
||||||
return name.lower().strip().translate(trans)
|
return name.translate(trans)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
import os
|
import os
|
||||||
@@ -702,4 +704,4 @@ classes = (
|
|||||||
AddPresetUnitsLength,
|
AddPresetUnitsLength,
|
||||||
ExecutePreset,
|
ExecutePreset,
|
||||||
WM_MT_operator_presets,
|
WM_MT_operator_presets,
|
||||||
)
|
)
|
||||||
|
@@ -1067,6 +1067,7 @@ class SmartProject(Operator):
|
|||||||
island_margin = FloatProperty(
|
island_margin = FloatProperty(
|
||||||
name="Island Margin",
|
name="Island Margin",
|
||||||
description="Margin to reduce bleed from adjacent islands",
|
description="Margin to reduce bleed from adjacent islands",
|
||||||
|
unit='LENGTH', subtype='DISTANCE',
|
||||||
min=0.0, max=1.0,
|
min=0.0, max=1.0,
|
||||||
default=0.0,
|
default=0.0,
|
||||||
)
|
)
|
||||||
|
@@ -985,9 +985,12 @@ class WM_OT_doc_view_manual(Operator):
|
|||||||
def _find_reference(rna_id, url_mapping, verbose=True):
|
def _find_reference(rna_id, url_mapping, verbose=True):
|
||||||
if verbose:
|
if verbose:
|
||||||
print("online manual check for: '%s'... " % rna_id)
|
print("online manual check for: '%s'... " % rna_id)
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatchcase
|
||||||
|
# XXX, for some reason all RNA ID's are stored lowercase
|
||||||
|
# Adding case into all ID's isn't worth the hassle so force lowercase.
|
||||||
|
rna_id = rna_id.lower()
|
||||||
for pattern, url_suffix in url_mapping:
|
for pattern, url_suffix in url_mapping:
|
||||||
if fnmatch(rna_id, pattern):
|
if fnmatchcase(rna_id, pattern):
|
||||||
if verbose:
|
if verbose:
|
||||||
print(" match found: '%s' --> '%s'" % (pattern, url_suffix))
|
print(" match found: '%s' --> '%s'" % (pattern, url_suffix))
|
||||||
return url_suffix
|
return url_suffix
|
||||||
@@ -2212,7 +2215,7 @@ class WM_OT_addon_userpref_show(Operator):
|
|||||||
info = addon_utils.module_bl_info(mod)
|
info = addon_utils.module_bl_info(mod)
|
||||||
info["show_expanded"] = True
|
info["show_expanded"] = True
|
||||||
|
|
||||||
bpy.context.user_preferences.active_section = 'ADDONS'
|
context.user_preferences.active_section = 'ADDONS'
|
||||||
context.window_manager.addon_filter = 'All'
|
context.window_manager.addon_filter = 'All'
|
||||||
context.window_manager.addon_search = info["name"]
|
context.window_manager.addon_search = info["name"]
|
||||||
bpy.ops.screen.userpref_show('INVOKE_DEFAULT')
|
bpy.ops.screen.userpref_show('INVOKE_DEFAULT')
|
||||||
|
@@ -206,7 +206,8 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
|
|||||||
|
|
||||||
col = row.column(align=True)
|
col = row.column(align=True)
|
||||||
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
|
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
|
||||||
col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="").all = False
|
props = col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="")
|
||||||
|
props.all_unlocked = props.all = False
|
||||||
col.menu("MESH_MT_vertex_group_specials", icon='DOWNARROW_HLT', text="")
|
col.menu("MESH_MT_vertex_group_specials", icon='DOWNARROW_HLT', text="")
|
||||||
if group:
|
if group:
|
||||||
col.separator()
|
col.separator()
|
||||||
|
@@ -146,9 +146,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||||||
layout.row().prop(md, "offset_type", expand=True)
|
layout.row().prop(md, "offset_type", expand=True)
|
||||||
|
|
||||||
def BOOLEAN(self, layout, ob, md):
|
def BOOLEAN(self, layout, ob, md):
|
||||||
|
solver = md.solver
|
||||||
if not bpy.app.build_options.mod_boolean:
|
if not bpy.app.build_options.mod_boolean:
|
||||||
layout.label("Built without Boolean modifier")
|
if solver == 'CARVE':
|
||||||
return
|
layout.label("Built without Carve solver")
|
||||||
|
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
@@ -164,9 +165,13 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||||||
split.column().label(text="Solver:")
|
split.column().label(text="Solver:")
|
||||||
split.column().prop(md, "solver", text="")
|
split.column().prop(md, "solver", text="")
|
||||||
|
|
||||||
if md.solver == 'BMESH':
|
if solver == 'BMESH':
|
||||||
layout.prop(md, "double_threshold")
|
layout.prop(md, "double_threshold")
|
||||||
|
|
||||||
|
if bpy.app.debug:
|
||||||
|
layout.prop(md, "debug_options")
|
||||||
|
|
||||||
|
|
||||||
def BUILD(self, layout, ob, md):
|
def BUILD(self, layout, ob, md):
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
@@ -747,6 +752,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||||||
col.prop(md, "steps")
|
col.prop(md, "steps")
|
||||||
col.prop(md, "render_steps")
|
col.prop(md, "render_steps")
|
||||||
col.prop(md, "use_smooth_shade")
|
col.prop(md, "use_smooth_shade")
|
||||||
|
col.prop(md, "use_merge_vertices")
|
||||||
|
sub = col.column()
|
||||||
|
sub.active = md.use_merge_vertices
|
||||||
|
sub.prop(md, "merge_threshold")
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
row = col.row()
|
row = col.row()
|
||||||
@@ -910,12 +919,13 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||||||
row.prop(md, "material_offset_rim", text="Rim")
|
row.prop(md, "material_offset_rim", text="Rim")
|
||||||
|
|
||||||
def SUBSURF(self, layout, ob, md):
|
def SUBSURF(self, layout, ob, md):
|
||||||
|
from bpy import context
|
||||||
layout.row().prop(md, "subdivision_type", expand=True)
|
layout.row().prop(md, "subdivision_type", expand=True)
|
||||||
|
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
col = split.column()
|
col = split.column()
|
||||||
|
|
||||||
scene = bpy.context.scene
|
scene = context.scene
|
||||||
engine = scene.render.engine
|
engine = scene.render.engine
|
||||||
show_adaptive_options = (engine == "CYCLES" and md == ob.modifiers[-1] and
|
show_adaptive_options = (engine == "CYCLES" and md == ob.modifiers[-1] and
|
||||||
scene.cycles.feature_set == "EXPERIMENTAL")
|
scene.cycles.feature_set == "EXPERIMENTAL")
|
||||||
|
@@ -581,10 +581,6 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
|
|||||||
layout.row().prop(part, "physics_type", expand=True)
|
layout.row().prop(part, "physics_type", expand=True)
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
col = row.column(align=True)
|
|
||||||
col.prop(part, "particle_size")
|
|
||||||
col.prop(part, "size_random", slider=True)
|
|
||||||
|
|
||||||
if part.physics_type != 'NO':
|
if part.physics_type != 'NO':
|
||||||
col = row.column(align=True)
|
col = row.column(align=True)
|
||||||
col.prop(part, "mass")
|
col.prop(part, "mass")
|
||||||
@@ -1089,7 +1085,8 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
|
|||||||
col = row.column()
|
col = row.column()
|
||||||
col.label(text="")
|
col.label(text="")
|
||||||
|
|
||||||
if part.render_type in {'OBJECT', 'GROUP'} and not part.use_advanced_hair:
|
if part.type == 'EMITTER' or \
|
||||||
|
(part.render_type in {'OBJECT', 'GROUP'} and part.type == 'HAIR' and not part.use_advanced_hair):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(part, "particle_size")
|
row.prop(part, "particle_size")
|
||||||
row.prop(part, "size_random", slider=True)
|
row.prop(part, "size_random", slider=True)
|
||||||
|
@@ -79,7 +79,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
|
|||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
|
|
||||||
if obj.type in {'MESH', 'LATTICE', 'CURVE'}:
|
if obj.type in {'MESH', 'LATTICE', 'CURVE', 'SURFACE', 'FONT'}:
|
||||||
physics_add(self, col, context.soft_body, "Soft Body", 'SOFT_BODY', 'MOD_SOFT', True)
|
physics_add(self, col, context.soft_body, "Soft Body", 'SOFT_BODY', 'MOD_SOFT', True)
|
||||||
|
|
||||||
if obj.type == 'MESH':
|
if obj.type == 'MESH':
|
||||||
|
@@ -26,6 +26,9 @@ from bl_ui.properties_physics_common import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
COMPAT_OB_TYPES = {'MESH', 'LATTICE', 'CURVE', 'SURFACE', 'FONT'}
|
||||||
|
|
||||||
|
|
||||||
def softbody_panel_enabled(md):
|
def softbody_panel_enabled(md):
|
||||||
return (md.point_cache.is_baked is False)
|
return (md.point_cache.is_baked is False)
|
||||||
|
|
||||||
@@ -39,7 +42,7 @@ class PhysicButtonsPanel:
|
|||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
ob = context.object
|
ob = context.object
|
||||||
rd = context.scene.render
|
rd = context.scene.render
|
||||||
return (ob and (ob.type == 'MESH' or ob.type == 'LATTICE'or ob.type == 'CURVE')) and (rd.engine in cls.COMPAT_ENGINES) and (context.soft_body)
|
return ob and ob.type in COMPAT_OB_TYPES and rd.engine in cls.COMPAT_ENGINES and context.soft_body
|
||||||
|
|
||||||
|
|
||||||
class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel):
|
class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel):
|
||||||
|
@@ -470,6 +470,7 @@ class CLIP_PT_tools_cleanup(CLIP_PT_tracking_panel, Panel):
|
|||||||
layout.prop(settings, "clean_frames", text="Frames")
|
layout.prop(settings, "clean_frames", text="Frames")
|
||||||
layout.prop(settings, "clean_error", text="Error")
|
layout.prop(settings, "clean_error", text="Error")
|
||||||
layout.prop(settings, "clean_action", text="")
|
layout.prop(settings, "clean_action", text="")
|
||||||
|
layout.separator()
|
||||||
layout.operator("clip.filter_tracks")
|
layout.operator("clip.filter_tracks")
|
||||||
|
|
||||||
|
|
||||||
|
@@ -552,6 +552,7 @@ from bl_ui.properties_mask_common import (
|
|||||||
MASK_PT_point,
|
MASK_PT_point,
|
||||||
MASK_PT_display,
|
MASK_PT_display,
|
||||||
MASK_PT_tools,
|
MASK_PT_tools,
|
||||||
|
MASK_PT_add,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -580,6 +581,20 @@ class IMAGE_PT_active_mask_point(MASK_PT_point, Panel):
|
|||||||
bl_region_type = 'UI'
|
bl_region_type = 'UI'
|
||||||
|
|
||||||
|
|
||||||
|
class IMAGE_PT_tools_mask(MASK_PT_tools, Panel):
|
||||||
|
bl_space_type = 'IMAGE_EDITOR'
|
||||||
|
bl_region_type = 'TOOLS'
|
||||||
|
bl_category = 'Mask'
|
||||||
|
|
||||||
|
class IMAGE_PT_tools_mask_add(MASK_PT_add, Panel):
|
||||||
|
bl_space_type = 'IMAGE_EDITOR'
|
||||||
|
bl_region_type = 'TOOLS'
|
||||||
|
bl_category = 'Mask'
|
||||||
|
|
||||||
|
|
||||||
|
# --- end mask ---
|
||||||
|
|
||||||
|
|
||||||
class IMAGE_PT_image_properties(Panel):
|
class IMAGE_PT_image_properties(Panel):
|
||||||
bl_space_type = 'IMAGE_EDITOR'
|
bl_space_type = 'IMAGE_EDITOR'
|
||||||
bl_region_type = 'UI'
|
bl_region_type = 'UI'
|
||||||
@@ -1158,12 +1173,6 @@ class IMAGE_UV_sculpt(Panel, ImagePaintPanel):
|
|||||||
col.prop(uvsculpt, "show_brush")
|
col.prop(uvsculpt, "show_brush")
|
||||||
|
|
||||||
|
|
||||||
class IMAGE_PT_tools_mask(MASK_PT_tools, Panel):
|
|
||||||
bl_space_type = 'IMAGE_EDITOR'
|
|
||||||
bl_region_type = 'TOOLS'
|
|
||||||
bl_category = 'Mask'
|
|
||||||
|
|
||||||
# --- end mask ---
|
|
||||||
|
|
||||||
|
|
||||||
class IMAGE_PT_options_uvs(Panel, UVToolsPanel):
|
class IMAGE_PT_options_uvs(Panel, UVToolsPanel):
|
||||||
@@ -1348,6 +1357,7 @@ classes = (
|
|||||||
IMAGE_HT_header,
|
IMAGE_HT_header,
|
||||||
MASK_MT_editor_menus,
|
MASK_MT_editor_menus,
|
||||||
IMAGE_PT_mask,
|
IMAGE_PT_mask,
|
||||||
|
IMAGE_PT_tools_mask_add,
|
||||||
IMAGE_PT_mask_layers,
|
IMAGE_PT_mask_layers,
|
||||||
IMAGE_PT_mask_display,
|
IMAGE_PT_mask_display,
|
||||||
IMAGE_PT_active_mask_spline,
|
IMAGE_PT_active_mask_spline,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user