Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2021-08-05 20:10:57 +02:00
commit b991a92aab
358 changed files with 11599 additions and 2277 deletions

View File

@ -110,6 +110,10 @@ if(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
endif()
# Install CODE|SCRIPT allow the use of generator expressions.
if(POLICY CMP0087)
cmake_policy(SET CMP0087 NEW)
endif()
#-----------------------------------------------------------------------------
# Load some macros.
include(build_files/cmake/macros.cmake)
@ -424,6 +428,10 @@ mark_as_advanced(WITH_CYCLES_NETWORK)
option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime" ON)
mark_as_advanced(WITH_CUDA_DYNLOAD)
# Draw Manager
option(WITH_DRAW_DEBUG "Add extra debug capabilities to Draw Manager" OFF)
mark_as_advanced(WITH_DRAW_DEBUG)
# LLVM
option(WITH_LLVM "Use LLVM" OFF)
if(APPLE)

View File

@ -63,7 +63,7 @@ Package Targets
* package_debian: Build a debian package.
* package_pacman: Build an arch linux pacman package.
* package_archive: Build an archive package.
* package_archive: Build an archive package.
Testing Targets
Not associated with building Blender.
@ -167,7 +167,7 @@ endef
# This makefile is not meant for Windows
ifeq ($(OS),Windows_NT)
$(error On Windows, use "cmd //c make.bat" instead of "make")
$(error On Windows, use "cmd //c make.bat" instead of "make")
endif
# System Vars
@ -379,7 +379,7 @@ deps: .FORCE
@cmake -H"$(DEPS_SOURCE_DIR)" \
-B"$(DEPS_BUILD_DIR)" \
-DHARVEST_TARGET=$(DEPS_INSTALL_DIR)
-DHARVEST_TARGET=$(DEPS_INSTALL_DIR)
@echo
@echo Building dependencies ...
@ -456,7 +456,8 @@ project_eclipse: .FORCE
check_cppcheck: .FORCE
$(CMAKE_CONFIG)
cd "$(BUILD_DIR)" ; \
$(PYTHON) "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py" 2> \
$(PYTHON) \
"$(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py" 2> \
"$(BLENDER_DIR)/check_cppcheck.txt"
@echo "written: check_cppcheck.txt"
@ -518,8 +519,9 @@ source_archive: .FORCE
python3 ./build_files/utils/make_source_archive.py
source_archive_complete: .FORCE
cmake -S "$(BLENDER_DIR)/build_files/build_environment" -B"$(BUILD_DIR)/source_archive" \
-DCMAKE_BUILD_TYPE_INIT:STRING=$(BUILD_TYPE) -DPACKAGE_USE_UPSTREAM_SOURCES=OFF
cmake \
-S "$(BLENDER_DIR)/build_files/build_environment" -B"$(BUILD_DIR)/source_archive" \
-DCMAKE_BUILD_TYPE_INIT:STRING=$(BUILD_TYPE) -DPACKAGE_USE_UPSTREAM_SOURCES=OFF
# This assumes CMake is still using a default `PACKAGE_DIR` variable:
python3 ./build_files/utils/make_source_archive.py --include-packages "$(BUILD_DIR)/source_archive/packages"
@ -527,9 +529,11 @@ source_archive_complete: .FORCE
INKSCAPE_BIN?="inkscape"
icons: .FORCE
BLENDER_BIN=$(BLENDER_BIN) INKSCAPE_BIN=$(INKSCAPE_BIN) \
"$(BLENDER_DIR)/release/datafiles/blender_icons_update.py"
BLENDER_BIN=$(BLENDER_BIN) INKSCAPE_BIN=$(INKSCAPE_BIN) \
"$(BLENDER_DIR)/release/datafiles/prvicons_update.py"
"$(BLENDER_DIR)/release/datafiles/blender_icons_update.py"
INKSCAPE_BIN=$(INKSCAPE_BIN) \
"$(BLENDER_DIR)/release/datafiles/prvicons_update.py"
INKSCAPE_BIN=$(INKSCAPE_BIN) \
"$(BLENDER_DIR)/release/datafiles/alert_icons_update.py"
icons_geom: .FORCE
BLENDER_BIN=$(BLENDER_BIN) \
@ -543,7 +547,7 @@ update_code: .FORCE
format: .FORCE
PATH="../lib/${OS_NCASE}_${CPU}/llvm/bin/:../lib/${OS_NCASE}_centos7_${CPU}/llvm/bin/:../lib/${OS_NCASE}/llvm/bin/:$(PATH)" \
$(PYTHON) source/tools/utils_maintenance/clang_format_paths.py $(PATHS)
$(PYTHON) source/tools/utils_maintenance/clang_format_paths.py $(PATHS)
# -----------------------------------------------------------------------------
@ -553,8 +557,9 @@ format: .FORCE
# Simple version of ./doc/python_api/sphinx_doc_gen.sh with no PDF generation.
doc_py: .FORCE
ASAN_OPTIONS=halt_on_error=0:${ASAN_OPTIONS} \
$(BLENDER_BIN) --background -noaudio --factory-startup \
--python doc/python_api/sphinx_doc_gen.py
$(BLENDER_BIN) \
--background -noaudio --factory-startup \
--python doc/python_api/sphinx_doc_gen.py
sphinx-build -b html -j $(NPROCS) doc/python_api/sphinx-in doc/python_api/sphinx-out
@echo "docs written into: '$(BLENDER_DIR)/doc/python_api/sphinx-out/index.html'"
@ -563,8 +568,9 @@ doc_doxy: .FORCE
@echo "docs written into: '$(BLENDER_DIR)/doc/doxygen/html/index.html'"
doc_dna: .FORCE
$(BLENDER_BIN) --background -noaudio --factory-startup \
--python doc/blender_file_format/BlendFileDnaExporter_25.py
$(BLENDER_BIN) \
--background -noaudio --factory-startup \
--python doc/blender_file_format/BlendFileDnaExporter_25.py
@echo "docs written into: '$(BLENDER_DIR)/doc/blender_file_format/dna.html'"
doc_man: .FORCE

View File

@ -1447,9 +1447,7 @@ compile_Python() {
make -j$THREADS && make install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "Python--$PYTHON_VERSION failed to compile, exiting"
exit 1
fi
@ -1465,6 +1463,9 @@ compile_Python() {
INFO "If you want to force rebuild of this lib, use the --force-python option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "python-$PYTHON_VERSION_SHORT"
# Extra step: install required modules with pip.
@ -1558,9 +1559,7 @@ compile_Boost() {
--prefix=$_inst --disable-icu boost.locale.icu=off install
./b2 --clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "Boost-$BOOST_VERSION failed to compile, exiting"
exit 1
fi
@ -1574,7 +1573,9 @@ compile_Boost() {
INFO "If you want to force rebuild of this lib, use the --force-boost option."
fi
# Just always run it, much simpler this way!
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "boost"
}
@ -1687,9 +1688,7 @@ compile_TBB() {
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "TBB-$TBB_VERSION$TBB_VERSION_UPDATE failed to compile, exiting"
exit 1
fi
@ -1703,6 +1702,9 @@ compile_TBB() {
INFO "If you want to force rebuild of this lib, use the --force-tbb option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "tbb"
}
@ -1822,9 +1824,7 @@ compile_OCIO() {
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "OpenColorIO-$OCIO_VERSION failed to compile, exiting"
exit 1
fi
@ -1838,6 +1838,9 @@ compile_OCIO() {
INFO "If you want to force rebuild of this lib, use the --force-ocio option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "ocio"
}
@ -1953,9 +1956,7 @@ compile_OPENEXR() {
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "OpenEXR-$OPENEXR_VERSION failed to compile, exiting"
exit 1
fi
@ -1971,7 +1972,9 @@ compile_OPENEXR() {
_with_built_openexr=true
# Just always run it, much simpler this way!
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "openexr"
}
@ -2112,9 +2115,7 @@ compile_OIIO() {
make -j$THREADS && make install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "OpenImageIO-$OIIO_VERSION failed to compile, exiting"
exit 1
fi
@ -2128,7 +2129,9 @@ compile_OIIO() {
INFO "If you want to force rebuild of this lib, use the --force-oiio option."
fi
# Just always run it, much simpler this way!
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "oiio"
}
@ -2237,9 +2240,7 @@ compile_LLVM() {
make -j$THREADS && make install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "LLVM-$LLVM_VERSION failed to compile, exiting"
exit 1
fi
@ -2252,6 +2253,10 @@ compile_LLVM() {
INFO "Own LLVM-$LLVM_VERSION (CLANG included) is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-llvm option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
}
# ----------------------------------------------------------------------------
@ -2390,9 +2395,7 @@ compile_OSL() {
make -j$THREADS && make install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "OpenShadingLanguage-$OSL_VERSION failed to compile, exiting"
exit 1
fi
@ -2406,6 +2409,9 @@ compile_OSL() {
INFO "If you want to force rebuild of this lib, use the --force-osl option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "osl"
}
@ -2506,9 +2512,7 @@ compile_OSD() {
make -j$THREADS && make install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "OpenSubdiv-$OSD_VERSION failed to compile, exiting"
exit 1
fi
@ -2522,6 +2526,9 @@ compile_OSD() {
INFO "If you want to force rebuild of this lib, use the --force-osd option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "osd"
}
@ -2611,9 +2618,7 @@ compile_BLOSC() {
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "Blosc-$OPENVDB_BLOSC_VERSION failed to compile, exiting"
exit 1
fi
@ -2626,6 +2631,9 @@ compile_BLOSC() {
magic_compile_set blosc-$OPENVDB_BLOSC_VERSION $blosc_magic
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "blosc"
}
@ -2716,9 +2724,7 @@ install_NanoVDB() {
#~ mkdir -p $_inst
#~ cp -r $_src/include $_inst/include
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "NanoVDB-v$OPENVDB_VERSION failed to install, exiting"
exit 1
fi
@ -2730,6 +2736,10 @@ install_NanoVDB() {
else
INFO "Own NanoVDB-v$OPENVDB_VERSION is up to date, nothing to do!"
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
}
@ -2849,9 +2859,7 @@ compile_OPENVDB() {
make -j$THREADS install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "OpenVDB-$OPENVDB_VERSION failed to compile, exiting"
exit 1
fi
@ -2865,6 +2873,9 @@ compile_OPENVDB() {
INFO "If you want to force rebuild of this lib, use the --force-openvdb option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "openvdb"
if [ "$WITH_NANOVDB" = true ]; then
@ -2962,9 +2973,7 @@ compile_ALEMBIC() {
make -j$THREADS install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "Alembic-$ALEMBIC_VERSION failed to compile, exiting"
exit 1
fi
@ -2978,6 +2987,9 @@ compile_ALEMBIC() {
INFO "If you want to force rebuild of this lib, use the --force-alembic option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "alembic"
}
@ -3062,9 +3074,7 @@ compile_USD() {
make -j$THREADS install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "USD-$USD_VERSION failed to compile, exiting"
exit 1
fi
@ -3078,6 +3088,9 @@ compile_USD() {
INFO "If you want to force rebuild of this lib, use the --force-usd option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "usd"
}
@ -3171,9 +3184,7 @@ compile_OpenCOLLADA() {
make -j$THREADS && make install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "OpenCOLLADA-$OPENCOLLADA_VERSION failed to compile, exiting"
exit 1
fi
@ -3186,6 +3197,10 @@ compile_OpenCOLLADA() {
INFO "Own OpenCOLLADA-$OPENCOLLADA_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-opencollada option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
}
# ----------------------------------------------------------------------------
@ -3286,9 +3301,7 @@ compile_Embree() {
make -j$THREADS && make install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "Embree-$EMBREE_VERSION failed to compile, exiting"
exit 1
fi
@ -3301,6 +3314,10 @@ compile_Embree() {
INFO "Own Embree-$EMBREE_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-embree option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
}
# ----------------------------------------------------------------------------
@ -3363,9 +3380,7 @@ install_ISPC() {
mkdir -p $_inst
cp -r $_src/bin $_inst/bin
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "ISPC-v$ISPC_VERSION failed to install, exiting"
exit 1
fi
@ -3378,6 +3393,10 @@ install_ISPC() {
INFO "Own ISPC-v$ISPC_VERSION is up to date, nothing to do!"
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
_ispc_path_bin=$_inst/bin
run_ldconfig "ispc"
}
@ -3477,9 +3496,7 @@ compile_OIDN() {
make -j$THREADS && make install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "OpenImageDenoise-$OIDN_VERSION failed to compile, exiting"
exit 1
fi
@ -3493,6 +3510,9 @@ compile_OIDN() {
INFO "If you want to force rebuild of this lib, use the --force-oidn option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "oidn"
}
@ -3609,9 +3629,7 @@ compile_FFmpeg() {
make -j$THREADS && make install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "FFmpeg-$FFMPEG_VERSION failed to compile, exiting"
exit 1
fi
@ -3624,6 +3642,10 @@ compile_FFmpeg() {
INFO "Own ffmpeg-$FFMPEG_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-ffmpeg option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
}
# ----------------------------------------------------------------------------
@ -3722,9 +3744,7 @@ compile_XR_OpenXR_SDK() {
make -j$THREADS && make install
make clean
if [ -d $_inst ]; then
_create_inst_shortcut
else
if [ ! -d $_inst ]; then
ERROR "XR-OpenXR-SDK-$XR_OPENXR_VERSION failed to compile, exiting"
exit 1
fi
@ -3738,6 +3758,9 @@ compile_XR_OpenXR_SDK() {
INFO "If you want to force rebuild of this lib, use the --force-xr-openxr option."
fi
if [ -d $_inst ]; then
_create_inst_shortcut
fi
run_ldconfig "xr-openxr-sdk"
}

View File

@ -411,25 +411,9 @@ if(WITH_OPENMP)
set(OPENMP_FOUND ON)
set(OpenMP_C_FLAGS "-Xclang -fopenmp -I'${LIBDIR}/openmp/include'")
set(OpenMP_CXX_FLAGS "-Xclang -fopenmp -I'${LIBDIR}/openmp/include'")
set(OpenMP_LINKER_FLAGS "-L'${LIBDIR}/openmp/lib' -lomp")
# Copy libomp.dylib to allow executables like datatoc and tests to work.
# `@executable_path/../Resources/lib/` `LC_ID_DYLIB` is added by the deps builder.
# For single config generator datatoc, tests etc.
execute_process(
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/Resources/lib
COMMAND cp -p ${LIBDIR}/openmp/lib/libomp.dylib ${CMAKE_BINARY_DIR}/Resources/lib/libomp.dylib
)
# For multi-config generator datatoc, etc.
execute_process(
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/bin/Resources/lib
COMMAND cp -p ${LIBDIR}/openmp/lib/libomp.dylib ${CMAKE_BINARY_DIR}/bin/Resources/lib/libomp.dylib
)
# For multi-config generator tests.
execute_process(
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/bin/tests/Resources/lib
COMMAND cp -p ${LIBDIR}/openmp/lib/libomp.dylib ${CMAKE_BINARY_DIR}/bin/tests/Resources/lib/libomp.dylib
)
set(OpenMP_LIBRARY_DIR "${LIBDIR}/openmp/lib/")
set(OpenMP_LINKER_FLAGS "-L'${OpenMP_LIBRARY_DIR}' -lomp")
set(OpenMP_LIBRARY "${OpenMP_LIBRARY_DIR}/libomp.dylib")
endif()
endif()
@ -511,3 +495,22 @@ if(WITH_COMPILER_CCACHE)
endif()
endif()
endif()
# For binaries that are built but not installed (also not distributed) (datatoc,
# makesdna, tests, etc.), we add an rpath to the OpenMP library dir through
# CMAKE_BUILD_RPATH. This avoids having to make many copies of the dylib next to each binary.
#
# For the installed Blender executable, CMAKE_INSTALL_RPATH will be used
# to locate the dylibs at @executable_path, next to the Blender executable.
#
# For the installed Python module, CMAKE_INSTALL_RPATH is modified to find the
# dylib in an adjacent folder.
set(CMAKE_SKIP_BUILD_RPATH FALSE)
list(APPEND CMAKE_BUILD_RPATH "${OpenMP_LIBRARY_DIR}")
set(CMAKE_SKIP_INSTALL_RPATH FALSE)
list(APPEND CMAKE_INSTALL_RPATH "@executable_path")
if(WITH_PYTHON_MODULE)
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/../Resources/${BLENDER_VERSION}/lib")
endif()

View File

@ -217,8 +217,8 @@ else()
endif()
if(WITH_WINDOWS_PDB)
set(PDB_INFO_OVERRIDE_FLAGS "${SYMBOL_FORMAT_RELEASE}")
set(PDB_INFO_OVERRIDE_LINKER_FLAGS "/DEBUG /OPT:REF /OPT:ICF /INCREMENTAL:NO")
set(PDB_INFO_OVERRIDE_FLAGS "${SYMBOL_FORMAT_RELEASE}")
set(PDB_INFO_OVERRIDE_LINKER_FLAGS "/DEBUG /OPT:REF /OPT:ICF /INCREMENTAL:NO")
endif()
string(APPEND CMAKE_CXX_FLAGS_DEBUG " /MDd ${SYMBOL_FORMAT}")

View File

@ -0,0 +1,28 @@
REM First see if there is an environment variable set
if EXIST "%BLENDER_BIN%" (
goto detect_blender_done
)
REM Check the build folder next, if ninja was used there will be no
REM debug/release folder
set BLENDER_BIN=%BUILD_DIR%\bin\blender.exe
if EXIST "%BLENDER_BIN%" (
goto detect_blender_done
)
REM Check the release folder next
set BLENDER_BIN=%BUILD_DIR%\bin\release\blender.exe
if EXIST "%BLENDER_BIN%" (
goto detect_blender_done
)
REM Check the debug folder next
set BLENDER_BIN=%BUILD_DIR%\bin\debug\blender.exe
if EXIST "%BLENDER_BIN%" (
goto detect_blender_done
)
REM at this point, we don't know where blender is, clear the variable
set BLENDER_BIN=
:detect_blender_done

View File

@ -0,0 +1,21 @@
REM First see if there is an environment variable set
if EXIST "%INKSCAPE_BIN%" (
goto detect_inkscape_done
)
REM Then see if inkscape is available in the path
for %%X in (inkscape.exe) do (set INKSCAPE_BIN=%%~$PATH:X)
if EXIST "%INKSCAPE_BIN%" (
goto detect_inkscape_done
)
REM Finally see if it is perhaps installed at the default location
set INKSCAPE_BIN=%ProgramFiles%\Inkscape\bin\inkscape.exe
if EXIST "%INKSCAPE_BIN%" (
goto detect_inkscape_done
)
REM If still not found clear the variable
set INKSCAPE_BIN=
:detect_inkscape_done

View File

@ -0,0 +1,42 @@
if EXIST %PYTHON% (
goto detect_python_done
)
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
echo python not found at %PYTHON%
exit /b 1
:detect_python_done
echo found python (%PYTHON%)
call "%~dp0\find_inkscape.cmd"
if EXIST "%INKSCAPE_BIN%" (
goto detect_inkscape_done
)
echo unable to locate inkscape, run "set inkscape_BIN=full_path_to_inkscape.exe"
exit /b 1
:detect_inkscape_done
call "%~dp0\find_blender.cmd"
if EXIST "%BLENDER_BIN%" (
goto detect_blender_done
)
echo unable to locate blender, run "set BLENDER_BIN=full_path_to_blender.exe"
exit /b 1
:detect_blender_done
%PYTHON% -B %BLENDER_DIR%\release\datafiles\blender_icons_update.py
%PYTHON% -B %BLENDER_DIR%\release\datafiles\prvicons_update.py
%PYTHON% -B %BLENDER_DIR%\release\datafiles\alert_icons_update.py
:EOF

View File

@ -0,0 +1,29 @@
if EXIST %PYTHON% (
goto detect_python_done
)
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
echo python not found at %PYTHON%
exit /b 1
:detect_python_done
echo found python (%PYTHON%)
call "%~dp0\find_blender.cmd"
if EXIST "%BLENDER_BIN%" (
goto detect_blender_done
)
echo unable to locate blender, run "set BLENDER_BIN=full_path_to_blender.exe"
exit /b 1
:detect_blender_done
%PYTHON% -B %BLENDER_DIR%\release\datafiles\blender_icons_geom_update.py
:EOF

View File

@ -107,6 +107,12 @@ if NOT "%1" == "" (
set FORMAT=1
set FORMAT_ARGS=%2 %3 %4 %5 %6 %7 %8 %9
goto EOF
) else if "%1" == "icons" (
set ICONS=1
goto EOF
) else if "%1" == "icons_geom" (
set ICONS_GEOM=1
goto EOF
) else (
echo Command "%1" unknown, aborting!
goto ERR

View File

@ -31,3 +31,5 @@ set PYDEBUG_CMAKE_ARGS=
set FORMAT=
set TEST=
set BUILD_WITH_SCCACHE=
set ICONS=
set ICONS_GEOM=

View File

@ -31,7 +31,8 @@ def draw():
context.space_data,
context.region,
view_matrix,
projection_matrix)
projection_matrix,
True)
gpu.state.depth_mask_set(False)
draw_texture_2d(offscreen.texture_color, (10, 10), WIDTH, HEIGHT)

View File

@ -111,5 +111,5 @@ if(WITH_MOD_FLUID)
endif()
if (WITH_COMPOSITOR)
add_subdirectory(smaa_areatex)
add_subdirectory(smaa_areatex)
endif()

View File

@ -1164,12 +1164,6 @@ class CyclesVisibilitySettings(bpy.types.PropertyGroup):
@classmethod
def register(cls):
bpy.types.Object.cycles_visibility = PointerProperty(
name="Cycles Visibility Settings",
description="Cycles visibility settings",
type=cls,
)
bpy.types.World.cycles_visibility = PointerProperty(
name="Cycles Visibility Settings",
description="Cycles visibility settings",
@ -1178,7 +1172,6 @@ class CyclesVisibilitySettings(bpy.types.PropertyGroup):
@classmethod
def unregister(cls):
del bpy.types.Object.cycles_visibility
del bpy.types.World.cycles_visibility
@ -1268,18 +1261,12 @@ class CyclesObjectSettings(bpy.types.PropertyGroup):
default=0.1,
)
is_shadow_catcher: BoolProperty(
name="Shadow Catcher",
description="Only render shadows on this object, for compositing renders into real footage",
default=False,
)
is_holdout: BoolProperty(
name="Holdout",
description="Render objects as a holdout or matte, creating a "
"hole in the image with zero alpha, to fill out in "
"compositing with real footage or another render",
default=False,
ao_distance: FloatProperty(
name="AO Distance",
description="AO distance used for approximate global illumination (0 means use world setting)",
min=0.0,
default=0.0,
subtype='DISTANCE',
)
@classmethod

View File

@ -1102,7 +1102,7 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
if ob:
is_sortable = len(ob.material_slots) > 1
rows = 1
rows = 3
if (is_sortable):
rows = 4
@ -1228,6 +1228,26 @@ class CYCLES_OBJECT_PT_shading_shadow_terminator(CyclesButtonsPanel, Panel):
flow.prop(cob, "shadow_terminator_offset", text="Shading Offset")
class CYCLES_OBJECT_PT_shading_gi_approximation(CyclesButtonsPanel, Panel):
bl_label = "Fast GI Approximation"
bl_parent_id = "CYCLES_OBJECT_PT_shading"
bl_context = "object"
def draw(self, context):
layout = self.layout
layout.use_property_split = True
scene = context.scene
ob = context.object
cob = ob.cycles
cscene = scene.cycles
col = layout.column()
col.active = cscene.use_fast_gi
col.prop(cob, "ao_distance")
class CYCLES_OBJECT_PT_visibility(CyclesButtonsPanel, Panel):
bl_label = "Visibility"
bl_context = "object"
@ -1250,10 +1270,9 @@ class CYCLES_OBJECT_PT_visibility(CyclesButtonsPanel, Panel):
col.prop(ob, "hide_render", text="Renders", invert_checkbox=True, toggle=False)
if has_geometry_visibility(ob):
cob = ob.cycles
col = layout.column(heading="Mask")
col.prop(cob, "is_shadow_catcher")
col.prop(cob, "is_holdout")
col.prop(ob, "is_shadow_catcher")
col.prop(ob, "is_holdout")
class CYCLES_OBJECT_PT_visibility_ray_visibility(CyclesButtonsPanel, Panel):
@ -1273,19 +1292,17 @@ class CYCLES_OBJECT_PT_visibility_ray_visibility(CyclesButtonsPanel, Panel):
scene = context.scene
ob = context.object
cob = ob.cycles
visibility = ob.cycles_visibility
col = layout.column()
col.prop(visibility, "camera")
col.prop(visibility, "diffuse")
col.prop(visibility, "glossy")
col.prop(visibility, "transmission")
col.prop(visibility, "scatter")
col.prop(ob, "visible_camera", text="Camera")
col.prop(ob, "visible_diffuse", text="Diffuse")
col.prop(ob, "visible_glossy", text="Glossy")
col.prop(ob, "visible_transmission", text="Transmission")
col.prop(ob, "visible_volume_scatter", text="Volume Scatter")
if ob.type != 'LIGHT':
sub = col.column()
sub.prop(visibility, "shadow")
sub.prop(ob, "visible_shadow", text="Shadow")
class CYCLES_OBJECT_PT_visibility_culling(CyclesButtonsPanel, Panel):
@ -2305,6 +2322,7 @@ classes = (
CYCLES_OBJECT_PT_motion_blur,
CYCLES_OBJECT_PT_shading,
CYCLES_OBJECT_PT_shading_shadow_terminator,
CYCLES_OBJECT_PT_shading_gi_approximation,
CYCLES_OBJECT_PT_visibility,
CYCLES_OBJECT_PT_visibility_ray_visibility,
CYCLES_OBJECT_PT_visibility_culling,

View File

@ -199,8 +199,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
/* Visibility flags for both parent and child. */
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
bool use_holdout = get_boolean(cobject, "is_holdout") ||
b_parent.holdout_get(PointerRNA_NULL, b_view_layer);
bool use_holdout = b_parent.holdout_get(PointerRNA_NULL, b_view_layer);
uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
if (b_parent.ptr.data != b_ob.ptr.data) {
@ -287,8 +286,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
object->set_visibility(visibility);
bool is_shadow_catcher = get_boolean(cobject, "is_shadow_catcher");
object->set_is_shadow_catcher(is_shadow_catcher);
object->set_is_shadow_catcher(b_ob.is_shadow_catcher());
float shadow_terminator_shading_offset = get_float(cobject, "shadow_terminator_offset");
object->set_shadow_terminator_shading_offset(shadow_terminator_shading_offset);
@ -297,6 +295,13 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
"shadow_terminator_geometry_offset");
object->set_shadow_terminator_geometry_offset(shadow_terminator_geometry_offset);
float ao_distance = get_float(cobject, "ao_distance");
if (ao_distance == 0.0f && b_parent.ptr.data != b_ob.ptr.data) {
PointerRNA cparent = RNA_pointer_get(&b_parent.ptr, "cycles");
ao_distance = get_float(cparent, "ao_distance");
}
object->set_ao_distance(ao_distance);
/* sync the asset name for Cryptomatte */
BL::Object parent = b_ob.parent();
ustring parent_name;

View File

@ -596,15 +596,14 @@ static inline Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob,
static inline uint object_ray_visibility(BL::Object &b_ob)
{
PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility");
uint flag = 0;
flag |= get_boolean(cvisibility, "camera") ? PATH_RAY_CAMERA : 0;
flag |= get_boolean(cvisibility, "diffuse") ? PATH_RAY_DIFFUSE : 0;
flag |= get_boolean(cvisibility, "glossy") ? PATH_RAY_GLOSSY : 0;
flag |= get_boolean(cvisibility, "transmission") ? PATH_RAY_TRANSMIT : 0;
flag |= get_boolean(cvisibility, "shadow") ? PATH_RAY_SHADOW : 0;
flag |= get_boolean(cvisibility, "scatter") ? PATH_RAY_VOLUME_SCATTER : 0;
flag |= b_ob.visible_camera() ? PATH_RAY_CAMERA : 0;
flag |= b_ob.visible_diffuse() ? PATH_RAY_DIFFUSE : 0;
flag |= b_ob.visible_glossy() ? PATH_RAY_GLOSSY : 0;
flag |= b_ob.visible_transmission() ? PATH_RAY_TRANSMIT : 0;
flag |= b_ob.visible_shadow() ? PATH_RAY_SHADOW : 0;
flag |= b_ob.visible_volume_scatter() ? PATH_RAY_VOLUME_SCATTER : 0;
return flag;
}

View File

@ -239,4 +239,14 @@ ccl_device_forceinline int intersection_get_shader(KernelGlobals *ccl_restrict k
return shader & SHADER_MASK;
}
ccl_device_forceinline int intersection_get_object(KernelGlobals *ccl_restrict kg,
const Intersection *ccl_restrict isect)
{
if (isect->object != OBJECT_NONE) {
return isect->object;
}
return kernel_tex_fetch(__prim_object, isect->prim);
}
CCL_NAMESPACE_END

View File

@ -81,7 +81,8 @@ ccl_device_noinline void compute_light_pass(
kg, sd, emission_sd, L, &state, &ray, &throughput, &ss_indirect)) {
while (ss_indirect.num_rays) {
kernel_path_subsurface_setup_indirect(kg, &ss_indirect, &state, &ray, L, &throughput);
kernel_path_indirect(kg, &indirect_sd, emission_sd, &ray, throughput, &state, L);
kernel_path_indirect(
kg, &indirect_sd, emission_sd, &ray, throughput, &state, L, sd->object);
}
is_sss_sample = true;
}
@ -97,7 +98,8 @@ ccl_device_noinline void compute_light_pass(
state.ray_t = 0.0f;
# endif
/* compute indirect light */
kernel_path_indirect(kg, &indirect_sd, emission_sd, &ray, throughput, &state, L);
kernel_path_indirect(
kg, &indirect_sd, emission_sd, &ray, throughput, &state, L, sd->object);
/* sum and reset indirect light pass variables for the next samples */
path_radiance_sum_indirect(L);

View File

@ -58,7 +58,8 @@ ccl_device_forceinline bool kernel_path_scene_intersect(KernelGlobals *kg,
ccl_addr_space PathState *state,
Ray *ray,
Intersection *isect,
PathRadiance *L)
PathRadiance *L,
const int last_object)
{
PROFILING_INIT(kg, PROFILING_SCENE_INTERSECT);
@ -66,6 +67,12 @@ ccl_device_forceinline bool kernel_path_scene_intersect(KernelGlobals *kg,
if (path_state_ao_bounce(kg, state)) {
ray->t = kernel_data.background.ao_distance;
if (last_object != OBJECT_NONE) {
const float object_ao_distance = kernel_tex_fetch(__objects, last_object).ao_distance;
if (object_ao_distance != 0.0f) {
ray->t = object_ao_distance;
}
}
}
bool hit = scene_intersect(kg, ray, visibility, isect);
@ -253,7 +260,7 @@ ccl_device_forceinline bool kernel_path_shader_apply(KernelGlobals *kg,
PROFILING_INIT(kg, PROFILING_SHADER_APPLY);
#ifdef __SHADOW_TRICKS__
if ((sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) {
if (sd->object_flag & SD_OBJECT_SHADOW_CATCHER) {
if (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND) {
state->flag |= (PATH_RAY_SHADOW_CATCHER | PATH_RAY_STORE_SHADOW_INFO);
@ -369,7 +376,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
Ray *ray,
float3 throughput,
PathState *state,
PathRadiance *L)
PathRadiance *L,
const int last_object)
{
# ifdef __SUBSURFACE__
SubsurfaceIndirectRays ss_indirect;
@ -382,7 +390,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
for (;;) {
/* Find intersection with objects in scene. */
Intersection isect;
bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L, last_object);
/* Find intersection with lamps and compute emission for MIS. */
kernel_path_lamp_emission(kg, state, ray, throughput, &isect, sd, L);
@ -526,7 +534,7 @@ ccl_device_forceinline void kernel_path_integrate(KernelGlobals *kg,
for (;;) {
/* Find intersection with objects in scene. */
Intersection isect;
bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L, sd.object);
/* Find intersection with lamps and compute emission for MIS. */
kernel_path_lamp_emission(kg, state, ray, throughput, &isect, &sd, L);

View File

@ -92,6 +92,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
volume_ray.t = (hit) ? isect->t : FLT_MAX;
float step_size = volume_stack_step_size(kg, state->volume_stack);
const int object = sd->object;
# ifdef __VOLUME_DECOUPLED__
/* decoupled ray marching only supported on CPU */
@ -134,7 +135,8 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
if (result == VOLUME_PATH_SCATTERED &&
kernel_path_volume_bounce(kg, sd, &tp, &ps, &L->state, &pray)) {
kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp * num_samples_inv, &ps, L);
kernel_path_indirect(
kg, indirect_sd, emission_sd, &pray, tp * num_samples_inv, &ps, L, object);
/* for render passes, sum and reset indirect light pass variables
* for the next samples */
@ -180,7 +182,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
kernel_path_volume_connect_light(kg, sd, emission_sd, tp, state, L);
if (kernel_path_volume_bounce(kg, sd, &tp, &ps, &L->state, &pray)) {
kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp, &ps, L);
kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp, &ps, L, object);
/* for render passes, sum and reset indirect light pass variables
* for the next samples */
@ -266,7 +268,8 @@ ccl_device_noinline_cpu void kernel_branched_path_surface_indirect_light(KernelG
ps.rng_hash = state->rng_hash;
kernel_path_indirect(kg, indirect_sd, emission_sd, &bsdf_ray, tp * num_samples_inv, &ps, L);
kernel_path_indirect(
kg, indirect_sd, emission_sd, &bsdf_ray, tp * num_samples_inv, &ps, L, sd->object);
/* for render passes, sum and reset indirect light pass variables
* for the next samples */
@ -395,7 +398,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
for (;;) {
/* Find intersection with objects in scene. */
Intersection isect;
bool hit = kernel_path_scene_intersect(kg, &state, &ray, &isect, L);
bool hit = kernel_path_scene_intersect(kg, &state, &ray, &isect, L, sd.object);
# ifdef __VOLUME__
/* Volume integration. */

View File

@ -1447,7 +1447,10 @@ typedef struct KernelObject {
float shadow_terminator_shading_offset;
float shadow_terminator_geometry_offset;
float pad1, pad2, pad3;
float ao_distance;
float pad1, pad2;
} KernelObject;
static_assert_align(KernelObject, 16);

View File

@ -65,7 +65,10 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg)
PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
Intersection isect;
bool hit = kernel_path_scene_intersect(kg, state, &ray, &isect, L);
const int last_object = state->bounce > 0 ?
intersection_get_object(kg, &kernel_split_state.isect[ray_index]) :
OBJECT_NONE;
bool hit = kernel_path_scene_intersect(kg, state, &ray, &isect, L, last_object);
kernel_split_state.isect[ray_index] = isect;
if (!hit) {

View File

@ -102,6 +102,8 @@ NODE_DEFINE(Object)
SOCKET_NODE(particle_system, "Particle System", ParticleSystem::get_node_type());
SOCKET_INT(particle_index, "Particle Index", 0);
SOCKET_FLOAT(ao_distance, "AO Distance", 0.0f);
return type;
}
@ -428,6 +430,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
kobject.random_number = random_number;
kobject.particle_index = particle_index;
kobject.motion_offset = 0;
kobject.ao_distance = ob->ao_distance;
if (geom->get_use_motion_blur()) {
state->have_motion = true;

View File

@ -73,6 +73,8 @@ class Object : public Node {
NODE_SOCKET_API(ParticleSystem *, particle_system);
NODE_SOCKET_API(int, particle_index);
NODE_SOCKET_API(float, ao_distance)
Object();
~Object();

View File

@ -1066,22 +1066,6 @@ void GHOST_XrDestroyActions(GHOST_XrContextHandle xr_context,
uint32_t count,
const char *const *action_names);
/**
* Create spaces for pose-based OpenXR actions.
*/
int GHOST_XrCreateActionSpaces(GHOST_XrContextHandle xr_context,
const char *action_set_name,
uint32_t count,
const GHOST_XrActionSpaceInfo *infos);
/**
* Destroy previously created spaces for OpenXR actions.
*/
void GHOST_XrDestroyActionSpaces(GHOST_XrContextHandle xr_context,
const char *action_set_name,
uint32_t count,
const GHOST_XrActionSpaceInfo *infos);
/**
* Create input/output path bindings for OpenXR actions.
*/
@ -1096,7 +1080,8 @@ int GHOST_XrCreateActionBindings(GHOST_XrContextHandle xr_context,
void GHOST_XrDestroyActionBindings(GHOST_XrContextHandle xr_context,
const char *action_set_name,
uint32_t count,
const GHOST_XrActionProfileInfo *infos);
const char *const *action_names,
const char *const *profile_paths);
/**
* Attach all created action sets to the current OpenXR session.
@ -1117,6 +1102,7 @@ int GHOST_XrSyncActions(GHOST_XrContextHandle xr_context, const char *action_set
int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_context,
const char *action_set_name,
const char *action_name,
const char **subaction_path,
const int64_t *duration,
const float *frequency,
const float *amplitude);
@ -1126,7 +1112,8 @@ int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_context,
*/
void GHOST_XrStopHapticAction(GHOST_XrContextHandle xr_context,
const char *action_set_name,
const char *action_name);
const char *action_name,
const char **subaction_path);
/**
* Get action set custom data (owned by Blender, not GHOST).
@ -1141,6 +1128,18 @@ void *GHOST_XrGetActionCustomdata(GHOST_XrContextHandle xr_context,
const char *action_set_name,
const char *action_name);
/**
* Get the number of actions in an action set.
*/
unsigned int GHOST_XrGetActionCount(GHOST_XrContextHandle xr_context, const char *action_set_name);
/**
* Get custom data for all actions in an action set.
*/
void GHOST_XrGetActionCustomdataArray(GHOST_XrContextHandle xr_context,
const char *action_set_name,
void **r_customdata_array);
#endif /* WITH_XR_OPENXR */
#ifdef __cplusplus

View File

@ -719,29 +719,27 @@ typedef struct GHOST_XrActionInfo {
const char **subaction_paths;
/** States for each subaction path. */
void *states;
/** Input thresholds/regions for each subaction path. */
float *float_thresholds;
int16_t *axis_flags;
GHOST_XrCustomdataFreeFn customdata_free_fn;
void *customdata; /* wmXrAction */
} GHOST_XrActionInfo;
typedef struct GHOST_XrActionSpaceInfo {
const char *action_name;
uint32_t count_subaction_paths;
const char **subaction_paths;
/** Poses for each subaction path. */
const GHOST_XrPose *poses;
} GHOST_XrActionSpaceInfo;
typedef struct GHOST_XrActionBindingInfo {
const char *action_name;
uint32_t count_interaction_paths;
/** Interaction path: User (sub-action) path + component path. */
const char **interaction_paths;
const char *component_path;
float float_threshold;
int16_t axis_flag;
GHOST_XrPose pose;
} GHOST_XrActionBindingInfo;
typedef struct GHOST_XrActionProfileInfo {
const char *action_name;
const char *profile_path;
uint32_t count_bindings;
uint32_t count_subaction_paths;
const char **subaction_paths;
/* Bindings for each subaction path. */
const GHOST_XrActionBindingInfo *bindings;
} GHOST_XrActionProfileInfo;

View File

@ -961,28 +961,6 @@ void GHOST_XrDestroyActions(GHOST_XrContextHandle xr_contexthandle,
GHOST_XR_CAPI_CALL(xr_session->destroyActions(action_set_name, count, action_names), xr_context);
}
int GHOST_XrCreateActionSpaces(GHOST_XrContextHandle xr_contexthandle,
const char *action_set_name,
uint32_t count,
const GHOST_XrActionSpaceInfo *infos)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
GHOST_XrSession *xr_session = xr_context->getSession();
GHOST_XR_CAPI_CALL_RET(xr_session->createActionSpaces(action_set_name, count, infos),
xr_context);
return 0;
}
void GHOST_XrDestroyActionSpaces(GHOST_XrContextHandle xr_contexthandle,
const char *action_set_name,
uint32_t count,
const GHOST_XrActionSpaceInfo *infos)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
GHOST_XrSession *xr_session = xr_context->getSession();
GHOST_XR_CAPI_CALL(xr_session->destroyActionSpaces(action_set_name, count, infos), xr_context);
}
int GHOST_XrCreateActionBindings(GHOST_XrContextHandle xr_contexthandle,
const char *action_set_name,
uint32_t count,
@ -998,11 +976,14 @@ int GHOST_XrCreateActionBindings(GHOST_XrContextHandle xr_contexthandle,
void GHOST_XrDestroyActionBindings(GHOST_XrContextHandle xr_contexthandle,
const char *action_set_name,
uint32_t count,
const GHOST_XrActionProfileInfo *infos)
const char *const *action_names,
const char *const *profile_paths)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
GHOST_XrSession *xr_session = xr_context->getSession();
GHOST_XR_CAPI_CALL(xr_session->destroyActionBindings(action_set_name, count, infos), xr_context);
GHOST_XR_CAPI_CALL(
xr_session->destroyActionBindings(action_set_name, count, action_names, profile_paths),
xr_context);
}
int GHOST_XrAttachActionSets(GHOST_XrContextHandle xr_contexthandle)
@ -1024,25 +1005,29 @@ int GHOST_XrSyncActions(GHOST_XrContextHandle xr_contexthandle, const char *acti
int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_contexthandle,
const char *action_set_name,
const char *action_name,
const char **subaction_path,
const int64_t *duration,
const float *frequency,
const float *amplitude)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
GHOST_XrSession *xr_session = xr_context->getSession();
GHOST_XR_CAPI_CALL_RET(xr_session->applyHapticAction(
action_set_name, action_name, *duration, *frequency, *amplitude),
xr_context);
GHOST_XR_CAPI_CALL_RET(
xr_session->applyHapticAction(
action_set_name, action_name, subaction_path, *duration, *frequency, *amplitude),
xr_context);
return 0;
}
void GHOST_XrStopHapticAction(GHOST_XrContextHandle xr_contexthandle,
const char *action_set_name,
const char *action_name)
const char *action_name,
const char **subaction_path)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
GHOST_XrSession *xr_session = xr_context->getSession();
GHOST_XR_CAPI_CALL(xr_session->stopHapticAction(action_set_name, action_name), xr_context);
GHOST_XR_CAPI_CALL(xr_session->stopHapticAction(action_set_name, action_name, subaction_path),
xr_context);
}
void *GHOST_XrGetActionSetCustomdata(GHOST_XrContextHandle xr_contexthandle,
@ -1065,4 +1050,23 @@ void *GHOST_XrGetActionCustomdata(GHOST_XrContextHandle xr_contexthandle,
return 0;
}
unsigned int GHOST_XrGetActionCount(GHOST_XrContextHandle xr_contexthandle,
const char *action_set_name)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
GHOST_XrSession *xr_session = xr_context->getSession();
GHOST_XR_CAPI_CALL_RET(xr_session->getActionCount(action_set_name), xr_context);
return 0;
}
void GHOST_XrGetActionCustomdataArray(GHOST_XrContextHandle xr_contexthandle,
const char *action_set_name,
void **r_customdata_array)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
GHOST_XrSession *xr_session = xr_context->getSession();
GHOST_XR_CAPI_CALL(xr_session->getActionCustomdataArray(action_set_name, r_customdata_array),
xr_context);
}
#endif /* WITH_XR_OPENXR */

View File

@ -295,8 +295,8 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
glXMakeCurrent(m_display, m_window, m_context);
// Seems that this has to be called after MakeCurrent,
// which means we cannot use glX extensions until after we create a context
/* Seems that this has to be called after #glXMakeCurrent,
* which means we cannot use `glX` extensions until after we create a context. */
initContextGLXEW();
if (m_window) {

View File

@ -141,22 +141,26 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(
printf(" setting.frequency=%d\n", setting.frequency);
#endif // GHOST_DEBUG
// Display configuration is no more available in 10.6
/* Display configuration is no more available in 10.6. */
/* CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate(
m_displayIDs[display],
(size_t)setting.bpp,
(size_t)setting.xPixels,
(size_t)setting.yPixels,
(CGRefreshRate)setting.frequency,
NULL);*/
#if 0
CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate(
m_displayIDs[display],
(size_t)setting.bpp,
(size_t)setting.xPixels,
(size_t)setting.yPixels,
(CGRefreshRate)setting.frequency,
NULL);
#endif
#ifdef GHOST_DEBUG
/* printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");
# if 0
printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");
printf(" setting.xPixels=%d\n", getValue(displayModeValues, kCGDisplayWidth));
printf(" setting.yPixels=%d\n", getValue(displayModeValues, kCGDisplayHeight));
printf(" setting.bpp=%d\n", getValue(displayModeValues, kCGDisplayBitsPerPixel));
printf(" setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate)); */
printf(" setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate));
# endif
#endif // GHOST_DEBUG
// CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);

View File

@ -32,7 +32,6 @@
GHOST_ImeWin32::GHOST_ImeWin32()
: is_composing_(false),
ime_status_(false),
input_language_id_(LANG_USER_DEFAULT),
conversion_modes_(IME_CMODE_ALPHANUMERIC),
sentence_mode_(IME_SMODE_NONE),
@ -47,18 +46,13 @@ GHOST_ImeWin32::~GHOST_ImeWin32()
{
}
bool GHOST_ImeWin32::SetInputLanguage()
void GHOST_ImeWin32::UpdateInputLanguage()
{
/**
* Retrieve the current keyboard layout from Windows and determine whether
* or not the current input context has IMEs.
* Also save its input language for language-specific operations required
* while composing a text.
* Store the current input language.
*/
HKL keyboard_layout = ::GetKeyboardLayout(0);
input_language_id_ = LOWORD(keyboard_layout);
ime_status_ = ::ImmIsIME(keyboard_layout);
return ime_status_;
HKL input_locale = ::GetKeyboardLayout(0);
input_language_id_ = LOWORD(input_locale);
}
WORD GHOST_ImeWin32::GetInputLanguage()

View File

@ -88,7 +88,7 @@ class GHOST_EventIME : public GHOST_Event {
* An application CAN call ::DefWindowProc().
* 2.5. WM_INPUTLANGCHANGE (0x0051)
* Call the functions listed below:
* - GHOST_ImeWin32::SetInputLanguage().
* - GHOST_ImeWin32::UpdateInputLanguage().
* An application CAN call ::DefWindowProc().
*/
@ -148,13 +148,8 @@ class GHOST_ImeWin32 {
/**
* Retrieves the input language from Windows and update it.
* Return values
* * true
* The given input language has IMEs.
* * false
* The given input language does not have IMEs.
*/
bool SetInputLanguage();
void UpdateInputLanguage();
/* Returns the current input language id. */
WORD GetInputLanguage();
@ -350,15 +345,6 @@ class GHOST_ImeWin32 {
*/
bool is_composing_;
/**
* This value represents whether or not the current input context has IMEs.
* The following table shows the list of IME status:
* Value Description
* false The current input language does not have IMEs.
* true The current input language has IMEs.
*/
bool ime_status_;
/**
* The current input Language ID retrieved from Windows, which consists of:
* * Primary Language ID (bit 0 to bit 9), which shows a natural language

View File

@ -473,7 +473,7 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
GHOST_TKey gkey = convertSDLKey(sdl_sub_evt.keysym.scancode);
/* NOTE: the `sdl_sub_evt.keysym.sym` is truncated,
* for unicode support ghost has to be modified. */
/* printf("%d\n", sym); */
// printf("%d\n", sym);
if (sym > 127) {
switch (sym) {
case SDLK_KP_DIVIDE:

View File

@ -1424,7 +1424,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_INPUTLANGCHANGE: {
system->handleKeyboardChange();
#ifdef WITH_INPUT_IME
window->getImeInput()->SetInputLanguage();
window->getImeInput()->UpdateInputLanguage();
window->getImeInput()->UpdateConversionStatus(hwnd);
#endif
break;
@ -1471,7 +1471,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
}
case WM_IME_SETCONTEXT: {
GHOST_ImeWin32 *ime = window->getImeInput();
ime->SetInputLanguage();
ime->UpdateInputLanguage();
ime->CreateImeWindow(hwnd);
ime->CleanupComposition(hwnd);
ime->CheckFirst(hwnd);

View File

@ -802,8 +802,7 @@ static bool checkTabletProximity(Display *display, XDevice *device)
if (state) {
XInputClass *cls = state->data;
// printf("%d class%s :\n", state->num_classes,
// (state->num_classes > 1) ? "es" : "");
// printf("%d class%s :\n", state->num_classes, (state->num_classes > 1) ? "es" : "");
for (int loop = 0; loop < state->num_classes; loop++) {
switch (cls->c_class) {
case ValuatorClass:

View File

@ -403,7 +403,7 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
}
if (natom) {
/* printf("Register atoms: %d\n", natom); */
// printf("Register atoms: %d\n", natom);
XSetWMProtocols(m_display, m_window, atoms, natom);
}
}
@ -1275,15 +1275,15 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
{
if (type == GHOST_kDrawingContextTypeOpenGL) {
// During development:
// try 4.x compatibility profile
// try 3.3 compatibility profile
// fall back to 3.0 if needed
//
// Final Blender 2.8:
// try 4.x core profile
// try 3.3 core profile
// no fallbacks
/* During development:
* - Try 4.x compatibility profile.
* - Try 3.3 compatibility profile.
* - Fall back to 3.0 if needed.
*
* Final Blender 2.8:
* - Try 4.x core profile
* - Try 3.3 core profile
* - No fall-backs. */
#if defined(WITH_GL_PROFILE_CORE)
{

View File

@ -33,24 +33,22 @@
*
* \{ */
GHOST_XrActionSpace::GHOST_XrActionSpace(XrInstance instance,
XrSession session,
GHOST_XrActionSpace::GHOST_XrActionSpace(XrSession session,
XrAction action,
const GHOST_XrActionSpaceInfo &info,
uint32_t subaction_idx)
const char *action_name,
const char *profile_path,
XrPath subaction_path,
const char *subaction_path_str,
const GHOST_XrPose &pose)
{
const char *subaction_path = info.subaction_paths[subaction_idx];
CHECK_XR(xrStringToPath(instance, subaction_path, &m_subaction_path),
(std::string("Failed to get user path \"") + subaction_path + "\".").data());
XrActionSpaceCreateInfo action_space_info{XR_TYPE_ACTION_SPACE_CREATE_INFO};
action_space_info.action = action;
action_space_info.subactionPath = m_subaction_path;
copy_ghost_pose_to_openxr_pose(info.poses[subaction_idx], action_space_info.poseInActionSpace);
action_space_info.subactionPath = subaction_path;
copy_ghost_pose_to_openxr_pose(pose, action_space_info.poseInActionSpace);
CHECK_XR(xrCreateActionSpace(session, &action_space_info, &m_space),
(std::string("Failed to create space \"") + subaction_path + "\" for action \"" +
info.action_name + "\".")
(std::string("Failed to create space \"") + subaction_path_str + "\" for action \"" +
action_name + "\" and profile \"" + profile_path + "\".")
.data());
}
@ -66,11 +64,6 @@ XrSpace GHOST_XrActionSpace::getSpace() const
return m_space;
}
const XrPath &GHOST_XrActionSpace::getSubactionPath() const
{
return m_subaction_path;
}
/** \} */
/* -------------------------------------------------------------------- */
@ -79,13 +72,19 @@ const XrPath &GHOST_XrActionSpace::getSubactionPath() const
* \{ */
GHOST_XrActionProfile::GHOST_XrActionProfile(XrInstance instance,
XrSession session,
XrAction action,
const char *profile_path,
const GHOST_XrActionBindingInfo &info)
GHOST_XrActionType type,
const GHOST_XrActionProfileInfo &info)
{
CHECK_XR(
xrStringToPath(instance, profile_path, &m_profile),
(std::string("Failed to get interaction profile path \"") + profile_path + "\".").data());
CHECK_XR(xrStringToPath(instance, info.profile_path, &m_profile),
(std::string("Failed to get interaction profile path \"") + info.profile_path + "\".")
.data());
const bool is_float_action = (type == GHOST_kXrActionTypeFloatInput ||
type == GHOST_kXrActionTypeVector2fInput);
const bool is_button_action = (is_float_action || type == GHOST_kXrActionTypeBooleanInput);
const bool is_pose_action = (type == GHOST_kXrActionTypePoseInput);
/* Create bindings. */
XrInteractionProfileSuggestedBinding bindings_info{
@ -93,31 +92,80 @@ GHOST_XrActionProfile::GHOST_XrActionProfile(XrInstance instance,
bindings_info.interactionProfile = m_profile;
bindings_info.countSuggestedBindings = 1;
for (uint32_t interaction_idx = 0; interaction_idx < info.count_interaction_paths;
++interaction_idx) {
const char *interaction_path = info.interaction_paths[interaction_idx];
for (uint32_t subaction_idx = 0; subaction_idx < info.count_subaction_paths; ++subaction_idx) {
const char *subaction_path_str = info.subaction_paths[subaction_idx];
const GHOST_XrActionBindingInfo &binding_info = info.bindings[subaction_idx];
const std::string interaction_path = std::string(subaction_path_str) +
binding_info.component_path;
if (m_bindings.find(interaction_path) != m_bindings.end()) {
continue;
}
XrActionSuggestedBinding sbinding;
sbinding.action = action;
CHECK_XR(xrStringToPath(instance, interaction_path, &sbinding.binding),
CHECK_XR(xrStringToPath(instance, interaction_path.data(), &sbinding.binding),
(std::string("Failed to get interaction path \"") + interaction_path + "\".").data());
bindings_info.suggestedBindings = &sbinding;
/* Although the bindings will be re-suggested in GHOST_XrSession::attachActionSets(), it
* greatly improves error checking to suggest them here first. */
CHECK_XR(xrSuggestInteractionProfileBindings(instance, &bindings_info),
(std::string("Failed to create binding for profile \"") + profile_path +
"\" and action \"" + info.action_name +
"\". Are the profile and action paths correct?")
(std::string("Failed to create binding for action \"") + info.action_name +
"\" and profile \"" + info.profile_path +
"\". Are the action and profile paths correct?")
.data());
m_bindings.insert({interaction_path, sbinding.binding});
if (m_subaction_data.find(subaction_path_str) == m_subaction_data.end()) {
std::map<std::string, GHOST_XrSubactionData>::iterator it =
m_subaction_data
.emplace(
std::piecewise_construct, std::make_tuple(subaction_path_str), std::make_tuple())
.first;
GHOST_XrSubactionData &subaction = it->second;
CHECK_XR(xrStringToPath(instance, subaction_path_str, &subaction.subaction_path),
(std::string("Failed to get user path \"") + subaction_path_str + "\".").data());
if (is_float_action || is_button_action) {
if (is_float_action) {
subaction.float_threshold = binding_info.float_threshold;
}
if (is_button_action) {
subaction.axis_flag = binding_info.axis_flag;
}
}
else if (is_pose_action) {
/* Create action space for pose bindings. */
subaction.space = std::make_unique<GHOST_XrActionSpace>(session,
action,
info.action_name,
info.profile_path,
subaction.subaction_path,
subaction_path_str,
binding_info.pose);
}
}
}
}
XrPath GHOST_XrActionProfile::getProfile() const
{
return m_profile;
}
const GHOST_XrSubactionData *GHOST_XrActionProfile::getSubaction(XrPath subaction_path) const
{
for (auto &[subaction_path_str, subaction] : m_subaction_data) {
if (subaction.subaction_path == subaction_path) {
return &subaction;
}
}
return nullptr;
}
void GHOST_XrActionProfile::getBindings(
XrAction action, std::map<XrPath, std::vector<XrActionSuggestedBinding>> &r_bindings) const
{
@ -152,14 +200,18 @@ GHOST_XrAction::GHOST_XrAction(XrInstance instance,
const GHOST_XrActionInfo &info)
: m_type(info.type),
m_states(info.states),
m_float_thresholds(info.float_thresholds),
m_axis_flags(info.axis_flags),
m_custom_data_(
std::make_unique<GHOST_C_CustomDataWrapper>(info.customdata, info.customdata_free_fn))
{
m_subaction_paths.resize(info.count_subaction_paths);
for (uint32_t i = 0; i < info.count_subaction_paths; ++i) {
CHECK_XR(xrStringToPath(instance, info.subaction_paths[i], &m_subaction_paths[i]),
(std::string("Failed to get user path \"") + info.subaction_paths[i] + "\".").data());
const char *subaction_path_str = info.subaction_paths[i];
CHECK_XR(xrStringToPath(instance, subaction_path_str, &m_subaction_paths[i]),
(std::string("Failed to get user path \"") + subaction_path_str + "\".").data());
m_subaction_indices.insert({subaction_path_str, i});
}
XrActionCreateInfo action_info{XR_TYPE_ACTION_CREATE_INFO};
@ -201,52 +253,25 @@ GHOST_XrAction::~GHOST_XrAction()
}
}
bool GHOST_XrAction::createSpace(XrInstance instance,
XrSession session,
const GHOST_XrActionSpaceInfo &info)
{
uint32_t subaction_idx = 0;
for (; subaction_idx < info.count_subaction_paths; ++subaction_idx) {
if (m_spaces.find(info.subaction_paths[subaction_idx]) != m_spaces.end()) {
return false;
}
}
for (subaction_idx = 0; subaction_idx < info.count_subaction_paths; ++subaction_idx) {
m_spaces.emplace(std::piecewise_construct,
std::make_tuple(info.subaction_paths[subaction_idx]),
std::make_tuple(instance, session, m_action, info, subaction_idx));
}
return true;
}
void GHOST_XrAction::destroySpace(const char *subaction_path)
{
if (m_spaces.find(subaction_path) != m_spaces.end()) {
m_spaces.erase(subaction_path);
}
}
bool GHOST_XrAction::createBinding(XrInstance instance,
const char *profile_path,
const GHOST_XrActionBindingInfo &info)
XrSession session,
const GHOST_XrActionProfileInfo &info)
{
if (m_profiles.find(profile_path) != m_profiles.end()) {
if (m_profiles.find(info.profile_path) != m_profiles.end()) {
return false;
}
m_profiles.emplace(std::piecewise_construct,
std::make_tuple(profile_path),
std::make_tuple(instance, m_action, profile_path, info));
std::make_tuple(info.profile_path),
std::make_tuple(instance, session, m_action, m_type, info));
return true;
}
void GHOST_XrAction::destroyBinding(const char *interaction_profile_path)
void GHOST_XrAction::destroyBinding(const char *profile_path)
{
if (m_profiles.find(interaction_profile_path) != m_profiles.end()) {
m_profiles.erase(interaction_profile_path);
if (m_profiles.find(profile_path) != m_profiles.end()) {
m_profiles.erase(profile_path);
}
}
@ -255,6 +280,10 @@ void GHOST_XrAction::updateState(XrSession session,
XrSpace reference_space,
const XrTime &predicted_display_time)
{
const bool is_float_action = (m_type == GHOST_kXrActionTypeFloatInput ||
m_type == GHOST_kXrActionTypeVector2fInput);
const bool is_button_action = (is_float_action || m_type == GHOST_kXrActionTypeBooleanInput);
XrActionStateGetInfo state_info{XR_TYPE_ACTION_STATE_GET_INFO};
state_info.action = m_action;
@ -262,6 +291,28 @@ void GHOST_XrAction::updateState(XrSession session,
for (size_t subaction_idx = 0; subaction_idx < count_subaction_paths; ++subaction_idx) {
state_info.subactionPath = m_subaction_paths[subaction_idx];
/* Set subaction data based on current interaction profile. */
XrInteractionProfileState profile_state{XR_TYPE_INTERACTION_PROFILE_STATE};
CHECK_XR(xrGetCurrentInteractionProfile(session, state_info.subactionPath, &profile_state),
"Failed to get current interaction profile.");
const GHOST_XrSubactionData *subaction = nullptr;
for (auto &[profile_path, profile] : m_profiles) {
if (profile.getProfile() == profile_state.interactionProfile) {
subaction = profile.getSubaction(state_info.subactionPath);
break;
}
}
if (subaction != nullptr) {
if (is_float_action) {
m_float_thresholds[subaction_idx] = subaction->float_threshold;
}
if (is_button_action) {
m_axis_flags[subaction_idx] = subaction->axis_flag;
}
}
switch (m_type) {
case GHOST_kXrActionTypeBooleanInput: {
XrActionStateBoolean state{XR_TYPE_ACTION_STATE_BOOLEAN};
@ -299,14 +350,9 @@ void GHOST_XrAction::updateState(XrSession session,
xrGetActionStatePose(session, &state_info, &state),
(std::string("Failed to get state for pose action \"") + action_name + "\".").data());
if (state.isActive) {
XrSpace pose_space = XR_NULL_HANDLE;
for (auto &[path, space] : m_spaces) {
if (space.getSubactionPath() == state_info.subactionPath) {
pose_space = space.getSpace();
break;
}
}
XrSpace pose_space = ((subaction != nullptr) && (subaction->space != nullptr)) ?
subaction->space->getSpace() :
XR_NULL_HANDLE;
if (pose_space != XR_NULL_HANDLE) {
XrSpaceLocation space_location{XR_TYPE_SPACE_LOCATION};
CHECK_XR(
@ -329,6 +375,7 @@ void GHOST_XrAction::updateState(XrSession session,
void GHOST_XrAction::applyHapticFeedback(XrSession session,
const char *action_name,
const char **subaction_path_str,
const int64_t &duration,
const float &frequency,
const float &amplitude)
@ -342,24 +389,46 @@ void GHOST_XrAction::applyHapticFeedback(XrSession session,
XrHapticActionInfo haptic_info{XR_TYPE_HAPTIC_ACTION_INFO};
haptic_info.action = m_action;
for (std::vector<XrPath>::iterator it = m_subaction_paths.begin(); it != m_subaction_paths.end();
++it) {
haptic_info.subactionPath = *it;
CHECK_XR(xrApplyHapticFeedback(session, &haptic_info, (const XrHapticBaseHeader *)&vibration),
(std::string("Failed to apply haptic action \"") + action_name + "\".").data());
if (subaction_path_str != nullptr) {
SubactionIndexMap::iterator it = m_subaction_indices.find(*subaction_path_str);
if (it != m_subaction_indices.end()) {
haptic_info.subactionPath = m_subaction_paths[it->second];
CHECK_XR(
xrApplyHapticFeedback(session, &haptic_info, (const XrHapticBaseHeader *)&vibration),
(std::string("Failed to apply haptic action \"") + action_name + "\".").data());
}
}
else {
for (const XrPath &subaction_path : m_subaction_paths) {
haptic_info.subactionPath = subaction_path;
CHECK_XR(
xrApplyHapticFeedback(session, &haptic_info, (const XrHapticBaseHeader *)&vibration),
(std::string("Failed to apply haptic action \"") + action_name + "\".").data());
}
}
}
void GHOST_XrAction::stopHapticFeedback(XrSession session, const char *action_name)
void GHOST_XrAction::stopHapticFeedback(XrSession session,
const char *action_name,
const char **subaction_path_str)
{
XrHapticActionInfo haptic_info{XR_TYPE_HAPTIC_ACTION_INFO};
haptic_info.action = m_action;
for (std::vector<XrPath>::iterator it = m_subaction_paths.begin(); it != m_subaction_paths.end();
++it) {
haptic_info.subactionPath = *it;
CHECK_XR(xrStopHapticFeedback(session, &haptic_info),
(std::string("Failed to stop haptic action \"") + action_name + "\".").data());
if (subaction_path_str != nullptr) {
SubactionIndexMap::iterator it = m_subaction_indices.find(*subaction_path_str);
if (it != m_subaction_indices.end()) {
haptic_info.subactionPath = m_subaction_paths[it->second];
CHECK_XR(xrStopHapticFeedback(session, &haptic_info),
(std::string("Failed to stop haptic action \"") + action_name + "\".").data());
}
}
else {
for (const XrPath &subaction_path : m_subaction_paths) {
haptic_info.subactionPath = subaction_path;
CHECK_XR(xrStopHapticFeedback(session, &haptic_info),
(std::string("Failed to stop haptic action \"") + action_name + "\".").data());
}
}
}
@ -467,6 +536,19 @@ void *GHOST_XrActionSet::getCustomdata()
return m_custom_data_->custom_data_;
}
uint32_t GHOST_XrActionSet::getActionCount() const
{
return (uint32_t)m_actions.size();
}
void GHOST_XrActionSet::getActionCustomdataArray(void **r_customdata_array)
{
uint32_t i = 0;
for (auto &[name, action] : m_actions) {
r_customdata_array[i++] = action.getCustomdata();
}
}
void GHOST_XrActionSet::getBindings(
std::map<XrPath, std::vector<XrActionSuggestedBinding>> &r_bindings) const
{

View File

@ -18,8 +18,8 @@
* \ingroup GHOST
*/
/* Note: Requires OpenXR headers to be included before this one for OpenXR types (XrSpace, XrPath,
* etc.). */
/* NOTE: Requires OpenXR headers to be included before this one for OpenXR types
* (XrSpace, XrPath, etc.). */
#pragma once
@ -34,38 +34,53 @@
class GHOST_XrActionSpace {
public:
GHOST_XrActionSpace() = delete; /* Default constructor for map storage. */
GHOST_XrActionSpace(XrInstance instance,
XrSession session,
GHOST_XrActionSpace(XrSession session,
XrAction action,
const GHOST_XrActionSpaceInfo &info,
uint32_t subaction_idx);
const char *action_name,
const char *profile_path,
XrPath subaction_path,
const char *subaction_path_str,
const GHOST_XrPose &pose);
~GHOST_XrActionSpace();
XrSpace getSpace() const;
const XrPath &getSubactionPath() const;
private:
XrSpace m_space = XR_NULL_HANDLE;
XrPath m_subaction_path = XR_NULL_PATH;
};
/* -------------------------------------------------------------------- */
typedef struct GHOST_XrSubactionData {
XrPath subaction_path = XR_NULL_PATH;
float float_threshold;
int16_t axis_flag;
std::unique_ptr<GHOST_XrActionSpace> space = nullptr;
} GHOST_XrSubactionData;
/* -------------------------------------------------------------------- */
class GHOST_XrActionProfile {
public:
GHOST_XrActionProfile() = delete; /* Default constructor for map storage. */
GHOST_XrActionProfile(XrInstance instance,
XrSession session,
XrAction action,
const char *profile_path,
const GHOST_XrActionBindingInfo &info);
GHOST_XrActionType type,
const GHOST_XrActionProfileInfo &info);
~GHOST_XrActionProfile() = default;
XrPath getProfile() const;
const GHOST_XrSubactionData *getSubaction(XrPath subaction_path) const;
void getBindings(XrAction action,
std::map<XrPath, std::vector<XrActionSuggestedBinding>> &r_bindings) const;
private:
XrPath m_profile = XR_NULL_PATH;
/* Bindings identified by interaction (user (subaction) + component) path. */
/** Sub-action data identified by user `subaction` path. */
std::map<std::string, GHOST_XrSubactionData> m_subaction_data;
/** Bindings identified by interaction (user `subaction` + component) path. */
std::map<std::string, XrPath> m_bindings;
};
@ -77,12 +92,9 @@ class GHOST_XrAction {
GHOST_XrAction(XrInstance instance, XrActionSet action_set, const GHOST_XrActionInfo &info);
~GHOST_XrAction();
bool createSpace(XrInstance instance, XrSession session, const GHOST_XrActionSpaceInfo &info);
void destroySpace(const char *subaction_path);
bool createBinding(XrInstance instance,
const char *profile_path,
const GHOST_XrActionBindingInfo &info);
XrSession session,
const GHOST_XrActionProfileInfo &info);
void destroyBinding(const char *profile_path);
void updateState(XrSession session,
@ -91,26 +103,31 @@ class GHOST_XrAction {
const XrTime &predicted_display_time);
void applyHapticFeedback(XrSession session,
const char *action_name,
const char **subaction_path,
const int64_t &duration,
const float &frequency,
const float &amplitude);
void stopHapticFeedback(XrSession session, const char *action_name);
void stopHapticFeedback(XrSession session, const char *action_name, const char **subaction_path);
void *getCustomdata();
void getBindings(std::map<XrPath, std::vector<XrActionSuggestedBinding>> &r_bindings) const;
private:
using SubactionIndexMap = std::map<std::string, uint32_t>;
XrAction m_action = XR_NULL_HANDLE;
GHOST_XrActionType m_type;
SubactionIndexMap m_subaction_indices;
std::vector<XrPath> m_subaction_paths;
/** States for each subaction path. */
void *m_states;
/** Input thresholds/regions for each subaction path. */
float *m_float_thresholds;
int16_t *m_axis_flags;
std::unique_ptr<GHOST_C_CustomDataWrapper> m_custom_data_ = nullptr; /* wmXrAction */
/* Spaces identified by user (subaction) path. */
std::map<std::string, GHOST_XrActionSpace> m_spaces;
/* Profiles identified by interaction profile path. */
/** Profiles identified by interaction profile path. */
std::map<std::string, GHOST_XrActionProfile> m_profiles;
};
@ -132,6 +149,8 @@ class GHOST_XrActionSet {
XrActionSet getActionSet() const;
void *getCustomdata();
uint32_t getActionCount() const;
void getActionCustomdataArray(void **r_customdata_array);
void getBindings(std::map<XrPath, std::vector<XrActionSuggestedBinding>> &r_bindings) const;
private:

View File

@ -610,57 +610,6 @@ void GHOST_XrSession::destroyActions(const char *action_set_name,
}
}
bool GHOST_XrSession::createActionSpaces(const char *action_set_name,
uint32_t count,
const GHOST_XrActionSpaceInfo *infos)
{
GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
if (action_set == nullptr) {
return false;
}
XrInstance instance = m_context->getInstance();
XrSession session = m_oxr->session;
for (uint32_t action_idx = 0; action_idx < count; ++action_idx) {
const GHOST_XrActionSpaceInfo &info = infos[action_idx];
GHOST_XrAction *action = action_set->findAction(info.action_name);
if (action == nullptr) {
continue;
}
if (!action->createSpace(instance, session, info)) {
return false;
}
}
return true;
}
void GHOST_XrSession::destroyActionSpaces(const char *action_set_name,
uint32_t count,
const GHOST_XrActionSpaceInfo *infos)
{
GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
if (action_set == nullptr) {
return;
}
for (uint32_t action_idx = 0; action_idx < count; ++action_idx) {
const GHOST_XrActionSpaceInfo &info = infos[action_idx];
GHOST_XrAction *action = action_set->findAction(info.action_name);
if (action == nullptr) {
continue;
}
for (uint32_t subaction_idx = 0; subaction_idx < info.count_subaction_paths; ++subaction_idx) {
action->destroySpace(info.subaction_paths[subaction_idx]);
}
}
}
bool GHOST_XrSession::createActionBindings(const char *action_set_name,
uint32_t count,
const GHOST_XrActionProfileInfo *infos)
@ -671,21 +620,17 @@ bool GHOST_XrSession::createActionBindings(const char *action_set_name,
}
XrInstance instance = m_context->getInstance();
XrSession session = m_oxr->session;
for (uint32_t profile_idx = 0; profile_idx < count; ++profile_idx) {
const GHOST_XrActionProfileInfo &info = infos[profile_idx];
const char *profile_path = info.profile_path;
for (uint32_t binding_idx = 0; binding_idx < info.count_bindings; ++binding_idx) {
const GHOST_XrActionBindingInfo &binding = info.bindings[binding_idx];
GHOST_XrAction *action = action_set->findAction(binding.action_name);
if (action == nullptr) {
continue;
}
action->createBinding(instance, profile_path, binding);
GHOST_XrAction *action = action_set->findAction(info.action_name);
if (action == nullptr) {
continue;
}
action->createBinding(instance, session, info);
}
return true;
@ -693,27 +638,21 @@ bool GHOST_XrSession::createActionBindings(const char *action_set_name,
void GHOST_XrSession::destroyActionBindings(const char *action_set_name,
uint32_t count,
const GHOST_XrActionProfileInfo *infos)
const char *const *action_names,
const char *const *profile_paths)
{
GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
if (action_set == nullptr) {
return;
}
for (uint32_t profile_idx = 0; profile_idx < count; ++profile_idx) {
const GHOST_XrActionProfileInfo &info = infos[profile_idx];
const char *profile_path = info.profile_path;
for (uint32_t binding_idx = 0; binding_idx < info.count_bindings; ++binding_idx) {
const GHOST_XrActionBindingInfo &binding = info.bindings[binding_idx];
GHOST_XrAction *action = action_set->findAction(binding.action_name);
if (action == nullptr) {
continue;
}
action->destroyBinding(profile_path);
for (uint32_t i = 0; i < count; ++i) {
GHOST_XrAction *action = action_set->findAction(action_names[i]);
if (action == nullptr) {
continue;
}
action->destroyBinding(profile_paths[i]);
}
}
@ -815,6 +754,7 @@ bool GHOST_XrSession::syncActions(const char *action_set_name)
bool GHOST_XrSession::applyHapticAction(const char *action_set_name,
const char *action_name,
const char **subaction_path,
const int64_t &duration,
const float &frequency,
const float &amplitude)
@ -829,12 +769,15 @@ bool GHOST_XrSession::applyHapticAction(const char *action_set_name,
return false;
}
action->applyHapticFeedback(m_oxr->session, action_name, duration, frequency, amplitude);
action->applyHapticFeedback(
m_oxr->session, action_name, subaction_path, duration, frequency, amplitude);
return true;
}
void GHOST_XrSession::stopHapticAction(const char *action_set_name, const char *action_name)
void GHOST_XrSession::stopHapticAction(const char *action_set_name,
const char *action_name,
const char **subaction_path)
{
GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
if (action_set == nullptr) {
@ -846,7 +789,7 @@ void GHOST_XrSession::stopHapticAction(const char *action_set_name, const char *
return;
}
action->stopHapticFeedback(m_oxr->session, action_name);
action->stopHapticFeedback(m_oxr->session, action_name, subaction_path);
}
void *GHOST_XrSession::getActionSetCustomdata(const char *action_set_name)
@ -874,4 +817,25 @@ void *GHOST_XrSession::getActionCustomdata(const char *action_set_name, const ch
return action->getCustomdata();
}
uint32_t GHOST_XrSession::getActionCount(const char *action_set_name)
{
GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
if (action_set == nullptr) {
return 0;
}
return action_set->getActionCount();
}
void GHOST_XrSession::getActionCustomdataArray(const char *action_set_name,
void **r_customdata_array)
{
GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
if (action_set == nullptr) {
return;
}
action_set->getActionCustomdataArray(r_customdata_array);
}
/** \} */ /* Actions */

View File

@ -60,18 +60,13 @@ class GHOST_XrSession {
void destroyActions(const char *action_set_name,
uint32_t count,
const char *const *action_names);
bool createActionSpaces(const char *action_set_name,
uint32_t count,
const GHOST_XrActionSpaceInfo *infos);
void destroyActionSpaces(const char *action_set_name,
uint32_t count,
const GHOST_XrActionSpaceInfo *infos);
bool createActionBindings(const char *action_set_name,
uint32_t count,
const GHOST_XrActionProfileInfo *infos);
void destroyActionBindings(const char *action_set_name,
uint32_t count,
const GHOST_XrActionProfileInfo *infos);
const char *const *action_names,
const char *const *profile_paths);
bool attachActionSets();
/**
@ -81,14 +76,19 @@ class GHOST_XrSession {
bool syncActions(const char *action_set_name = nullptr);
bool applyHapticAction(const char *action_set_name,
const char *action_name,
const char **subaction_path,
const int64_t &duration,
const float &frequency,
const float &amplitude);
void stopHapticAction(const char *action_set_name, const char *action_name);
void stopHapticAction(const char *action_set_name,
const char *action_name,
const char **subaction_path);
/* Custom data (owned by Blender, not GHOST) accessors. */
void *getActionSetCustomdata(const char *action_set_name);
void *getActionCustomdata(const char *action_set_name, const char *action_name);
uint32_t getActionCount(const char *action_set_name);
void getActionCustomdataArray(const char *action_set_name, void **r_customdata_array);
private:
/** Pointer back to context managing this session. Would be nice to avoid, but needed to access

View File

@ -58,6 +58,16 @@ if "%BUILD_UPDATE%" == "1" (
call "%BLENDER_DIR%\build_files\windows\set_build_dir.cmd"
if "%ICONS%" == "1" (
call "%BLENDER_DIR%\build_files\windows\icons.cmd"
goto EOF
)
if "%ICONS_GEOM%" == "1" (
call "%BLENDER_DIR%\build_files\windows\icons_geom.cmd"
goto EOF
)
echo Building blender with VS%BUILD_VS_YEAR% for %BUILD_ARCH% in %BUILD_DIR%
call "%BLENDER_DIR%\build_files\windows\check_libraries.cmd"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 25 KiB

32
release/datafiles/alert_icons_update.py Normal file → Executable file
View File

@ -1,5 +1,25 @@
#!/usr/bin/env python3
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# This script updates icons from the SVG file
import os
import subprocess
@ -7,19 +27,19 @@ import sys
BASEDIR = os.path.abspath(os.path.dirname(__file__))
inkscape_path = 'inkscape'
inkscape_bin = os.environ.get("INKSCAPE_BIN", "inkscape")
if sys.platform == 'darwin':
inkscape_app_path = '/Applications/Inkscape.app/Contents/Resources/script'
inkscape_app_path = '/Applications/Inkscape.app/Contents/MacOS/inkscape'
if os.path.exists(inkscape_app_path):
inkscape_path = inkscape_app_path
inkscape_bin = inkscape_app_path
cmd = (
inkscape_path,
inkscape_bin,
os.path.join(BASEDIR, "alert_icons.svg"),
"--export-width=1280",
"--export-height=256",
"--without-gui",
"--export-png=" + os.path.join(BASEDIR, "alert_icons.png"),
"--export-type=png",
"--export-filename=" + os.path.join(BASEDIR, "alert_icons.png"),
)
subprocess.check_call(cmd)

View File

@ -17301,6 +17301,26 @@
d="m 1800,348 h 3 v 14 h -3 z m -4,7 h 16 v 3 h -16 z"
inkscape:connector-curvature="0" />
</g>
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.98999999;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new"
d="m 418.85321,140.04954 -2.82,-2.82 a 0.62,0.62 0 0 0 -0.4,-0.18 0.6,0.6 0 0 0 -0.6,0.6 0.62,0.62 0 0 0 0.18,0.43 l 1,1 -9.18,9.12 -1,-1 a 0.62,0.62 0 0 0 -0.4,-0.15 0.6,0.6 0 0 0 -0.6,0.6 0.62,0.62 0 0 0 0.18,0.4 l 2.82,2.82 a 0.6,0.6 0 0 0 0.82,-0.82 l -1,-1 9.18,-9.15 1,1 a 0.6,0.6 0 0 0 0.82,-0.85 z"
id="path3261"
inkscape:connector-curvature="0" />
<g
style="display:inline;enable-background:new"
transform="translate(-0.35812,42.294299)"
id="g4073">
<path
sodipodi:nodetypes="cccccccccccccssssccs"
d="m 388.17266,99.291166 c -0.27613,4e-5 -0.49997,0.22388 -0.5,0.5 v 1.261304 h -3.16865 v 1.46027 h 3.16865 v 1.27843 c 3e-5,0.27613 0.22387,0.49997 0.5,0.5 h 4 c 0.27613,-3e-5 0.49997,-0.22387 0.5,-0.5 v -4.000004 c -3e-5,-0.27612 -0.22387,-0.49996 -0.5,-0.5 z m 2.59221,-4.74807 c 2.50006,0 4.81247,1.33488 6.0625,3.5 1.25002,2.165124 1.25002,4.834884 0,7.000004 -1.25003,2.16512 -3.56244,3.5 -6.0625,3.5 h -6.5 c 0,-4.66667 0,-9.333336 0,-14.000004 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new"
id="rect10339-4-1-6" />
</g>
<path
id="rect10339-4-1-7-3"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new"
d="m 368.30892,141.58547 c -0.27613,4e-5 -0.49997,0.22388 -0.5,0.5 v 1.26473 h -4.76715 v 1.4911 h 4.76715 v 1.24417 c 3e-5,0.27613 0.22387,0.49997 0.5,0.5 0.63583,0.004 3.43318,-0.006 3.9995,-0.006 0.24106,0 0.46127,-0.0485 0.46127,-0.50967 4e-5,-0.85242 -8.9e-4,-2.98571 -8.9e-4,-3.95935 0,-0.30244 -0.19636,-0.51552 -0.46153,-0.51552 -0.82724,0 -3.36276,-0.009 -3.99823,-0.009 v 2e-5 z m 2.30359,-4.68113 -0.005,4.25868 c 0.48989,0.002 1.39549,0.005 1.88538,0.007 0.44541,0.0357 0.71675,0.47423 0.71675,0.85988 -6.6e-4,1.00616 -0.009,2.97018 -0.009,4.15122 0,0.46073 -0.24756,0.84994 -0.6533,0.84994 -0.48399,0.0143 -1.44986,-1.1e-4 -1.93405,-1.6e-4 v 3.87356 l -7.75691,-0.0669 v -14.00001 z"
sodipodi:nodetypes="cccccccccccccccccccccccccc" />
</g>
<g
inkscape:groupmode="layer"

Before

Width:  |  Height:  |  Size: 2.5 MiB

After

Width:  |  Height:  |  Size: 2.5 MiB

View File

@ -1,15 +1,34 @@
#!/usr/bin/env python3
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# This script updates icons from the BLEND file
import os
import subprocess
import sys
def run(cmd):
def run(cmd, *, env=None):
print(" ", " ".join(cmd))
# Don't use check_call because asan causes nonzero exitcode :S
subprocess.call(cmd)
subprocess.check_call(cmd, env=env)
def edit_text_file(filename, marker_begin, marker_end, content):
@ -73,7 +92,17 @@ for blend in icons_blend:
"--group", "Export",
"--output-dir", output_dir,
)
run(cmd)
env = {}
# Developers may have ASAN enabled, avoid non-zero exit codes.
env["ASAN_OPTIONS"] = "exitcode=0:" + os.environ.get("ASAN_OPTIONS", "")
# These NEED to be set on windows for python to initialize properly.
if sys.platform[:3] == "win":
env["PATHEXT"] = os.environ.get("PATHEXT", "")
env["SystemDrive"] = os.environ.get("SystemDrive", "")
env["SystemRoot"] = os.environ.get("SystemRoot", "")
run(cmd, env=env)
files_new = set(names_and_time_from_path(output_dir))
icon_files.extend([

View File

@ -1,18 +1,48 @@
#!/usr/bin/env python3
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# This script updates icons from the SVG file
import os
import subprocess
import sys
def run(cmd):
def run(cmd, *, env=None):
print(" ", " ".join(cmd))
subprocess.check_call(cmd)
subprocess.check_call(cmd, env=env)
BASEDIR = os.path.abspath(os.path.dirname(__file__))
env = {}
# Developers may have ASAN enabled, avoid non-zero exit codes.
env["ASAN_OPTIONS"] = "exitcode=0:" + os.environ.get("ASAN_OPTIONS", "")
# These NEED to be set on windows for python to initialize properly.
if sys.platform[:3] == "win":
env["PATHEXT"] = os.environ.get("PATHEXT", "")
env["SystemDrive"] = os.environ.get("SystemDrive", "")
env["SystemRoot"] = os.environ.get("SystemRoot", "")
inkscape_bin = os.environ.get("INKSCAPE_BIN", "inkscape")
blender_bin = os.environ.get("BLENDER_BIN", "blender")
@ -32,7 +62,7 @@ cmd = (
"--export-type=png",
"--export-filename=" + os.path.join(BASEDIR, "blender_icons16.png"),
)
run(cmd)
run(cmd, env=env)
cmd = (
inkscape_bin,
@ -42,7 +72,7 @@ cmd = (
"--export-type=png",
"--export-filename=" + os.path.join(BASEDIR, "blender_icons32.png"),
)
run(cmd)
run(cmd, env=env)
# For testing it can be good to clear all old
@ -64,7 +94,7 @@ cmd = (
"--minx_icon", "2", "--maxx_icon", "2", "--miny_icon", "2", "--maxy_icon", "2",
"--spacex_icon", "1", "--spacey_icon", "1",
)
run(cmd)
run(cmd, env=env)
cmd = (
blender_bin, "--background", "--factory-startup", "-noaudio",
@ -78,7 +108,7 @@ cmd = (
"--minx_icon", "4", "--maxx_icon", "4", "--miny_icon", "4", "--maxy_icon", "4",
"--spacex_icon", "2", "--spacey_icon", "2",
)
run(cmd)
run(cmd, env=env)
os.remove(os.path.join(BASEDIR, "blender_icons16.png"))
os.remove(os.path.join(BASEDIR, "blender_icons32.png"))

View File

@ -1,27 +1,25 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ***** BEGIN GPL LICENSE BLOCK *****
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2009 Blender Foundation.
# All rights reserved.
#
# ***** END GPL LICENCE BLOCK *****
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>

View File

@ -1,5 +1,25 @@
#!/usr/bin/env python3
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# This script updates icons from the SVG file
import os
import subprocess
@ -7,15 +27,15 @@ import sys
BASEDIR = os.path.abspath(os.path.dirname(__file__))
inkscape_path = 'inkscape'
inkscape_bin = os.environ.get("INKSCAPE_BIN", "inkscape")
if sys.platform == 'darwin':
inkscape_app_path = '/Applications/Inkscape.app/Contents/MacOS/inkscape'
if os.path.exists(inkscape_app_path):
inkscape_path = inkscape_app_path
inkscape_bin = inkscape_app_path
cmd = (
inkscape_path,
inkscape_bin,
os.path.join(BASEDIR, "prvicons.svg"),
"--export-width=1792",
"--export-height=256",

View File

@ -3329,6 +3329,8 @@ def km_grease_pencil_stroke_edit_mode(params):
("gpencil.layer_isolate", {"type": 'NUMPAD_ASTERIX', "value": 'PRESS'}, None),
# Move to layer
op_menu("GPENCIL_MT_move_to_layer", {"type": 'M', "value": 'PRESS'}),
# Merge Layer
("gpencil.layer_merge", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None),
# Transform tools
("transform.translate", {"type": 'G', "value": 'PRESS'}, None),
("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None),
@ -3427,6 +3429,8 @@ def km_grease_pencil_stroke_paint_mode(params):
{"properties": [("unselected", True)]}),
# Active layer
op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}),
# Merge Layer
("gpencil.layer_merge", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None),
# Active material
op_menu("GPENCIL_MT_material_active", {"type": 'U', "value": 'PRESS'}),
# Keyframe menu
@ -3592,6 +3596,8 @@ def km_grease_pencil_stroke_sculpt_mode(params):
("gpencil.active_frames_delete_all", {"type": 'DEL', "value": 'PRESS', "shift": True}, None),
# Active layer
op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}),
# Merge Layer
("gpencil.layer_merge", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None),
# Keyframe menu
op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}),
# Context menu
@ -3809,6 +3815,8 @@ def km_grease_pencil_stroke_weight_mode(params):
("gpencil.active_frames_delete_all", {"type": 'DEL', "value": 'PRESS', "shift": True}, None),
# Active layer
op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}),
# Merge Layer
("gpencil.layer_merge", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None),
# Keyframe menu
op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}),
# Context menu
@ -3873,6 +3881,8 @@ def km_grease_pencil_stroke_vertex_mode(params):
("gpencil.active_frames_delete_all", {"type": 'DEL', "value": 'PRESS', "shift": True}, None),
# Active layer
op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}),
# Merge Layer
("gpencil.layer_merge", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None),
# Keyframe menu
op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}),
# Vertex Paint context menu

View File

@ -54,7 +54,7 @@ class AnnotationDrawingToolsPanel:
col.label(text="Stroke Placement:")
row = col.row(align=True)
row.prop_enum(tool_settings, "annotation_stroke_placement_view2d", 'VIEW')
row.prop_enum(tool_settings, "annotation_stroke_placement_view2d", 'CURSOR', text="Cursor")
row.prop_enum(tool_settings, "annotation_stroke_placement_view2d", 'IMAGE', text="Image")
class GreasePencilSculptOptionsPanel:

View File

@ -399,6 +399,10 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel):
col = layout.column(heading="Grease Pencil")
col.prop(ob, "use_grease_pencil_lights", toggle=False)
layout.separator()
col = layout.column(heading="Mask")
col.prop(ob, "is_holdout")
class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}

View File

@ -1269,6 +1269,12 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False)
if brush.gpencil_tool == 'TINT':
row = layout.row(align=True)
row.prop(gp_settings, "vertex_mode", text="Mode")
else:
row = layout.row(align=True)
if context.region.type == 'TOOL_HEADER':
row.prop(gp_settings, "caps_type", text="", expand=True)
else:
row.prop(gp_settings, "caps_type", text="Caps Type")
# FIXME: tools must use their own UI drawing!
if tool.idname in {

View File

@ -373,6 +373,7 @@ class FILEBROWSER_PT_advanced_filter(Panel):
def poll(cls, context):
# only useful in append/link (library) context currently...
return (
context.space_data.params and
context.space_data.params.use_library_browsing and
panel_poll_is_upper_region(context.region) and
not panel_poll_is_asset_browsing(context)
@ -383,19 +384,17 @@ class FILEBROWSER_PT_advanced_filter(Panel):
space = context.space_data
params = space.params
if params and params.use_library_browsing:
layout.prop(params, "use_filter_blendid")
if params.use_filter_blendid:
layout.separator()
col = layout.column(align=True)
layout.prop(params, "use_filter_blendid")
if params.use_filter_blendid:
layout.separator()
col = layout.column(align=True)
if context.preferences.experimental.use_asset_browser:
col.prop(params, "use_filter_asset_only")
col.prop(params, "use_filter_asset_only")
filter_id = params.filter_id
for identifier in dir(filter_id):
if identifier.startswith("filter_"):
col.prop(filter_id, identifier, toggle=True)
filter_id = params.filter_id
for identifier in dir(filter_id):
if identifier.startswith("filter_"):
col.prop(filter_id, identifier, toggle=True)
def is_option_region_visible(context, space):
@ -423,6 +422,10 @@ class FILEBROWSER_PT_directory_path(Panel):
return True
@classmethod
def poll(cls, context):
return context.space_data.params
def draw(self, context):
layout = self.layout
space = context.space_data

View File

@ -468,6 +468,9 @@ class TOPBAR_MT_file_import(Menu):
text="Collada (Default) (.dae)")
if bpy.app.build_options.alembic:
self.layout.operator("wm.alembic_import", text="Alembic (.abc)")
if bpy.app.build_options.usd:
self.layout.operator(
"wm.usd_import", text="Universal Scene Description (.usd, .usdc, .usda)")
self.layout.operator("wm.gpencil_import_svg", text="SVG as Grease Pencil")

View File

@ -6406,7 +6406,13 @@ class VIEW3D_PT_overlay_edit_mesh_normals(Panel):
sub = row.row(align=True)
sub.active = overlay.show_vertex_normals or overlay.show_face_normals or overlay.show_split_normals
sub.prop(overlay, "normals_length", text="Size")
if overlay.use_normals_constant_screen_size:
sub.prop(overlay, "normals_constant_screen_size", text="Size")
else:
sub.prop(overlay, "normals_length", text="Size")
row.prop(overlay, "use_normals_constant_screen_size", text="", icon='FIXED_SIZE')
class VIEW3D_PT_overlay_edit_mesh_freestyle(Panel):

View File

@ -510,6 +510,7 @@ geometry_node_categories = [
NodeItem("GeometryNodeCurveTrim"),
NodeItem("GeometryNodeCurveLength"),
NodeItem("GeometryNodeCurveReverse"),
NodeItem("GeometryNodeCurveSplineType"),
NodeItem("GeometryNodeCurveSetHandles"),
]),
GeometryNodeCategory("GEO_PRIMITIVES_CURVE", "Curve Primitives", items=[

View File

@ -1359,9 +1359,15 @@ FontBLF *blf_font_new(const char *name, const char *filename)
return NULL;
}
err = FT_Select_Charmap(font->face, ft_encoding_unicode);
err = FT_Select_Charmap(font->face, FT_ENCODING_UNICODE);
if (err) {
printf("Can't set the unicode character map!\n");
err = FT_Select_Charmap(font->face, FT_ENCODING_APPLE_ROMAN);
}
if (err && font->face->num_charmaps > 0) {
err = FT_Select_Charmap(font->face, font->face->charmaps[0]->encoding);
}
if (err) {
printf("Can't set a character map!\n");
FT_Done_Face(font->face);
MEM_freeN(font);
return NULL;

View File

@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 15
#define BLENDER_FILE_SUBVERSION 17
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file

View File

@ -197,13 +197,14 @@ typedef void (*BKE_scene_collections_Cb)(struct Collection *ob, void *data);
#define FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN(_collection, _object, _mode) \
{ \
int _base_flag = (_mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT : BASE_ENABLED_RENDER; \
int _object_restrict_flag = (_mode == DAG_EVAL_VIEWPORT) ? OB_RESTRICT_VIEWPORT : \
OB_RESTRICT_RENDER; \
int _object_visibility_flag = (_mode == DAG_EVAL_VIEWPORT) ? OB_HIDE_VIEWPORT : \
OB_HIDE_RENDER; \
int _base_id = 0; \
for (Base *_base = (Base *)BKE_collection_object_cache_get(_collection).first; _base; \
_base = _base->next, _base_id++) { \
Object *_object = _base->object; \
if ((_base->flag & _base_flag) && (_object->restrictflag & _object_restrict_flag) == 0) {
if ((_base->flag & _base_flag) && \
(_object->visibility_flag & _object_visibility_flag) == 0) {
#define FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END \
} \

View File

@ -70,6 +70,7 @@ typedef struct Global {
* * -16384 and below: Reserved for python (add-ons) usage.
* * -1: Disable faster motion paths computation (since 08/2018).
* * 1 - 30: EEVEE debug/stats values (01/2018).
* * 31: Enable the Select Debug Engine. Only available with #WITH_DRAW_DEBUG (08/2021).
* * 101: Enable UI debug drawing of fullscreen area's corner widget (10/2014).
* * 666: Use quicker batch delete for outliners' delete hierarchy (01/2019).
* * 777: Enable UI node panel's sockets polling (11/2011).

View File

@ -1475,6 +1475,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL 1070
#define GEO_NODE_CURVE_TRIM 1071
#define GEO_NODE_CURVE_SET_HANDLES 1072
#define GEO_NODE_CURVE_SPLINE_TYPE 1073
/** \} */

View File

@ -74,11 +74,13 @@ struct Ocean *BKE_ocean_add(void);
void BKE_ocean_free_data(struct Ocean *oc);
void BKE_ocean_free(struct Ocean *oc);
bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution);
void BKE_ocean_init_from_modifier(struct Ocean *ocean,
bool BKE_ocean_init_from_modifier(struct Ocean *ocean,
struct OceanModifierData const *omd,
const int resolution);
void BKE_ocean_init(struct Ocean *o,
bool BKE_ocean_is_valid(const struct Ocean *o);
bool BKE_ocean_init(struct Ocean *o,
int M,
int N,
float Lx,

View File

@ -302,7 +302,7 @@ void BKE_ptcache_remove(void);
/************ ID specific functions ************************/
void BKE_ptcache_id_clear(PTCacheID *id, int mode, unsigned int cfra);
int BKE_ptcache_id_exist(PTCacheID *id, int cfra);
bool BKE_ptcache_id_exist(PTCacheID *id, int cfra);
int BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *id, int mode);
void BKE_ptcache_id_time(PTCacheID *pid,
struct Scene *scene,

View File

@ -698,6 +698,13 @@ if(WITH_ALEMBIC)
add_definitions(-DWITH_ALEMBIC)
endif()
if(WITH_USD)
list(APPEND INC
../io/usd
)
add_definitions(-DWITH_USD)
endif()
if(WITH_OPENSUBDIV)
list(APPEND INC_SYS
${OPENSUBDIV_INCLUDE_DIRS}

View File

@ -426,7 +426,7 @@ bool BKE_animsys_rna_path_resolve(PointerRNA *ptr,
}
/* less than 1.0 evaluates to false, use epsilon to avoid float error */
#define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON)))
#define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > (1.0f - FLT_EPSILON))
bool BKE_animsys_read_from_rna_path(PathResolvedRNA *anim_rna, float *r_value)
{
@ -2625,7 +2625,7 @@ static void animsys_create_action_track_strip(const AnimData *adt,
bAction *action = adt->action;
if ((adt->flag & ADT_NLA_EDIT_ON)) {
if (adt->flag & ADT_NLA_EDIT_ON) {
action = adt->tmpact;
}

View File

@ -1882,7 +1882,7 @@ void BKE_bone_parent_transform_invert(struct BoneParentTransform *bpt)
{
invert_m4(bpt->rotscale_mat);
invert_m4(bpt->loc_mat);
invert_v3(bpt->post_scale);
invert_v3_safe(bpt->post_scale);
}
void BKE_bone_parent_transform_combine(const struct BoneParentTransform *in1,
@ -2663,7 +2663,7 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
}
}
/* printf("rebuild pose %s, %d bones\n", ob->id.name, counter); */
// printf("rebuild pose %s, %d bones\n", ob->id.name, counter);
/* synchronize protected layers with proxy */
/* HACK! To preserve 2.7x behavior that you always can pose even locked bones,

View File

@ -180,7 +180,7 @@ class BKE_armature_find_selected_bones_test : public testing::Test {
BLI_addtail(&arm.bonebase, &bone2); // bone2 is root bone
BLI_addtail(&bone2.childbase, &bone3); // bone3 has bone2 as parent
// Make sure the armature & its bones are visible, to make them selectable.
/* Make sure the armature & its bones are visible, to make them selectable. */
arm.layer = bone1.layer = bone2.layer = bone3.layer = 1;
}
};
@ -200,8 +200,8 @@ TEST_F(BKE_armature_find_selected_bones_test, some_bones_selected)
EXPECT_EQ(seen_bones[0], &bone1);
EXPECT_EQ(seen_bones[1], &bone3);
EXPECT_FALSE(result.all_bones_selected); // Bone 2 was not selected.
EXPECT_FALSE(result.no_bones_selected); // Bones 1 and 3 were selected.
EXPECT_FALSE(result.all_bones_selected); /* Bone 2 was not selected. */
EXPECT_FALSE(result.no_bones_selected); /* Bones 1 and 3 were selected. */
}
TEST_F(BKE_armature_find_selected_bones_test, no_bones_selected)

View File

@ -56,7 +56,7 @@ bool BKE_autoexec_match(const char *path)
if (path_cmp->path[0] == '\0') {
/* pass */
}
else if ((path_cmp->flag & USER_PATHCMP_GLOB)) {
else if (path_cmp->flag & USER_PATHCMP_GLOB) {
if (fnmatch(path_cmp->path, path, fnmatch_flags) == 0) {
return true;
}

View File

@ -55,6 +55,10 @@
# include "ABC_alembic.h"
#endif
#ifdef WITH_USD
# include "usd.h"
#endif
static void cachefile_handle_free(CacheFile *cache_file);
static void cache_file_init_data(ID *id)
@ -166,15 +170,30 @@ void BKE_cachefile_reader_open(CacheFile *cache_file,
Object *object,
const char *object_path)
{
#ifdef WITH_ALEMBIC
#if defined(WITH_ALEMBIC) || defined(WITH_USD)
BLI_assert(cache_file->id.tag & LIB_TAG_COPIED_ON_WRITE);
if (cache_file->handle == NULL) {
return;
}
/* Open Alembic cache reader. */
*reader = CacheReader_open_alembic_object(cache_file->handle, *reader, object, object_path);
switch (cache_file->type) {
case CACHEFILE_TYPE_ALEMBIC:
# ifdef WITH_ALEMBIC
/* Open Alembic cache reader. */
*reader = CacheReader_open_alembic_object(cache_file->handle, *reader, object, object_path);
# endif
break;
case CACHEFILE_TYPE_USD:
# ifdef WITH_USD
/* Open USD cache reader. */
*reader = CacheReader_open_usd_object(cache_file->handle, *reader, object, object_path);
# endif
break;
case CACHE_FILE_TYPE_INVALID:
break;
}
/* Multiple modifiers and constraints can call this function concurrently. */
BLI_spin_lock(&spin);
@ -197,16 +216,30 @@ void BKE_cachefile_reader_open(CacheFile *cache_file,
void BKE_cachefile_reader_free(CacheFile *cache_file, struct CacheReader **reader)
{
#ifdef WITH_ALEMBIC
#if defined(WITH_ALEMBIC) || defined(WITH_USD)
/* Multiple modifiers and constraints can call this function concurrently, and
* cachefile_handle_free() can also be called at the same time. */
BLI_spin_lock(&spin);
if (*reader != NULL) {
if (cache_file) {
BLI_assert(cache_file->id.tag & LIB_TAG_COPIED_ON_WRITE);
switch (cache_file->type) {
case CACHEFILE_TYPE_ALEMBIC:
# ifdef WITH_ALEMBIC
ABC_CacheReader_free(*reader);
# endif
break;
case CACHEFILE_TYPE_USD:
# ifdef WITH_USD
USD_CacheReader_free(*reader);
# endif
break;
case CACHE_FILE_TYPE_INVALID:
break;
}
}
CacheReader_free(*reader);
*reader = NULL;
if (cache_file && cache_file->handle_readers) {
@ -221,7 +254,8 @@ void BKE_cachefile_reader_free(CacheFile *cache_file, struct CacheReader **reade
static void cachefile_handle_free(CacheFile *cache_file)
{
#ifdef WITH_ALEMBIC
#if defined(WITH_ALEMBIC) || defined(WITH_USD)
/* Free readers in all modifiers and constraints that use the handle, before
* we free the handle itself. */
BLI_spin_lock(&spin);
@ -230,7 +264,21 @@ static void cachefile_handle_free(CacheFile *cache_file)
GSET_ITER (gs_iter, cache_file->handle_readers) {
struct CacheReader **reader = BLI_gsetIterator_getKey(&gs_iter);
if (*reader != NULL) {
CacheReader_free(*reader);
switch (cache_file->type) {
case CACHEFILE_TYPE_ALEMBIC:
# ifdef WITH_ALEMBIC
ABC_CacheReader_free(*reader);
# endif
break;
case CACHEFILE_TYPE_USD:
# ifdef WITH_USD
USD_CacheReader_free(*reader);
# endif
break;
case CACHE_FILE_TYPE_INVALID:
break;
}
*reader = NULL;
}
}
@ -242,7 +290,22 @@ static void cachefile_handle_free(CacheFile *cache_file)
/* Free handle. */
if (cache_file->handle) {
ABC_free_handle(cache_file->handle);
switch (cache_file->type) {
case CACHEFILE_TYPE_ALEMBIC:
# ifdef WITH_ALEMBIC
ABC_free_handle(cache_file->handle);
# endif
break;
case CACHEFILE_TYPE_USD:
# ifdef WITH_USD
USD_free_handle(cache_file->handle);
# endif
break;
case CACHE_FILE_TYPE_INVALID:
break;
}
cache_file->handle = NULL;
}
@ -289,8 +352,18 @@ void BKE_cachefile_eval(Main *bmain, Depsgraph *depsgraph, CacheFile *cache_file
BLI_freelistN(&cache_file->object_paths);
#ifdef WITH_ALEMBIC
cache_file->handle = ABC_create_handle(bmain, filepath, &cache_file->object_paths);
BLI_strncpy(cache_file->handle_filepath, filepath, FILE_MAX);
if (BLI_path_extension_check_glob(filepath, "*abc")) {
cache_file->type = CACHEFILE_TYPE_ALEMBIC;
cache_file->handle = ABC_create_handle(bmain, filepath, &cache_file->object_paths);
BLI_strncpy(cache_file->handle_filepath, filepath, FILE_MAX);
}
#endif
#ifdef WITH_USD
if (BLI_path_extension_check_glob(filepath, "*.usd;*.usda;*.usdc")) {
cache_file->type = CACHEFILE_TYPE_USD;
cache_file->handle = USD_create_handle(bmain, filepath, &cache_file->object_paths);
BLI_strncpy(cache_file->handle_filepath, filepath, FILE_MAX);
}
#endif
if (DEG_is_active(depsgraph)) {

View File

@ -806,10 +806,10 @@ static void collection_object_cache_fill(ListBase *lb,
/* Only collection flags are checked here currently, object restrict flag is checked
* in FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN since it can be animated
* without updating the cache. */
if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0)) {
if (((child_restrict & COLLECTION_HIDE_VIEWPORT) == 0)) {
base->flag |= BASE_ENABLED_VIEWPORT;
}
if (((child_restrict & COLLECTION_RESTRICT_RENDER) == 0)) {
if (((child_restrict & COLLECTION_HIDE_RENDER) == 0)) {
base->flag |= BASE_ENABLED_RENDER;
}
}
@ -1755,7 +1755,7 @@ static bool collection_objects_select(ViewLayer *view_layer, Collection *collect
{
bool changed = false;
if (collection->flag & COLLECTION_RESTRICT_SELECT) {
if (collection->flag & COLLECTION_HIDE_SELECT) {
return false;
}

View File

@ -95,6 +95,10 @@
# include "ABC_alembic.h"
#endif
#ifdef WITH_USD
# include "usd.h"
#endif
/* ---------------------------------------------------------------------------- */
/* Useful macros for testing various common flag combinations */
@ -4612,9 +4616,7 @@ static void splineik_free(bConstraint *con)
bSplineIKConstraint *data = con->data;
/* binding array */
if (data->points) {
MEM_freeN(data->points);
}
MEM_SAFE_FREE(data->points);
}
static void splineik_copy(bConstraint *con, bConstraint *srccon)
@ -5403,7 +5405,7 @@ static void transformcache_id_looper(bConstraint *con, ConstraintIDFunc func, vo
static void transformcache_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
{
#ifdef WITH_ALEMBIC
#if defined(WITH_ALEMBIC) || defined(WITH_USD)
bTransformCacheConstraint *data = con->data;
Scene *scene = cob->scene;
@ -5421,7 +5423,20 @@ static void transformcache_evaluate(bConstraint *con, bConstraintOb *cob, ListBa
BKE_cachefile_reader_open(cache_file, &data->reader, cob->ob, data->object_path);
}
ABC_get_transform(data->reader, cob->matrix, time, cache_file->scale);
switch (cache_file->type) {
case CACHEFILE_TYPE_ALEMBIC:
# ifdef WITH_ALEMBIC
ABC_get_transform(data->reader, cob->matrix, time, cache_file->scale);
# endif
break;
case CACHEFILE_TYPE_USD:
# ifdef WITH_USD
USD_get_transform(data->reader, cob->matrix, time * FPS, cache_file->scale);
# endif
break;
case CACHE_FILE_TYPE_INVALID:
break;
}
#else
UNUSED_VARS(con, cob);
#endif

View File

@ -861,7 +861,7 @@ static void get_effector_tot(
int totpart = eff->psys->totpart;
int amount = eff->psys->part->effector_amount;
*step = (totpart > amount) ? totpart / amount : 1;
*step = (totpart > amount) ? (int)ceil((float)totpart / (float)amount) : 1;
}
}
else {

View File

@ -4153,7 +4153,7 @@ static void BKE_fluid_modifier_process(
{
const int scene_framenr = (int)DEG_get_ctime(depsgraph);
if ((fmd->type & MOD_FLUID_TYPE_FLOW)) {
if (fmd->type & MOD_FLUID_TYPE_FLOW) {
BKE_fluid_modifier_processFlow(fmd, depsgraph, scene, ob, me, scene_framenr);
}
else if (fmd->type & MOD_FLUID_TYPE_EFFEC) {

View File

@ -337,13 +337,9 @@ VFont *BKE_vfont_load(Main *bmain, const char *filepath)
vfd = BLI_vfontdata_from_freetypefont(pf);
if (vfd) {
vfont = BKE_libblock_alloc(bmain, ID_VF, filename, 0);
/* If there's a font name, use it for the ID name. */
vfont = BKE_libblock_alloc(bmain, ID_VF, vfd->name[0] ? vfd->name : filename, 0);
vfont->data = vfd;
/* if there's a font name, use it for the ID name */
if (vfd->name[0] != '\0') {
BLI_strncpy(vfont->id.name + 2, vfd->name, sizeof(vfont->id.name) - 2);
}
BLI_strncpy(vfont->filepath, filepath, sizeof(vfont->filepath));
/* if autopack is on store the packedfile in de font structure */

View File

@ -602,7 +602,7 @@ static bool layer_collection_hidden(ViewLayer *view_layer, LayerCollection *lc)
}
/* Check visiblilty restriction flags */
if (lc->flag & LAYER_COLLECTION_HIDE || lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) {
if (lc->flag & LAYER_COLLECTION_HIDE || lc->collection->flag & COLLECTION_HIDE_VIEWPORT) {
return true;
}
@ -1005,22 +1005,22 @@ static void layer_collection_objects_sync(ViewLayer *view_layer,
BLI_addtail(r_lb_new_object_bases, base);
}
if ((collection_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) {
if ((collection_restrict & COLLECTION_HIDE_VIEWPORT) == 0) {
base->flag_from_collection |= (BASE_ENABLED_VIEWPORT | BASE_VISIBLE_DEPSGRAPH);
if ((layer_restrict & LAYER_COLLECTION_HIDE) == 0) {
base->flag_from_collection |= BASE_VISIBLE_VIEWLAYER;
}
if (((collection_restrict & COLLECTION_RESTRICT_SELECT) == 0)) {
if (((collection_restrict & COLLECTION_HIDE_SELECT) == 0)) {
base->flag_from_collection |= BASE_SELECTABLE;
}
}
if ((collection_restrict & COLLECTION_RESTRICT_RENDER) == 0) {
if ((collection_restrict & COLLECTION_HIDE_RENDER) == 0) {
base->flag_from_collection |= BASE_ENABLED_RENDER;
}
/* Holdout and indirect only */
if (layer->flag & LAYER_COLLECTION_HOLDOUT) {
if ((layer->flag & LAYER_COLLECTION_HOLDOUT) || (base->object->visibility_flag & OB_HOLDOUT)) {
base->flag_from_collection |= BASE_HOLDOUT;
}
if (layer->flag & LAYER_COLLECTION_INDIRECT_ONLY) {
@ -1150,11 +1150,11 @@ static void layer_collection_sync(ViewLayer *view_layer,
/* We separate restrict viewport and visible view layer because a layer collection can be
* hidden in the view layer yet (locally) visible in a viewport (if it is not restricted). */
if (child_collection_restrict & COLLECTION_RESTRICT_VIEWPORT) {
child_layer->runtime_flag |= LAYER_COLLECTION_RESTRICT_VIEWPORT;
if (child_collection_restrict & COLLECTION_HIDE_VIEWPORT) {
child_layer->runtime_flag |= LAYER_COLLECTION_HIDE_VIEWPORT;
}
if (((child_layer->runtime_flag & LAYER_COLLECTION_RESTRICT_VIEWPORT) == 0) &&
if (((child_layer->runtime_flag & LAYER_COLLECTION_HIDE_VIEWPORT) == 0) &&
((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0)) {
child_layer->runtime_flag |= LAYER_COLLECTION_VISIBLE_VIEW_LAYER;
}
@ -1333,7 +1333,7 @@ void BKE_main_collection_sync_remap(const Main *bmain)
*/
bool BKE_layer_collection_objects_select(ViewLayer *view_layer, LayerCollection *lc, bool deselect)
{
if (lc->collection->flag & COLLECTION_RESTRICT_SELECT) {
if (lc->collection->flag & COLLECTION_HIDE_SELECT) {
return false;
}
@ -1369,7 +1369,7 @@ bool BKE_layer_collection_objects_select(ViewLayer *view_layer, LayerCollection
bool BKE_layer_collection_has_selected_objects(ViewLayer *view_layer, LayerCollection *lc)
{
if (lc->collection->flag & COLLECTION_RESTRICT_SELECT) {
if (lc->collection->flag & COLLECTION_HIDE_SELECT) {
return false;
}
@ -1457,7 +1457,7 @@ bool BKE_object_is_visible_in_viewport(const View3D *v3d, const struct Object *o
{
BLI_assert(v3d != NULL);
if (ob->restrictflag & OB_RESTRICT_VIEWPORT) {
if (ob->visibility_flag & OB_HIDE_VIEWPORT) {
return false;
}
@ -2146,14 +2146,14 @@ void BKE_base_eval_flags(Base *base)
base->flag |= (base->flag_from_collection & g_base_collection_flags);
/* Apply object restrictions. */
const int object_restrict = base->object->restrictflag;
if (object_restrict & OB_RESTRICT_VIEWPORT) {
const int object_restrict = base->object->visibility_flag;
if (object_restrict & OB_HIDE_VIEWPORT) {
base->flag &= ~BASE_ENABLED_VIEWPORT;
}
if (object_restrict & OB_RESTRICT_RENDER) {
if (object_restrict & OB_HIDE_RENDER) {
base->flag &= ~BASE_ENABLED_RENDER;
}
if (object_restrict & OB_RESTRICT_SELECT) {
if (object_restrict & OB_HIDE_SELECT) {
base->flag &= ~BASE_SELECTABLE;
}

View File

@ -73,6 +73,7 @@
#include "BKE_rigidbody.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "RNA_access.h"
@ -141,7 +142,8 @@ static int lib_id_clear_library_data_users_update_cb(LibraryIDLinkCallbackData *
{
ID *id = cb_data->user_data;
if (*cb_data->id_pointer == id) {
DEG_id_tag_update_ex(cb_data->bmain, cb_data->id_owner, ID_RECALC_TAG_FOR_UNDO);
DEG_id_tag_update_ex(
cb_data->bmain, cb_data->id_owner, ID_RECALC_TAG_FOR_UNDO | ID_RECALC_COPY_ON_WRITE);
return IDWALK_RET_STOP_ITER;
}
return IDWALK_RET_NOP;
@ -193,6 +195,8 @@ static void lib_id_clear_library_data_ex(Main *bmain, ID *id)
if (key != NULL) {
lib_id_clear_library_data_ex(bmain, &key->id);
}
DEG_relations_tag_update(bmain);
}
void BKE_lib_id_clear_library_data(Main *bmain, ID *id)

View File

@ -571,7 +571,7 @@ static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *dat
* would use one of those.
* NOTE: missing IDs (aka placeholders) are never overridden. */
if (ELEM(GS(to_id->name), ID_OB, ID_GR)) {
if ((to_id->tag & LIB_TAG_MISSING)) {
if (to_id->tag & LIB_TAG_MISSING) {
to_id->tag |= missing_tag;
}
else {
@ -604,7 +604,7 @@ static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
const bool is_resync = data->is_resync;
BLI_assert(!data->is_override);
if ((id_root->tag & LIB_TAG_MISSING)) {
if (id_root->tag & LIB_TAG_MISSING) {
id_root->tag |= data->missing_tag;
}
else {
@ -654,7 +654,7 @@ static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
if (instantiating_collection == NULL &&
instantiating_collection_override_candidate != NULL) {
if ((instantiating_collection_override_candidate->id.tag & LIB_TAG_MISSING)) {
if (instantiating_collection_override_candidate->id.tag & LIB_TAG_MISSING) {
instantiating_collection_override_candidate->id.tag |= data->missing_tag;
}
else {
@ -730,7 +730,7 @@ static void lib_override_overrides_group_tag(LibOverrideGroupTagData *data)
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root));
BLI_assert(data->is_override);
if ((id_root->override_library->reference->tag & LIB_TAG_MISSING)) {
if (id_root->override_library->reference->tag & LIB_TAG_MISSING) {
id_root->tag |= data->missing_tag;
}
else {
@ -855,8 +855,8 @@ static void lib_override_library_create_post_process(Main *bmain,
default_instantiating_collection = BKE_collection_add(
bmain, (Collection *)id_root, "OVERRIDE_HIDDEN");
/* Hide the collection from viewport and render. */
default_instantiating_collection->flag |= COLLECTION_RESTRICT_VIEWPORT |
COLLECTION_RESTRICT_RENDER;
default_instantiating_collection->flag |= COLLECTION_HIDE_VIEWPORT |
COLLECTION_HIDE_RENDER;
break;
}
case ID_OB: {
@ -1599,6 +1599,17 @@ static void lib_override_library_main_resync_on_library_indirect_level(
(!ID_IS_LINKED(id) && library_indirect_level != 0)) {
continue;
}
/* We cannot resync a scene that is currently active. */
if (id == &scene->id) {
id->tag &= ~LIB_TAG_LIB_OVERRIDE_NEED_RESYNC;
BKE_reportf(reports->reports,
RPT_WARNING,
"Scene '%s' was not resynced as it is the currently active one",
scene->id.name + 2);
continue;
}
Library *library = id->lib;
int level = 0;
@ -1731,8 +1742,7 @@ void BKE_lib_override_library_main_resync(Main *bmain,
override_resync_residual_storage = BKE_collection_add(
bmain, scene->master_collection, OVERRIDE_RESYNC_RESIDUAL_STORAGE_NAME);
/* Hide the collection from viewport and render. */
override_resync_residual_storage->flag |= COLLECTION_RESTRICT_VIEWPORT |
COLLECTION_RESTRICT_RENDER;
override_resync_residual_storage->flag |= COLLECTION_HIDE_VIEWPORT | COLLECTION_HIDE_RENDER;
}
/* Necessary to improve performances, and prevent layers matching override sub-collections to be

View File

@ -429,7 +429,7 @@ MaskLayer *BKE_mask_layer_copy(const MaskLayer *masklay)
masklay_new->blend_flag = masklay->blend_flag;
masklay_new->flag = masklay->flag;
masklay_new->falloff = masklay->falloff;
masklay_new->restrictflag = masklay->restrictflag;
masklay_new->visibility_flag = masklay->visibility_flag;
for (spline = masklay->splines.first; spline; spline = spline->next) {
MaskSpline *spline_new = BKE_mask_spline_copy(spline);
@ -2092,7 +2092,7 @@ void BKE_mask_clipboard_copy_from_layer(MaskLayer *mask_layer)
MaskSpline *spline;
/* Nothing to do if selection if disabled for the given layer. */
if (mask_layer->restrictflag & MASK_RESTRICT_SELECT) {
if (mask_layer->visibility_flag & MASK_HIDE_SELECT) {
return;
}

View File

@ -106,7 +106,7 @@
/* for debugging add... */
#ifndef NDEBUG
/* printf("%u %u %u %u\n", _t[0], _t[1], _t[2], _t[3]); \ */
// printf("%u %u %u %u\n", _t[0], _t[1], _t[2], _t[3]);
# define FACE_ASSERT(face, vert_max) \
{ \
unsigned int *_t = face; \
@ -619,7 +619,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
unsigned int tot_boundary_found = 0;
#endif
if (masklay->restrictflag & MASK_RESTRICT_RENDER) {
if (masklay->visibility_flag & MASK_HIDE_RENDER) {
/* skip the layer */
mr_handle->layers_tot--;
masklay_index--;
@ -1213,7 +1213,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
layer->falloff = masklay->falloff;
}
/* printf("tris %d, feather tris %d\n", sf_tri_tot, tot_feather_quads); */
// printf("tris %d, feather tris %d\n", sf_tri_tot, tot_feather_quads);
}
/* add trianges */

View File

@ -987,7 +987,7 @@ void BKE_edges_sharp_from_angle_set(const struct MVert *mverts,
/* Simple mapping from a loop to its polygon index. */
int *loop_to_poly = (int *)MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
LoopSplitTaskDataCommon common_data;
LoopSplitTaskDataCommon common_data = {};
common_data.mverts = mverts;
common_data.medges = medges;
common_data.mloops = mloops;
@ -1195,7 +1195,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli
}
}
// printf("FAN: vert %d, start edge %d\n", mv_pivot_index, ml_curr->e);
// printf("FAN: vert %d, start edge %d\n", mv_pivot_index, ml_curr->e);
while (true) {
const MEdge *me_curr = &medges[mlfan_curr->e];
@ -1212,7 +1212,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli
normalize_v3(vec_curr);
}
// printf("\thandling edge %d / loop %d\n", mlfan_curr->e, mlfan_curr_index);
// printf("\thandling edge %d / loop %d\n", mlfan_curr->e, mlfan_curr_index);
{
/* Code similar to accumulate_vertex_normals_poly_v3. */
@ -1252,9 +1252,8 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli
if (IS_EDGE_SHARP(e2lfan_curr) || (me_curr == me_org)) {
/* Current edge is sharp and we have finished with this fan of faces around this vert,
* or this vert is smooth, and we have completed a full turn around it.
*/
// printf("FAN: Finished!\n");
* or this vert is smooth, and we have completed a full turn around it. */
// printf("FAN: Finished!\n");
break;
}
@ -1537,12 +1536,12 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common
ml_curr_index,
ml_prev_index,
mp_index))) {
// printf("SKIPPING!\n");
// printf("SKIPPING!\n");
}
else {
LoopSplitTaskData *data, data_local;
// printf("PROCESSING!\n");
// printf("PROCESSING!\n");
if (pool) {
if (data_idx == 0) {

View File

@ -294,7 +294,7 @@ Mesh *BKE_mesh_remesh_voxel(const Mesh *mesh,
void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, Mesh *source)
{
BVHTreeFromMesh bvhtree = {{nullptr}};
BVHTreeFromMesh bvhtree = {nullptr};
BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2);
MVert *target_verts = (MVert *)CustomData_get_layer(&target->vdata, CD_MVERT);
@ -405,7 +405,7 @@ void BKE_mesh_remesh_sculpt_array_update(Object *ob, Mesh *target, Mesh *source)
void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, Mesh *source)
{
BVHTreeFromMesh bvhtree = {{nullptr}};
BVHTreeFromMesh bvhtree = {nullptr};
const MPoly *target_polys = (const MPoly *)CustomData_get_layer(&target->pdata, CD_MPOLY);
const MVert *target_verts = (const MVert *)CustomData_get_layer(&target->vdata, CD_MVERT);
@ -480,7 +480,7 @@ void BKE_remesh_reproject_materials(Mesh *target, Mesh *source)
void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
{
BVHTreeFromMesh bvhtree = {{nullptr}};
BVHTreeFromMesh bvhtree = {nullptr};
BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2);
int tot_color_layer = CustomData_number_of_layers(&source->vdata, CD_PROP_COLOR);

View File

@ -5149,6 +5149,7 @@ static void registerGeometryNodes()
register_node_type_geo_curve_resample();
register_node_type_geo_curve_reverse();
register_node_type_geo_curve_set_handles();
register_node_type_geo_curve_spline_type();
register_node_type_geo_curve_subdivide();
register_node_type_geo_curve_to_mesh();
register_node_type_geo_curve_to_points();

View File

@ -144,6 +144,7 @@
#include "DRW_engine.h"
#include "BLO_read_write.h"
#include "BLO_readfile.h"
#include "SEQ_sequencer.h"
@ -833,7 +834,7 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
{
Object *ob = (Object *)id;
bool warn = false;
BlendFileReadReport *reports = BLO_read_lib_reports(reader);
/* XXX deprecated - old animation system <<< */
BLO_read_id_address(reader, ob->id.lib, &ob->ipo);
@ -851,8 +852,8 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
else {
if (ob->instance_collection != NULL) {
ID *new_id = BLO_read_get_new_id_address(reader, ob->id.lib, &ob->instance_collection->id);
BLO_reportf_wrap(BLO_read_lib_reports(reader),
RPT_WARNING,
BLO_reportf_wrap(reports,
RPT_INFO,
TIP_("Non-Empty object '%s' cannot duplicate collection '%s' "
"anymore in Blender 2.80, removed instancing"),
ob->id.name + 2,
@ -870,11 +871,17 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
ob->proxy = NULL;
if (ob->id.lib) {
printf("Proxy lost from object %s lib %s\n", ob->id.name + 2, ob->id.lib->filepath);
BLO_reportf_wrap(reports,
RPT_INFO,
TIP_("Proxy lost from object %s lib %s\n"),
ob->id.name + 2,
ob->id.lib->filepath);
}
else {
printf("Proxy lost from object %s lib <NONE>\n", ob->id.name + 2);
BLO_reportf_wrap(
reports, RPT_INFO, TIP_("Proxy lost from object %s lib <NONE>\n"), ob->id.name + 2);
}
reports->count.missing_obproxies++;
}
else {
/* this triggers object_update to always use a copy */
@ -887,15 +894,7 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
BLO_read_id_address(reader, ob->id.lib, &ob->data);
if (ob->data == NULL && poin != NULL) {
if (ob->id.lib) {
printf("Can't find obdata of %s lib %s\n", ob->id.name + 2, ob->id.lib->filepath);
}
else {
printf("Object %s lost data.\n", ob->id.name + 2);
}
ob->type = OB_EMPTY;
warn = true;
if (ob->pose) {
/* we can't call #BKE_pose_free() here because of library linking
@ -911,6 +910,18 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
ob->pose = NULL;
ob->mode &= ~OB_MODE_POSE;
}
if (ob->id.lib) {
BLO_reportf_wrap(reports,
RPT_INFO,
TIP_("Can't find obdata of %s lib %s\n"),
ob->id.name + 2,
ob->id.lib->filepath);
}
else {
BLO_reportf_wrap(reports, RPT_INFO, TIP_("Object %s lost data\n"), ob->id.name + 2);
}
reports->count.missing_obdata++;
}
for (int a = 0; a < ob->totcol; a++) {
BLO_read_id_address(reader, ob->id.lib, &ob->mat[a]);
@ -922,7 +933,7 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
const short *totcol_data = BKE_object_material_len_p(ob);
/* Only expand so as not to lose any object materials that might be set. */
if (totcol_data && (*totcol_data > ob->totcol)) {
/* printf("'%s' %d -> %d\n", ob->id.name, ob->totcol, *totcol_data); */
// printf("'%s' %d -> %d\n", ob->id.name, ob->totcol, *totcol_data);
BKE_object_material_resize(BLO_read_lib_get_main(reader), ob, *totcol_data, false);
}
}
@ -992,10 +1003,6 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
BLO_read_id_address(reader, ob->id.lib, &ob->rigidbody_constraint->ob1);
BLO_read_id_address(reader, ob->id.lib, &ob->rigidbody_constraint->ob2);
}
if (warn) {
BLO_reportf_wrap(BLO_read_lib_reports(reader), RPT_WARNING, "Warning in console");
}
}
/* XXX deprecated - old animation system */
@ -2074,6 +2081,12 @@ static void object_init(Object *ob, const short ob_type)
if (ob->type == OB_GPENCIL) {
ob->dtx |= OB_USE_GPENCIL_LIGHTS;
}
if (ob->type == OB_LAMP) {
/* Lights are invisible to camera rays and are assumed to be a
* shadow catcher by default. */
ob->visibility_flag |= OB_HIDE_CAMERA | OB_SHADOW_CATCHER;
}
}
void *BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name)

View File

@ -1554,15 +1554,15 @@ static const DupliGenerator gen_dupli_particles = {
static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
{
int transflag = ctx->object->transflag;
int restrictflag = ctx->object->restrictflag;
int visibility_flag = ctx->object->visibility_flag;
if ((transflag & OB_DUPLI) == 0 && ctx->object->runtime.geometry_set_eval == nullptr) {
return nullptr;
}
/* Should the dupli's be generated for this object? - Respect restrict flags. */
if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER ? (restrictflag & OB_RESTRICT_RENDER) :
(restrictflag & OB_RESTRICT_VIEWPORT)) {
if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER ? (visibility_flag & OB_HIDE_RENDER) :
(visibility_flag & OB_HIDE_VIEWPORT)) {
return nullptr;
}

View File

@ -650,6 +650,14 @@ static void ocean_compute_normal_z(TaskPool *__restrict pool, void *UNUSED(taskd
fftw_execute(o->_N_z_plan);
}
/**
* Return true if the ocean is valid and can be used.
*/
bool BKE_ocean_is_valid(const struct Ocean *o)
{
return o->_k != NULL;
}
void BKE_ocean_simulate(struct Ocean *o, float t, float scale, float chop_amount)
{
TaskPool *pool;
@ -769,7 +777,10 @@ bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution)
return true;
}
void BKE_ocean_init_from_modifier(struct Ocean *ocean,
/**
* Return true if the ocean data is valid and can be used.
*/
bool BKE_ocean_init_from_modifier(struct Ocean *ocean,
struct OceanModifierData const *omd,
const int resolution)
{
@ -783,31 +794,34 @@ void BKE_ocean_init_from_modifier(struct Ocean *ocean,
BKE_ocean_free_data(ocean);
BKE_ocean_init(ocean,
resolution * resolution,
resolution * resolution,
omd->spatial_size,
omd->spatial_size,
omd->wind_velocity,
omd->smallest_wave,
1.0,
omd->wave_direction,
omd->damp,
omd->wave_alignment,
omd->depth,
omd->time,
omd->spectrum,
omd->fetch_jonswap,
omd->sharpen_peak_jonswap,
do_heightfield,
do_chop,
do_spray,
do_normals,
do_jacobian,
omd->seed);
return BKE_ocean_init(ocean,
resolution * resolution,
resolution * resolution,
omd->spatial_size,
omd->spatial_size,
omd->wind_velocity,
omd->smallest_wave,
1.0,
omd->wave_direction,
omd->damp,
omd->wave_alignment,
omd->depth,
omd->time,
omd->spectrum,
omd->fetch_jonswap,
omd->sharpen_peak_jonswap,
do_heightfield,
do_chop,
do_spray,
do_normals,
do_jacobian,
omd->seed);
}
void BKE_ocean_init(struct Ocean *o,
/**
* Return true if the ocean data is valid and can be used.
*/
bool BKE_ocean_init(struct Ocean *o,
int M,
int N,
float Lx,
@ -830,7 +844,6 @@ void BKE_ocean_init(struct Ocean *o,
short do_jacobian,
int seed)
{
RNG *rng;
int i, j, ii;
BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);
@ -858,18 +871,34 @@ void BKE_ocean_init(struct Ocean *o,
o->_fetch_jonswap = fetch_jonswap;
o->_sharpen_peak_jonswap = sharpen_peak_jonswap * 10.0f;
/* NOTE: most modifiers don't account for failure to allocate.
* In this case however a large resolution can easily perform large allocations that fail,
* support early exiting in this case. */
if ((o->_k = (float *)MEM_mallocN(sizeof(float) * (size_t)M * (1 + N / 2), "ocean_k")) &&
(o->_h0 = (fftw_complex *)MEM_mallocN(sizeof(fftw_complex) * (size_t)M * N, "ocean_h0")) &&
(o->_h0_minus = (fftw_complex *)MEM_mallocN(sizeof(fftw_complex) * (size_t)M * N,
"ocean_h0_minus")) &&
(o->_kx = (float *)MEM_mallocN(sizeof(float) * o->_M, "ocean_kx")) &&
(o->_kz = (float *)MEM_mallocN(sizeof(float) * o->_N, "ocean_kz"))) {
/* Success. */
}
else {
MEM_SAFE_FREE(o->_k);
MEM_SAFE_FREE(o->_h0);
MEM_SAFE_FREE(o->_h0_minus);
MEM_SAFE_FREE(o->_kx);
MEM_SAFE_FREE(o->_kz);
BLI_rw_mutex_unlock(&o->oceanmutex);
return false;
}
o->_do_disp_y = do_height_field;
o->_do_normals = do_normals;
o->_do_spray = do_spray;
o->_do_chop = do_chop;
o->_do_jacobian = do_jacobian;
o->_k = (float *)MEM_mallocN(M * (1 + N / 2) * sizeof(float), "ocean_k");
o->_h0 = (fftw_complex *)MEM_mallocN(M * N * sizeof(fftw_complex), "ocean_h0");
o->_h0_minus = (fftw_complex *)MEM_mallocN(M * N * sizeof(fftw_complex), "ocean_h0_minus");
o->_kx = (float *)MEM_mallocN(o->_M * sizeof(float), "ocean_kx");
o->_kz = (float *)MEM_mallocN(o->_N * sizeof(float), "ocean_kz");
/* make this robust in the face of erroneous usage */
if (o->_Lx == 0.0f) {
o->_Lx = 0.001f;
@ -902,11 +931,11 @@ void BKE_ocean_init(struct Ocean *o,
/* pre-calculate the k matrix */
for (i = 0; i < o->_M; i++) {
for (j = 0; j <= o->_N / 2; j++) {
o->_k[i * (1 + o->_N / 2) + j] = sqrt(o->_kx[i] * o->_kx[i] + o->_kz[j] * o->_kz[j]);
o->_k[(size_t)i * (1 + o->_N / 2) + j] = sqrt(o->_kx[i] * o->_kx[i] + o->_kz[j] * o->_kz[j]);
}
}
rng = BLI_rng_new(seed);
RNG *rng = BLI_rng_new(seed);
for (i = 0; i < o->_M; i++) {
for (j = 0; j < o->_N; j++) {
@ -1029,6 +1058,8 @@ void BKE_ocean_init(struct Ocean *o,
set_height_normalize_factor(o);
BLI_rng_free(rng);
return true;
}
void BKE_ocean_free_data(struct Ocean *oc)
@ -1608,7 +1639,7 @@ struct Ocean *BKE_ocean_add(void)
return oc;
}
void BKE_ocean_init(struct Ocean *UNUSED(o),
bool BKE_ocean_init(struct Ocean *UNUSED(o),
int UNUSED(M),
int UNUSED(N),
float UNUSED(Lx),
@ -1631,6 +1662,7 @@ void BKE_ocean_init(struct Ocean *UNUSED(o),
short UNUSED(do_jacobian),
int UNUSED(seed))
{
return false;
}
void BKE_ocean_free_data(struct Ocean *UNUSED(oc))
@ -1700,10 +1732,11 @@ void BKE_ocean_bake(struct Ocean *UNUSED(o),
(void)update_cb;
}
void BKE_ocean_init_from_modifier(struct Ocean *UNUSED(ocean),
bool BKE_ocean_init_from_modifier(struct Ocean *UNUSED(ocean),
struct OceanModifierData const *UNUSED(omd),
int UNUSED(resolution))
{
return true;
}
#endif /* WITH_OCEANSIM */

View File

@ -3112,7 +3112,7 @@ static void collision_fail(ParticleData *pa, ParticleCollision *col)
copy_v3_v3(pa->state.vel, col->pce.vel);
mul_v3_fl(pa->state.vel, col->inv_timestep);
/* printf("max iterations\n"); */
// printf("max iterations\n");
}
/* Particle - Mesh collision detection and response

View File

@ -1026,7 +1026,7 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata,
PBVHNode *node = data->nodes[n];
float(*vnors)[3] = data->vnors;
if ((node->flag & PBVH_UpdateNormals)) {
if (node->flag & PBVH_UpdateNormals) {
unsigned int mpoly_prev = UINT_MAX;
float fn[3];

View File

@ -2753,18 +2753,18 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
pid->cache->flag |= PTCACHE_FLAG_INFO_DIRTY;
}
int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
bool BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
{
if (!pid->cache) {
return 0;
return false;
}
if (cfra < pid->cache->startframe || cfra > pid->cache->endframe) {
return 0;
return false;
}
if (pid->cache->cached_frames && pid->cache->cached_frames[cfra - pid->cache->startframe] == 0) {
return 0;
return false;
}
if (pid->cache->flag & PTCACHE_DISK_CACHE) {
@ -2779,10 +2779,10 @@ int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
for (; pm; pm = pm->next) {
if (pm->frame == cfra) {
return 1;
return true;
}
}
return 0;
return false;
}
void BKE_ptcache_id_time(
PTCacheID *pid, Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
@ -3369,7 +3369,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
}
/* NOTE: breaking baking should leave calculated frames in cache, not clear it */
if ((cancel || G.is_break)) {
if (cancel || G.is_break) {
break;
}

View File

@ -2178,7 +2178,7 @@ int BKE_scene_base_iter_next(
/* exception: empty scene layer */
while ((*scene)->set) {
(*scene) = (*scene)->set;
ViewLayer *view_layer_set = BKE_view_layer_default_render((*scene));
ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene);
if (view_layer_set->object_bases.first) {
*base = view_layer_set->object_bases.first;
*ob = (*base)->object;
@ -2199,7 +2199,7 @@ int BKE_scene_base_iter_next(
/* (*scene) is finished, now do the set */
while ((*scene)->set) {
(*scene) = (*scene)->set;
ViewLayer *view_layer_set = BKE_view_layer_default_render((*scene));
ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene);
if (view_layer_set->object_bases.first) {
*base = view_layer_set->object_bases.first;
*ob = (*base)->object;
@ -2305,7 +2305,7 @@ Object *BKE_scene_camera_switch_find(Scene *scene)
Object *first_camera = NULL;
LISTBASE_FOREACH (TimeMarker *, m, &scene->markers) {
if (m->camera && (m->camera->restrictflag & OB_RESTRICT_RENDER) == 0) {
if (m->camera && (m->camera->visibility_flag & OB_HIDE_RENDER) == 0) {
if ((m->frame <= ctime) && (m->frame > frame)) {
camera = m->camera;
frame = m->frame;
@ -2898,7 +2898,7 @@ Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
next_set:
/* Reached the end, get the next base in the set. */
while ((*sce_iter = (*sce_iter)->set)) {
ViewLayer *view_layer_set = BKE_view_layer_default_render((*sce_iter));
ViewLayer *view_layer_set = BKE_view_layer_default_render(*sce_iter);
base = (Base *)view_layer_set->object_bases.first;
if (base) {
@ -3118,7 +3118,7 @@ bool BKE_scene_multiview_is_render_view_active(const RenderData *rd, const Scene
return false;
}
if ((srv->viewflag & SCE_VIEW_DISABLE)) {
if (srv->viewflag & SCE_VIEW_DISABLE) {
return false;
}

View File

@ -766,7 +766,7 @@ void BKE_screen_remove_double_scrverts(bScreen *screen)
while (v1) {
if (v1->newv == NULL) { /* !?! */
if (v1->vec.x == verg->vec.x && v1->vec.y == verg->vec.y) {
/* printf("doublevert\n"); */
// printf("doublevert\n");
v1->newv = verg;
}
}

View File

@ -2225,7 +2225,7 @@ static void sb_cf_threads_run(Scene *scene,
totthread--;
}
/* printf("sb_cf_threads_run spawning %d threads\n", totthread); */
// printf("sb_cf_threads_run spawning %d threads\n", totthread);
sb_threads = MEM_callocN(sizeof(SB_thread_context) * totthread, "SBThread");
memset(sb_threads, 0, sizeof(SB_thread_context) * totthread);
@ -2812,7 +2812,7 @@ static void reference_to_scratch(Object *ob)
}
mul_v3_fl(accu_pos, 1.0f / accu_mass);
copy_v3_v3(sb->scratch->Ref.com, accu_pos);
/* printf("reference_to_scratch\n"); */
// printf("reference_to_scratch\n");
}
/*
@ -3447,10 +3447,10 @@ static void softbody_step(
float newtime = forcetime * 1.1f; /* hope for 1.1 times better conditions in next step */
if (sb->scratch->flag & SBF_DOFUZZY) {
///* stay with this stepsize unless err really small */
// /* stay with this stepsize unless err really small */
// if (err > SoftHeunTol/(2.0f*sb->fuzzyness)) {
newtime = forcetime;
//}
// }
}
else {
if (err > SoftHeunTol / 2.0f) { /* stay with this stepsize unless err really small */

View File

@ -189,7 +189,11 @@ static float3 direction_bisect(const float3 &prev, const float3 &middle, const f
const float3 dir_prev = (middle - prev).normalized();
const float3 dir_next = (next - middle).normalized();
return (dir_prev + dir_next).normalized();
const float3 result = (dir_prev + dir_next).normalized();
if (UNLIKELY(result.is_zero())) {
return float3(0.0f, 0.0f, 1.0f);
}
return result;
}
static void calculate_tangents(Span<float3> positions,
@ -197,6 +201,7 @@ static void calculate_tangents(Span<float3> positions,
MutableSpan<float3> tangents)
{
if (positions.size() == 1) {
tangents.first() = float3(0.0f, 0.0f, 1.0f);
return;
}
@ -237,13 +242,8 @@ Span<float3> Spline::evaluated_tangents() const
Span<float3> positions = this->evaluated_positions();
if (eval_size == 1) {
evaluated_tangents_cache_.first() = float3(1.0f, 0.0f, 0.0f);
}
else {
calculate_tangents(positions, is_cyclic_, evaluated_tangents_cache_);
this->correct_end_tangents();
}
calculate_tangents(positions, is_cyclic_, evaluated_tangents_cache_);
this->correct_end_tangents();
tangent_cache_dirty_ = false;
return evaluated_tangents_cache_;

Some files were not shown because too many files have changed in this diff Show More