Merge remote-tracking branch 'origin' into sculpt-dev

This commit is contained in:
Joseph Eagar 2022-05-26 13:45:19 -07:00
commit 4c3d11c233
810 changed files with 16657 additions and 9522 deletions

View File

@ -774,6 +774,7 @@ endif()
set_and_warn_dependency(WITH_PYTHON WITH_CYCLES OFF)
set_and_warn_dependency(WITH_PYTHON WITH_DRACO OFF)
set_and_warn_dependency(WITH_PYTHON WITH_MOD_FLUID OFF)
if(WITH_DRACO AND NOT WITH_PYTHON_INSTALL)
message(STATUS "WITH_DRACO requires WITH_PYTHON_INSTALL to be ON, disabling WITH_DRACO for now")
@ -946,7 +947,10 @@ set(PLATFORM_CFLAGS)
set(C_WARNINGS)
set(CXX_WARNINGS)
# for gcc -Wno-blah-blah
# NOTE: These flags are intended for situations where where it's impractical to
# suppress warnings by modifying the code or for code which is maintained externally.
# For GCC this typically means adding `-Wno-*` arguments to negate warnings
# that are useful in the general case.
set(C_REMOVE_STRICT_FLAGS)
set(CXX_REMOVE_STRICT_FLAGS)
@ -1626,6 +1630,18 @@ if(CMAKE_COMPILER_IS_GNUCC)
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_IMPLICIT_FALLTHROUGH -Wimplicit-fallthrough=5)
endif()
#----------------------
# Suppress Strict Flags
#
# Exclude the following warnings from this list:
# - `-Wno-address`:
# This can give useful hints that point to bugs/misleading logic.
# - `-Wno-strict-prototypes`:
# No need to support older C-style prototypes.
#
# If code in `./extern/` needs to suppress these flags that can be done on a case-by-case basis.
# flags to undo strict flags
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
@ -1681,6 +1697,9 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_MACROS -Wunused-macros)
# ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNUSED_MACROS -Wunused-macros)
#----------------------
# Suppress Strict Flags
# flags to undo strict flags
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
@ -1746,6 +1765,7 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC")
"/wd4828" # The file contains a character that is illegal
"/wd4996" # identifier was declared deprecated
"/wd4661" # no suitable definition provided for explicit template instantiation request
"/wd4848" # 'no_unique_address' is a vendor extension in C++17
# errors:
"/we4013" # 'function' undefined; assuming extern returning int
"/we4133" # incompatible pointer types

View File

@ -51,3 +51,52 @@ diff --git a/pxr/usd/sdr/shaderMetadataHelpers.h b/pxr/usd/sdr/shaderMetadataHel
/// \namespace ShaderMetadataHelpers
diff --git a/pxr/base/arch/timing.h b/pxr/base/arch/timing.h
index 517561f..fda5a1f 100644
--- a/pxr/base/arch/timing.h
+++ b/pxr/base/arch/timing.h
@@ -91,6 +91,10 @@ ArchGetTickTime()
inline uint64_t
ArchGetStartTickTime()
{
+ // BLENDER: avoid using rdtsc instruction that is not supported on older CPUs.
+ return ArchGetTickTime();
+
+#if 0
uint64_t t;
#if defined (ARCH_OS_DARWIN)
return ArchGetTickTime();
@@ -123,6 +127,7 @@ ArchGetStartTickTime()
#error "Unsupported architecture."
#endif
return t;
+#endif
}
/// Get a "stop" tick time for measuring an interval of time. See
@@ -132,6 +137,10 @@ ArchGetStartTickTime()
inline uint64_t
ArchGetStopTickTime()
{
+ // BLENDER: avoid using rdtsc instruction that is not supported on older CPUs.
+ return ArchGetTickTime();
+
+#if 0
uint64_t t;
#if defined (ARCH_OS_DARWIN)
return ArchGetTickTime();
@@ -162,11 +171,11 @@ ArchGetStopTickTime()
#error "Unsupported architecture."
#endif
return t;
+#endif
}
-#if defined (doxygen) || \
- (!defined(ARCH_OS_DARWIN) && defined(ARCH_CPU_INTEL) && \
- (defined(ARCH_COMPILER_CLANG) || defined(ARCH_COMPILER_GCC)))
+// BLENDER: avoid using rdtsc instruction that is not supported on older CPUs.
+#if 0
/// A simple timer class for measuring an interval of time using the
/// ArchTickTimer facilities.

View File

@ -4,6 +4,12 @@ OpenGL Wrapper (bgl)
.. module:: bgl
.. warning::
This module is deprecated and will be removed in a future release,
when OpenGL is replaced by Metal and Vulkan.
Use the graphics API independent :mod:`gpu` module instead.
This module wraps OpenGL constants and functions, making them available from
within Blender Python.

File diff suppressed because it is too large Load Diff

View File

@ -450,7 +450,11 @@ if(WITH_COREAUDIO)
if(WITH_STRICT_DEPENDENCIES)
message(FATAL_ERROR "CoreAudio not found!")
else()
set(WITH_COREAUDIO FALSE CACHE BOOL "Build With CoreAudio" FORCE)
if(AUDASPACE_STANDALONE)
set(WITH_COREAUDIO FALSE CACHE BOOL "Build With CoreAudio" FORCE)
else()
set(WITH_COREAUDIO FALSE)
endif()
message(WARNING "CoreAudio not found, plugin will not be built.")
endif()
endif()
@ -487,7 +491,11 @@ if(WITH_FFMPEG)
list(APPEND DLLS ${FFMPEG_DLLS})
endif()
else()
set(WITH_FFMPEG FALSE CACHE BOOL "Build With FFMPEG" FORCE)
if(AUDASPACE_STANDALONE)
set(WITH_FFMPEG FALSE CACHE BOOL "Build With FFMPEG" FORCE)
else()
set(WITH_FFMPEG FALSE)
endif()
message(WARNING "FFMPEG not found, plugin will not be built.")
endif()
endif()
@ -536,7 +544,11 @@ if(WITH_FFTW)
list(APPEND DLLS ${FFTW_DLLS})
endif()
else()
set(WITH_FFTW FALSE CACHE BOOL "Build With FFTW" FORCE)
if(AUDASPACE_STANDALONE)
set(WITH_FFTW FALSE CACHE BOOL "Build With FFTW" FORCE)
else()
set(WITH_FFTW FALSE)
endif()
message(WARNING "FFTW not found, convolution functionality will not be built.")
endif()
endif()
@ -579,7 +591,11 @@ if(WITH_JACK)
list(APPEND DLLS ${JACK_DLLS})
endif()
else()
set(WITH_JACK FALSE CACHE BOOL "Build With JACK" FORCE)
if(AUDASPACE_STANDALONE)
set(WITH_JACK FALSE CACHE BOOL "Build With JACK" FORCE)
else()
set(WITH_JACK FALSE)
endif()
message(WARNING "JACK not found, plugin will not be built.")
endif()
endif()
@ -615,7 +631,11 @@ if(WITH_LIBSNDFILE)
list(APPEND DLLS ${LIBSNDFILE_DLLS})
endif()
else()
set(WITH_LIBSNDFILE FALSE CACHE BOOL "Build With LibSndFile" FORCE)
if(AUDASPACE_STANDALONE)
set(WITH_LIBSNDFILE FALSE CACHE BOOL "Build With LibSndFile" FORCE)
else()
set(WITH_LIBSNDFILE FALSE)
endif()
message(WARNING "LibSndFile not found, plugin will not be built.")
endif()
endif()
@ -649,7 +669,11 @@ if(WITH_OPENAL)
list(APPEND DLLS ${OPENAL_DLLS})
endif()
else()
set(WITH_OPENAL FALSE CACHE BOOL "Build With OpenAL" FORCE)
if(AUDASPACE_STANDALONE)
set(WITH_OPENAL FALSE CACHE BOOL "Build With OpenAL" FORCE)
else()
set(WITH_OPENAL FALSE)
endif()
message(WARNING "OpenAL not found, plugin will not be built.")
endif()
endif()
@ -685,7 +709,11 @@ if(WITH_PULSEAUDIO)
list(APPEND STATIC_PLUGINS PulseAudioDevice)
endif()
else()
set(WITH_PULSEAUDIO FALSE CACHE BOOL "Build With PulseAudio" FORCE)
if(AUDASPACE_STANDALONE)
set(WITH_PULSEAUDIO FALSE CACHE BOOL "Build With PulseAudio" FORCE)
else()
set(WITH_PULSEAUDIO FALSE)
endif()
message(WARNING "PulseAudio not found, plugin will not be built.")
endif()
endif()
@ -716,8 +744,12 @@ if(WITH_PYTHON)
list(APPEND DLLS ${PYTHON_DLLS})
endif()
else()
set(WITH_PYTHON FALSE CACHE BOOL "Build With Python Library" FORCE)
message(WARNING "Python libraries not found, language binding will not be built.")
if(AUDASPACE_STANDALONE)
set(WITH_PYTHON FALSE CACHE BOOL "Build With Python Library" FORCE)
else()
set(WITH_PYTHON FALSE)
endif()
message(WARNING "Python & NumPy libraries not found, language binding will not be built.")
endif()
endif()
@ -759,7 +791,11 @@ if(WITH_SDL)
list(APPEND DLLS ${SDL_DLLS})
endif()
else()
set(WITH_SDL FALSE CACHE BOOL "Build With SDL" FORCE)
if(AUDASPACE_STANDALONE)
set(WITH_SDL FALSE CACHE BOOL "Build With SDL" FORCE)
else()
set(WITH_SDL FALSE)
endif()
message(WARNING "SDL not found, plugin will not be built.")
endif()
endif()
@ -1116,7 +1152,11 @@ if(WITH_DOCS)
add_custom_target(audaspace_doc ALL ${DOXYGEN_EXECUTABLE} Doxyfile COMMENT "Building C++ HTML documentation with Doxygen.")
else()
set(WITH_DOCS FALSE CACHE BOOL "Build C++ HTML Documentation with Doxygen" FORCE)
if(AUDASPACE_STANDALONE)
set(WITH_DOCS FALSE CACHE BOOL "Build C++ HTML Documentation with Doxygen" FORCE)
else()
set(WITH_DOCS FALSE)
endif()
message(WARNING "Doxygen (and/or dot) not found, documentation will not be built.")
endif()
endif()
@ -1129,7 +1169,11 @@ if(WITH_BINDING_DOCS)
add_custom_target(bindings_doc ALL COMMAND ${PYTHON_EXECUTABLE} setup.py --build-docs ${SPHINX_EXECUTABLE} -q -b html -c "${CMAKE_CURRENT_BINARY_DIR}" -d "${CMAKE_CURRENT_BINARY_DIR}/_doctrees" "${CMAKE_CURRENT_SOURCE_DIR}/bindings/doc" "${CMAKE_CURRENT_BINARY_DIR}/doc/bindings" DEPENDS pythonmodule COMMENT "Building C/Python HTML documentation with Sphinx.")
else()
set(WITH_BINDING_DOCS FALSE CACHE BOOL "Build C/Python HTML Documentation with Sphinx" FORCE)
if(AUDASPACE_STANDALONE)
set(WITH_BINDING_DOCS FALSE CACHE BOOL "Build C/Python HTML Documentation with Sphinx" FORCE)
else()
set(WITH_BINDING_DOCS FALSE)
endif()
message(WARNING "Sphinx not found, binding documentation will not be built.")
endif()
endif()

View File

@ -7,6 +7,11 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
"-Wno-strict-prototypes"
)
endif()
if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "12.1"))
add_c_flag(
"-Wno-address"
)
endif()
# MSVC's inliner is not having a happy time with glewIsSupported
# causing this to be one of the most expensive things to build

View File

@ -35,11 +35,15 @@ if(NOT WITH_SYSTEM_AUDASPACE)
else()
list(APPEND LIB
${AUDASPACE_C_LIBRARIES}
${AUDASPACE_PY_LIBRARIES}
)
if(WITH_PYTHON AND WITH_PYTHON_NUMPY)
list(APPEND LIB
${AUDASPACE_PY_LIBRARIES}
)
endif()
endif()
if(WITH_PYTHON)
if(WITH_PYTHON AND WITH_PYTHON_NUMPY)
list(APPEND INC_SYS
${PYTHON_INCLUDE_DIRS}
)

View File

@ -24,12 +24,19 @@ from . import camera
enum_devices = (
('CPU', "CPU", "Use CPU for rendering"),
('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in the system tab in the user preferences"),
('GPU', "GPU Compute",
"Use GPU compute device for rendering, configured in the system tab in the user preferences"),
)
enum_feature_set = (
('SUPPORTED', "Supported", "Only use finished and supported features"),
('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future", 'ERROR', 1),
('SUPPORTED',
"Supported",
"Only use finished and supported features"),
('EXPERIMENTAL',
"Experimental",
"Use experimental and incomplete features that might be broken or change in the future",
'ERROR',
1),
)
enum_displacement_methods = (
@ -81,9 +88,14 @@ enum_sampling_pattern = (
)
enum_volume_sampling = (
('DISTANCE', "Distance", "Use distance sampling, best for dense volumes with lights far away"),
('EQUIANGULAR', "Equiangular", "Use equiangular sampling, best for volumes with low density with light inside or near the volume"),
('MULTIPLE_IMPORTANCE', "Multiple Importance",
('DISTANCE',
"Distance",
"Use distance sampling, best for dense volumes with lights far away"),
('EQUIANGULAR',
"Equiangular",
"Use equiangular sampling, best for volumes with low density with light inside or near the volume"),
('MULTIPLE_IMPORTANCE',
"Multiple Importance",
"Combine distance and equi-angular sampling for volumes where neither method is ideal"),
)
@ -93,10 +105,15 @@ enum_volume_interpolation = (
)
enum_world_mis = (
('NONE', "None", "Don't sample the background, faster but might cause noise for non-solid backgrounds"),
('AUTOMATIC', "Auto", "Automatically try to determine the best setting"),
('MANUAL', "Manual", "Manually set the resolution of the sampling map, higher values are slower and require more memory but reduce noise")
)
('NONE',
"None",
"Don't sample the background, faster but might cause noise for non-solid backgrounds"),
('AUTOMATIC',
"Auto",
"Automatically try to determine the best setting"),
('MANUAL',
"Manual",
"Manually set the resolution of the sampling map, higher values are slower and require more memory but reduce noise"))
enum_device_type = (
('CPU', "CPU", "CPU", 0),
@ -210,17 +227,33 @@ enum_denoising_input_passes = (
)
enum_denoising_prefilter = (
('NONE', "None", "No prefiltering, use when guiding passes are noise-free", 1),
('FAST', "Fast", "Denoise color and guiding passes together. Improves quality when guiding passes are noisy using least amount of extra processing time", 2),
('ACCURATE', "Accurate", "Prefilter noisy guiding passes before denoising color. Improves quality when guiding passes are noisy using extra processing time", 3),
('NONE',
"None",
"No prefiltering, use when guiding passes are noise-free",
1),
('FAST',
"Fast",
"Denoise color and guiding passes together. Improves quality when guiding passes are noisy using least amount of extra processing time",
2),
('ACCURATE',
"Accurate",
"Prefilter noisy guiding passes before denoising color. Improves quality when guiding passes are noisy using extra processing time",
3),
)
enum_direct_light_sampling_type = (
('MULTIPLE_IMPORTANCE_SAMPLING', "Multiple Importance Sampling",
"Multiple importance sampling is used to combine direct light contributions from next-event estimation and forward path tracing", 0),
('FORWARD_PATH_TRACING', "Forward Path Tracing", "Direct light contributions are only sampled using forward path tracing", 1),
('NEXT_EVENT_ESTIMATION', "Next-Event Estimation",
"Direct light contributions are only sampled using next-event estimation", 2),
('MULTIPLE_IMPORTANCE_SAMPLING',
"Multiple Importance Sampling",
"Multiple importance sampling is used to combine direct light contributions from next-event estimation and forward path tracing",
0),
('FORWARD_PATH_TRACING',
"Forward Path Tracing",
"Direct light contributions are only sampled using forward path tracing",
1),
('NEXT_EVENT_ESTIMATION',
"Next-Event Estimation",
"Direct light contributions are only sampled using next-event estimation",
2),
)
@ -357,7 +390,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
scrambling_distance: FloatProperty(
name="Scrambling Distance",
default=1.0,
min=0.0, soft_max=1.0,
min=0.0,
soft_max=1.0,
description="Reduce randomization between pixels to improve GPU rendering performance, at the cost of possible rendering artifacts if set too low",
)
preview_scrambling_distance: BoolProperty(
@ -383,7 +417,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
name="Light Sampling Threshold",
description="Probabilistically terminate light samples when the light contribution is below this threshold (more noise but faster rendering). "
"Zero disables the test and never ignores lights",
min=0.0, max=1.0,
min=0.0,
max=1.0,
default=0.01,
)
@ -395,7 +430,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
adaptive_threshold: FloatProperty(
name="Adaptive Sampling Threshold",
description="Noise level step to stop sampling at, lower values reduce noise at the cost of render time. Zero for automatic setting based on number of AA samples",
min=0.0, max=1.0,
min=0.0,
max=1.0,
soft_min=0.001,
default=0.01,
precision=4,
@ -403,7 +439,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
adaptive_min_samples: IntProperty(
name="Adaptive Min Samples",
description="Minimum AA samples for adaptive sampling, to discover noisy features before stopping sampling. Zero for automatic setting based on noise threshold",
min=0, max=4096,
min=0,
max=4096,
default=0,
)
@ -415,7 +452,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
preview_adaptive_threshold: FloatProperty(
name="Adaptive Sampling Threshold",
description="Noise level step to stop sampling at, lower values reduce noise at the cost of render time. Zero for automatic setting based on number of AA samples, for viewport renders",
min=0.0, max=1.0,
min=0.0,
max=1.0,
soft_min=0.001,
default=0.1,
precision=4,
@ -423,7 +461,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
preview_adaptive_min_samples: IntProperty(
name="Adaptive Min Samples",
description="Minimum AA samples for adaptive sampling, to discover noisy features before stopping sampling. Zero for automatic setting based on noise threshold, for viewport renders",
min=0, max=4096,
min=0,
max=4096,
default=0,
)
@ -550,7 +589,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
max_subdivisions: IntProperty(
name="Max Subdivisions",
description="Stop subdividing when this level is reached even if the dice rate would produce finer tessellation",
min=0, max=16,
min=0,
max=16,
default=12,
)
@ -817,8 +857,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
debug_use_optix_debug: BoolProperty(
name="OptiX Module Debug",
description="Load OptiX module in debug mode: lower logging verbosity level, enable validations, and lower optimization level",
default=False
)
default=False)
@classmethod
def register(cls):
@ -1185,7 +1224,8 @@ class CyclesObjectSettings(bpy.types.PropertyGroup):
motion_steps: IntProperty(
name="Motion Steps",
description="Control accuracy of motion blur, more steps gives more memory usage (actual number of steps is 2^(steps - 1))",
min=1, max=7,
min=1,
max=7,
default=1,
)
@ -1224,7 +1264,8 @@ class CyclesObjectSettings(bpy.types.PropertyGroup):
shadow_terminator_geometry_offset: FloatProperty(
name="Shadow Terminator Geometry Offset",
description="Offset rays from the surface to reduce shadow terminator artifact on low poly geometry. Only affects triangles at grazing angles to light",
min=0.0, max=1.0,
min=0.0,
max=1.0,
default=0.1,
)

View File

@ -1082,8 +1082,18 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel):
def has_geometry_visibility(ob):
return ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT', 'VOLUME', 'POINTCLOUD', 'CURVES'}) or
(ob.instance_type == 'COLLECTION' and ob.instance_collection))
return ob and (
(ob.type in {
'MESH',
'CURVE',
'SURFACE',
'FONT',
'META',
'LIGHT',
'VOLUME',
'POINTCLOUD',
'CURVES',
}) or (ob.instance_type == 'COLLECTION' and ob.instance_collection))
class CYCLES_OBJECT_PT_shading(CyclesButtonsPanel, Panel):

View File

@ -219,7 +219,10 @@ static void sync_smoke_volume(
class BlenderVolumeLoader : public VDBImageLoader {
public:
BlenderVolumeLoader(BL::BlendData &b_data, BL::Volume &b_volume, const string &grid_name)
BlenderVolumeLoader(BL::BlendData &b_data,
BL::Volume &b_volume,
const string &grid_name,
BL::VolumeRender::precision_enum precision_)
: VDBImageLoader(grid_name), b_volume(b_volume)
{
b_volume.grids.load(b_data.ptr.data);
@ -240,6 +243,20 @@ class BlenderVolumeLoader : public VDBImageLoader {
break;
}
}
#endif
#ifdef WITH_NANOVDB
switch (precision_) {
case BL::VolumeRender::precision_FULL:
precision = 32;
break;
case BL::VolumeRender::precision_HALF:
precision = 16;
break;
default:
case BL::VolumeRender::precision_VARIABLE:
precision = 0;
break;
}
#endif
}
@ -318,7 +335,8 @@ static void sync_volume_object(BL::BlendData &b_data,
volume->attributes.add(std) :
volume->attributes.add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL);
ImageLoader *loader = new BlenderVolumeLoader(b_data, b_volume, name.string());
ImageLoader *loader = new BlenderVolumeLoader(
b_data, b_volume, name.string(), b_render.precision());
ImageParams params;
params.frame = b_volume.grids.frame();

View File

@ -145,8 +145,8 @@ if(CYCLES_STANDALONE_REPOSITORY)
-DOIIO_STATIC_DEFINE
)
set(OPENIMAGEIO_INCLUDE_DIR ${OPENIMAGEIO_ROOT_DIR}/include)
set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIR} ${OPENIMAGEIO_INCLUDE_DIR}/OpenImageIO)
set(OPENIMAGEIO_INCLUDE_DIR ${OPENIMAGEIO_ROOT_DIR}/include)
set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIR} ${OPENIMAGEIO_INCLUDE_DIR}/OpenImageIO)
# Special exceptions for libraries which needs explicit debug version
set(OPENIMAGEIO_LIBRARIES
optimized ${OPENIMAGEIO_ROOT_DIR}/lib/OpenImageIO.lib

View File

@ -1084,7 +1084,9 @@ void CUDADevice::tex_alloc(device_texture &mem)
need_texture_info = true;
if (mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT &&
mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3) {
mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3 &&
mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FPN &&
mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FP16) {
CUDA_RESOURCE_DESC resDesc;
memset(&resDesc, 0, sizeof(resDesc));

View File

@ -1042,7 +1042,9 @@ void HIPDevice::tex_alloc(device_texture &mem)
need_texture_info = true;
if (mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT &&
mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3) {
mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3 &&
mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FPN &&
mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FP16) {
/* Bindless textures. */
hipResourceDesc resDesc;
memset(&resDesc, 0, sizeof(resDesc));

View File

@ -165,6 +165,8 @@ device_texture::device_texture(Device *device,
case IMAGE_DATA_TYPE_BYTE:
case IMAGE_DATA_TYPE_NANOVDB_FLOAT:
case IMAGE_DATA_TYPE_NANOVDB_FLOAT3:
case IMAGE_DATA_TYPE_NANOVDB_FPN:
case IMAGE_DATA_TYPE_NANOVDB_FP16:
data_type = TYPE_UCHAR;
data_elements = 1;
break;

View File

@ -172,7 +172,7 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel,
for (auto &pipeline : pipelines[device_kernel]) {
if (scene_specialized) {
if (pipeline->source_md5 == device->source_md5[PSO_SPECIALISED]) {
/* we already requested a pipeline that is specialised for this kernel data */
/* we already requested a pipeline that is specialized for this kernel data */
metal_printf("Specialized kernel already requested (%s)\n",
device_kernel_as_string(device_kernel));
return;
@ -445,7 +445,7 @@ void MetalKernelPipeline::compile()
string options;
if (use_metalrt && kernel_has_intersection(device_kernel)) {
/* incorporate any MetalRT specialisations into the archive name */
/* incorporate any MetalRT specializations into the archive name */
options += string_printf(".hair_%d.hair_thick_%d.pointcloud_%d",
metalrt_hair ? 1 : 0,
metalrt_hair_thick ? 1 : 0,

View File

@ -19,8 +19,10 @@ struct NodeEnum {
}
void insert(const char *x, int y)
{
left[ustring(x)] = y;
right[y] = ustring(x);
ustring ustr_x(x);
left[ustr_x] = y;
right[y] = ustr_x;
}
bool exists(ustring x) const

View File

@ -626,6 +626,7 @@ uint OIDNDenoiser::get_device_type_mask() const
Device *OIDNDenoiser::ensure_denoiser_device(Progress *progress)
{
#ifndef WITH_OPENIMAGEDENOISE
(void)progress;
path_trace_device_->set_error("Build without OpenImageDenoiser");
return nullptr;
#else

View File

@ -817,6 +817,16 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals kg,
}
case IMAGE_DATA_TYPE_NANOVDB_FLOAT3:
return NanoVDBInterpolator<nanovdb::Vec3f>::interp_3d(info, P.x, P.y, P.z, interp);
case IMAGE_DATA_TYPE_NANOVDB_FPN: {
const float f = NanoVDBInterpolator<nanovdb::FpN, float>::interp_3d(
info, P.x, P.y, P.z, interp);
return make_float4(f, f, f, 1.0f);
}
case IMAGE_DATA_TYPE_NANOVDB_FP16: {
const float f = NanoVDBInterpolator<nanovdb::Fp16, float>::interp_3d(
info, P.x, P.y, P.z, interp);
return make_float4(f, f, f, 1.0f);
}
#endif
default:
assert(0);

View File

@ -125,7 +125,8 @@ kernel_tex_image_interp_tricubic(ccl_global const TextureInfo &info, float x, fl
#ifdef WITH_NANOVDB
template<typename T, typename S>
ccl_device T kernel_tex_image_interp_tricubic_nanovdb(S &s, float x, float y, float z)
ccl_device typename nanovdb::NanoGrid<T>::ValueType kernel_tex_image_interp_tricubic_nanovdb(
S &s, float x, float y, float z)
{
float px = floorf(x);
float py = floorf(y);
@ -157,7 +158,7 @@ ccl_device T kernel_tex_image_interp_tricubic_nanovdb(S &s, float x, float y, fl
}
template<typename T>
ccl_device_noinline T kernel_tex_image_interp_nanovdb(
ccl_device_noinline typename nanovdb::NanoGrid<T>::ValueType kernel_tex_image_interp_nanovdb(
ccl_global const TextureInfo &info, float x, float y, float z, uint interpolation)
{
using namespace nanovdb;
@ -238,6 +239,14 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals kg,
info, x, y, z, interpolation);
return make_float4(f[0], f[1], f[2], 1.0f);
}
if (texture_type == IMAGE_DATA_TYPE_NANOVDB_FPN) {
float f = kernel_tex_image_interp_nanovdb<nanovdb::FpN>(info, x, y, z, interpolation);
return make_float4(f, f, f, 1.0f);
}
if (texture_type == IMAGE_DATA_TYPE_NANOVDB_FP16) {
float f = kernel_tex_image_interp_nanovdb<nanovdb::Fp16>(info, x, y, z, interpolation);
return make_float4(f, f, f, 1.0f);
}
#endif
if (texture_type == IMAGE_DATA_TYPE_FLOAT4 || texture_type == IMAGE_DATA_TYPE_BYTE4 ||
texture_type == IMAGE_DATA_TYPE_HALF4 || texture_type == IMAGE_DATA_TYPE_USHORT4) {

View File

@ -647,8 +647,9 @@ ccl_device_inline void kernel_gpu_film_convert_half_write(ccl_global uchar4 *rgb
const int x = render_pixel_index % width; \
const int y = render_pixel_index / width; \
\
ccl_global const float *buffer = render_buffer + offset + x * kfilm_convert.pass_stride + \
y * stride * kfilm_convert.pass_stride; \
const uint64_t buffer_pixel_index = x + y * stride; \
ccl_global const float *buffer = render_buffer + offset + \
buffer_pixel_index * kfilm_convert.pass_stride; \
\
ccl_global float *pixel = pixels + \
(render_pixel_index + rgba_offset) * kfilm_convert.pixel_stride; \
@ -677,8 +678,9 @@ ccl_device_inline void kernel_gpu_film_convert_half_write(ccl_global uchar4 *rgb
const int x = render_pixel_index % width; \
const int y = render_pixel_index / width; \
\
ccl_global const float *buffer = render_buffer + offset + x * kfilm_convert.pass_stride + \
y * stride * kfilm_convert.pass_stride; \
const uint64_t buffer_pixel_index = x + y * stride; \
ccl_global const float *buffer = render_buffer + offset + \
buffer_pixel_index * kfilm_convert.pass_stride; \
\
float pixel[4]; \
film_get_pass_pixel_##variant(&kfilm_convert, buffer, pixel); \

View File

@ -91,13 +91,13 @@ ccl_device void kernel_adaptive_sampling_filter_x(KernelGlobals kg,
bool prev = false;
for (int x = start_x; x < start_x + width; ++x) {
int index = offset + x + y * stride;
ccl_global float *buffer = render_buffer + index * kernel_data.film.pass_stride;
ccl_global float *buffer = render_buffer + (uint64_t)index * kernel_data.film.pass_stride;
const uint aux_w_offset = kernel_data.film.pass_adaptive_aux_buffer + 3;
if (buffer[aux_w_offset] == 0.0f) {
if (x > start_x && !prev) {
index = index - 1;
buffer = render_buffer + index * kernel_data.film.pass_stride;
buffer = render_buffer + (uint64_t)index * kernel_data.film.pass_stride;
buffer[aux_w_offset] = 0.0f;
}
prev = true;
@ -124,13 +124,13 @@ ccl_device void kernel_adaptive_sampling_filter_y(KernelGlobals kg,
bool prev = false;
for (int y = start_y; y < start_y + height; ++y) {
int index = offset + x + y * stride;
ccl_global float *buffer = render_buffer + index * kernel_data.film.pass_stride;
ccl_global float *buffer = render_buffer + (uint64_t)index * kernel_data.film.pass_stride;
const uint aux_w_offset = kernel_data.film.pass_adaptive_aux_buffer + 3;
if (buffer[aux_w_offset] == 0.0f) {
if (y > start_y && !prev) {
index = index - stride;
buffer = render_buffer + index * kernel_data.film.pass_stride;
buffer = render_buffer + (uint64_t)index * kernel_data.film.pass_stride;
buffer[aux_w_offset] = 0.0f;
}
prev = true;

View File

@ -102,7 +102,7 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
/* Setup render buffers. */
const int index = INTEGRATOR_STATE(state, path, render_pixel_index);
const int pass_stride = kernel_data.film.pass_stride;
ccl_global float *buffer = render_buffer + index * pass_stride;
ccl_global float *buffer = render_buffer + (uint64_t)index * pass_stride;
ccl_global float *primitive = buffer + kernel_data.film.pass_bake_primitive;
ccl_global float *differential = buffer + kernel_data.film.pass_bake_differential;

View File

@ -36,7 +36,7 @@
* https://cg.ivd.kit.edu/english/HSLT.php
*/
# define MNEE_MAX_ITERATIONS 32
# define MNEE_MAX_ITERATIONS 64
# define MNEE_MAX_INTERSECTION_COUNT 10
# define MNEE_SOLVER_THRESHOLD 0.001f
# define MNEE_MINIMUM_STEP_SIZE 0.0001f
@ -140,26 +140,8 @@ ccl_device_forceinline void mnee_update_light_sample(KernelGlobals kg,
ls->D = normalize_len(ls->P - P, &ls->t);
ls->pdf = fabsf(klight->area.invarea);
}
}
/* Compute orthonormal basis
* https://graphics.pixar.com/library/OrthonormalB/paper.pdf */
ccl_device_forceinline void mnee_make_orthonormals(const float3 n,
ccl_private float3 *dp_du,
ccl_private float3 *dp_dv)
{
if (n.z < 0.0f) {
const float a = 1.0f / (1.0f - n.z);
const float b = n.x * n.y * a;
*dp_du = make_float3(1.0f - n.x * n.x * a, -b, n.x);
*dp_dv = make_float3(b, n.y * n.y * a - 1.0f, -n.y);
}
else {
const float a = 1.0f / (1.0f + n.z);
const float b = -n.x * n.y * a;
*dp_du = make_float3(1.0f - n.x * n.x * a, b, -n.x);
*dp_dv = make_float3(b, 1.0f - n.y * n.y * a, -n.y);
}
ls->pdf *= kernel_data.integrator.pdf_lights;
}
/* Manifold vertex setup from ray and intersection data */
@ -170,8 +152,7 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg,
const float2 n_offset,
ccl_private const Ray *ray,
ccl_private const Intersection *isect,
ccl_private ShaderData *sd_vtx,
bool seed)
ccl_private ShaderData *sd_vtx)
{
sd_vtx->object = (isect->object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, isect->prim) :
isect->object;
@ -263,30 +244,13 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg,
dp_dv *= inv_len_dp_dv;
dn_dv *= inv_len_dp_dv;
/* Final local differential geometry. */
if (seed) {
vtx->dp_du = dp_du;
vtx->dp_dv = dp_dv;
vtx->dn_du = dn_du;
vtx->dn_dv = dn_dv;
}
else {
/* Find angle subtended by reference direction (travel direction). */
const float3 reference_direction = normalize(sd_vtx->P - vtx->p);
const float reference_theta = atan2(dot(reference_direction, vtx->dp_dv),
dot(reference_direction, vtx->dp_du));
const float current_theta = atan2(dot(reference_direction, dp_dv),
dot(reference_direction, dp_du));
const float theta = reference_theta - current_theta;
/* Rotate (dp_du,dp_dv) to be consistent with previous tangent frame. */
float cos_theta, sin_theta;
fast_sincosf(theta, &sin_theta, &cos_theta);
vtx->dp_du = cos_theta * dp_du - sin_theta * dp_dv;
vtx->dp_dv = sin_theta * dp_du + cos_theta * dp_dv;
vtx->dn_du = cos_theta * dn_du - sin_theta * dn_dv;
vtx->dn_dv = sin_theta * dn_du + cos_theta * dn_dv;
}
/* Find consistent tangent frame for every point on the surface. */
make_orthonormals(vtx->ng, &vtx->dp_du, &vtx->dp_dv);
/* Apply the equivalent rotation to the normal derivatives. */
const float cos_theta = dot(dp_du, vtx->dp_du);
const float sin_theta = -dot(dp_dv, vtx->dp_du);
vtx->dn_du = cos_theta * dn_du - sin_theta * dn_dv;
vtx->dn_dv = sin_theta * dn_du + cos_theta * dn_dv;
/* Manifold vertex position. */
vtx->p = sd_vtx->P;
@ -570,15 +534,8 @@ ccl_device_forceinline bool mnee_newton_solver(KernelGlobals kg,
tv.dp_dv = mv.dp_dv;
/* Setup corrected manifold vertex. */
mnee_setup_manifold_vertex(kg,
&tv,
mv.bsdf,
mv.eta,
mv.n_offset,
&projection_ray,
&projection_isect,
sd_vtx,
false);
mnee_setup_manifold_vertex(
kg, &tv, mv.bsdf, mv.eta, mv.n_offset, &projection_ray, &projection_isect, sd_vtx);
/* Fail newton solve if we are not making progress, probably stuck trying to move off the
* edge of the mesh. */
@ -749,7 +706,7 @@ ccl_device_forceinline bool mnee_compute_transfer_matrix(ccl_private const Shade
/* Local differential geometry. */
float3 dp_du, dp_dv;
mnee_make_orthonormals(ls->Ng, &dp_du, &dp_dv);
make_orthonormals(ls->Ng, &dp_du, &dp_dv);
/* Direction toward surface sample. */
float3 wi = vertex_count == 1 ? sd->P - m.p : vertices[mi - 1].p - m.p;
@ -850,6 +807,15 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
* and keep pdf in vertex area measure */
mnee_update_light_sample(kg, vertices[vertex_count - 1].p, ls);
/* Save state path bounce info in case a light path node is used in the refractive interface or
* light shader graph. */
const int transmission_bounce = INTEGRATOR_STATE(state, path, transmission_bounce);
const int diffuse_bounce = INTEGRATOR_STATE(state, path, diffuse_bounce);
const int bounce = INTEGRATOR_STATE(state, path, bounce);
/* Set diffuse bounce info . */
INTEGRATOR_STATE_WRITE(state, path, diffuse_bounce) = diffuse_bounce + 1;
/* Evaluate light sample
* in case the light has a node-based shader:
* 1. sd_mnee will be used to store light data, which is why we need to do
@ -857,6 +823,12 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
* interface data at the end of the call for the shadow ray setup to work.
* 2. ls needs to contain the last interface data for the light shader to
* evaluate properly */
/* Set bounce info in case a light path node is used in the light shader graph. */
INTEGRATOR_STATE_WRITE(state, path, transmission_bounce) = transmission_bounce + vertex_count -
1;
INTEGRATOR_STATE_WRITE(state, path, bounce) = bounce + vertex_count;
float3 light_eval = light_sample_shader_eval(kg, state, sd_mnee, ls, sd->time);
bsdf_eval_mul3(throughput, light_eval / ls->pdf);
@ -928,6 +900,11 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
false,
LAMP_NONE);
/* Set bounce info in case a light path node is used in the refractive interface
* shader graph. */
INTEGRATOR_STATE_WRITE(state, path, transmission_bounce) = transmission_bounce + vi;
INTEGRATOR_STATE_WRITE(state, path, bounce) = bounce + 1 + vi;
/* Evaluate shader nodes at solution vi. */
shader_eval_surface<KERNEL_FEATURE_NODE_MASK_SURFACE_SHADOW>(
kg, state, sd_mnee, NULL, PATH_RAY_DIFFUSE, true);
@ -944,6 +921,11 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
bsdf_eval_mul3(throughput, bsdf_contribution);
}
/* Restore original state path bounce info. */
INTEGRATOR_STATE_WRITE(state, path, transmission_bounce) = transmission_bounce;
INTEGRATOR_STATE_WRITE(state, path, diffuse_bounce) = diffuse_bounce;
INTEGRATOR_STATE_WRITE(state, path, bounce) = bounce;
return true;
}
@ -1050,8 +1032,7 @@ ccl_device_forceinline int kernel_path_mnee_sample(KernelGlobals kg,
}
/* Setup differential geometry on vertex. */
mnee_setup_manifold_vertex(
kg, &mv, bsdf, eta, h, &probe_ray, &probe_isect, sd_mnee, true);
mnee_setup_manifold_vertex(kg, &mv, bsdf, eta, h, &probe_ray, &probe_isect, sd_mnee);
break;
}
}
@ -1073,18 +1054,17 @@ ccl_device_forceinline int kernel_path_mnee_sample(KernelGlobals kg,
return 0;
/* Check whether the transmission depth limit is reached before continuing. */
if (INTEGRATOR_STATE(state, path, transmission_bounce) + vertex_count >=
if ((INTEGRATOR_STATE(state, path, transmission_bounce) + vertex_count - 1) >=
kernel_data.integrator.max_transmission_bounce)
return 0;
/* Check whether the diffuse depth limit is reached before continuing. */
if (INTEGRATOR_STATE(state, path, diffuse_bounce) + 1 >=
if ((INTEGRATOR_STATE(state, path, diffuse_bounce) + 1) >=
kernel_data.integrator.max_diffuse_bounce)
return 0;
/* Check whether the overall depth limit is reached before continuing. */
if (INTEGRATOR_STATE(state, path, bounce) + 1 + vertex_count >=
kernel_data.integrator.max_bounce)
if ((INTEGRATOR_STATE(state, path, bounce) + vertex_count) >= kernel_data.integrator.max_bounce)
return 0;
/* Mark the manifold walk valid to turn off mollification regardless of how successful the walk

View File

@ -253,13 +253,13 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
# ifdef __MNEE__
if (mnee_vertex_count > 0) {
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transmission_bounce) =
INTEGRATOR_STATE(state, path, transmission_bounce) + mnee_vertex_count;
INTEGRATOR_STATE(state, path, transmission_bounce) + mnee_vertex_count - 1;
INTEGRATOR_STATE_WRITE(shadow_state,
shadow_path,
diffuse_bounce) = INTEGRATOR_STATE(state, path, diffuse_bounce) + 1;
INTEGRATOR_STATE_WRITE(shadow_state,
shadow_path,
bounce) = INTEGRATOR_STATE(state, path, bounce) + 1 + mnee_vertex_count;
bounce) = INTEGRATOR_STATE(state, path, bounce) + mnee_vertex_count;
}
else
# endif

View File

@ -17,6 +17,7 @@
#include "kernel/types.h"
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_diffuse_ramp.h"
#include "kernel/closure/bsdf_util.h"
// clang-format on
CCL_NAMESPACE_BEGIN
@ -30,6 +31,8 @@ class DiffuseRampClosure : public CBSDFClosure {
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
DiffuseRampBsdf *bsdf = (DiffuseRampBsdf *)bsdf_alloc_osl(
sd, sizeof(DiffuseRampBsdf), weight, &params);

View File

@ -17,6 +17,7 @@
#include "kernel/types.h"
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_phong_ramp.h"
#include "kernel/closure/bsdf_util.h"
// clang-format on
CCL_NAMESPACE_BEGIN
@ -30,6 +31,8 @@ class PhongRampClosure : public CBSDFClosure {
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
PhongRampBsdf *bsdf = (PhongRampBsdf *)bsdf_alloc_osl(
sd, sizeof(PhongRampBsdf), weight, &params);

View File

@ -44,6 +44,8 @@ class CBSSRDFClosure : public CClosurePrimitive {
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
if (method == u_burley) {
alloc(sd, path_flag, weight, CLOSURE_BSSRDF_BURLEY_ID);
}

View File

@ -180,6 +180,8 @@ class PrincipledSheenClosure : public CBSDFClosure {
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
if (!skip(sd, path_flag, LABEL_DIFFUSE)) {
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc_osl(
sd, sizeof(PrincipledSheenBsdf), weight, &params);
sd->flag |= (bsdf) ? bsdf_principled_sheen_setup(sd, bsdf) : 0;
@ -223,6 +225,8 @@ class PrincipledHairClosure : public CBSDFClosure {
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
if (!skip(sd, path_flag, LABEL_GLOSSY)) {
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)alloc(sd, path_flag, weight);
if (!bsdf) {
return;
@ -282,6 +286,7 @@ class PrincipledClearcoatClosure : public CBSDFClosure {
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
@ -503,6 +508,8 @@ class MicrofacetClosure : public CBSDFClosure {
return;
}
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
sd, sizeof(MicrofacetBsdf), weight, &params);
@ -601,6 +608,8 @@ class MicrofacetGGXFresnelClosure : public MicrofacetFresnelClosure {
public:
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
@ -630,6 +639,8 @@ class MicrofacetGGXAnisoFresnelClosure : public MicrofacetFresnelClosure {
public:
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
@ -695,6 +706,8 @@ class MicrofacetMultiGGXClosure : public MicrofacetMultiClosure {
public:
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
@ -723,6 +736,8 @@ class MicrofacetMultiGGXAnisoClosure : public MicrofacetMultiClosure {
public:
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
@ -755,6 +770,8 @@ class MicrofacetMultiGGXGlassClosure : public MicrofacetMultiClosure {
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
@ -819,6 +836,8 @@ class MicrofacetMultiGGXFresnelClosure : public MicrofacetMultiFresnelClosure {
public:
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
@ -849,6 +868,8 @@ class MicrofacetMultiGGXAnisoFresnelClosure : public MicrofacetMultiFresnelClosu
public:
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;
@ -883,6 +904,8 @@ class MicrofacetMultiGGXGlassFresnelClosure : public MicrofacetMultiFresnelClosu
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
if (!bsdf) {
return;

View File

@ -114,6 +114,7 @@ class CBSDFClosure : public CClosurePrimitive {
void setup(ShaderData *sd, uint32_t path_flag, float3 weight) \
{ \
if (!skip(sd, path_flag, TYPE)) { \
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); \
structname *bsdf = (structname *)bsdf_alloc_osl(sd, sizeof(structname), weight, &params); \
sd->flag |= (bsdf) ? bsdf_##lower##_setup(bsdf) : 0; \
} \

View File

@ -41,7 +41,7 @@ struct KernelGlobalsCPU;
* These are stored in a concurrent hash map, because OSL can compile multiple
* shaders in parallel.
*
* Note: The svm_slots array contains a compressed mapping of tile to svm_slot pairs
* NOTE: The svm_slots array contains a compressed mapping of tile to svm_slot pairs
* stored as follows: x:tile_a, y:svm_slot_a, z:tile_b, w:svm_slot_b etc. */
struct OSLTextureHandle : public OIIO::RefCnt {

View File

@ -24,6 +24,7 @@ ccl_device_noinline void svm_node_blackbody(KernelGlobals kg,
float temperature = stack_load_float(stack, temperature_offset);
float3 color_rgb = rec709_to_rgb(kg, svm_math_blackbody_color_rec709(temperature));
color_rgb = max(color_rgb, zero_float3());
stack_store_float3(stack, col_offset, color_rgb);
}

View File

@ -188,6 +188,7 @@ ccl_device_noinline int svm_node_vector_displacement(
else
{
stack_store_float3(stack, displacement_offset, zero_float3());
(void)data_node;
}
return offset;

View File

@ -192,28 +192,26 @@ ccl_device float svm_math(NodeMathType type, float a, float b, float c)
ccl_device float3 svm_math_blackbody_color_rec709(float t)
{
/* Calculate color in range 800..12000 using an approximation
* a/x+bx+c for R and G and ((at + b)t + c)t + d) for B
* Max absolute error for RGB is (0.00095, 0.00077, 0.00057),
* which is enough to get the same 8 bit/channel color.
*/
* a/x+bx+c for R and G and ((at + b)t + c)t + d) for B.
*
* The result of this can be negative to support gamut wider than
* than rec.709, just needs to be clamped. */
if (t >= 12000.0f) {
return make_float3(0.826270103f, 0.994478524f, 1.56626022f);
return make_float3(0.8262954810464208f, 0.9945080501520986f, 1.566307710274283f);
}
else if (t < 965.0f) {
/* For 800 <= t < 965 color does not change in OSL implementation, so keep color the same */
return make_float3(4.70366907f, 0.0f, 0.0f);
else if (t < 800.0f) {
/* Arbitrary lower limit where light is very dim, matching OSL. */
return make_float3(5.413294490189271f, -0.20319390035873933f, -0.0822535242887164f);
}
/* Manually align for readability. */
/* clang-format off */
int i = (t >= 6365.0f) ? 5 :
(t >= 3315.0f) ? 4 :
(t >= 1902.0f) ? 3 :
(t >= 1449.0f) ? 2 :
(t >= 1167.0f) ? 1 :
int i = (t >= 6365.0f) ? 6 :
(t >= 3315.0f) ? 5 :
(t >= 1902.0f) ? 4 :
(t >= 1449.0f) ? 3 :
(t >= 1167.0f) ? 2 :
(t >= 965.0f) ? 1 :
0;
/* clang-format on */
ccl_constant float *r = blackbody_table_r[i];
ccl_constant float *g = blackbody_table_g[i];

View File

@ -4,30 +4,33 @@
/* clang-format off */
ccl_inline_constant float blackbody_table_r[][3] = {
{2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f},
{3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f},
{4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f},
{4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f},
{4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f},
{3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f}
{1.61919106e+03f, -2.05010916e-03f, 5.02995757e+00f},
{2.48845471e+03f, -1.11330907e-03f, 3.22621544e+00f},
{3.34143193e+03f, -4.86551192e-04f, 1.76486769e+00f},
{4.09461742e+03f, -1.27446582e-04f, 7.25731635e-01f},
{4.67028036e+03f, 2.91258199e-05f, 1.26703442e-01f},
{4.59509185e+03f, 2.87495649e-05f, 1.50345020e-01f},
{3.78717450e+03f, 9.35907826e-06f, 3.99075871e-01f}
};
ccl_inline_constant float blackbody_table_g[][3] = {
{-7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f},
{-1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f},
{-1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f},
{-1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f},
{-1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f},
{-5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f}
{-4.88999748e+02f, 6.04330754e-04f, -7.55807526e-02f},
{-7.55994277e+02f, 3.16730098e-04f, 4.78306139e-01f},
{-1.02363977e+03f, 1.20223470e-04f, 9.36662319e-01f},
{-1.26571316e+03f, 4.87340896e-06f, 1.27054498e+00f},
{-1.42529332e+03f, -4.01150431e-05f, 1.43972784e+00f},
{-1.17554822e+03f, -2.16378048e-05f, 1.30408023e+00f},
{-5.00799571e+02f, -4.59832026e-06f, 1.09098763e+00f}
};
ccl_inline_constant float blackbody_table_b[][4] = {
{0.0f, 0.0f, 0.0f, 0.0f}, /* zeros should be optimized by compiler */
{0.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 0.0f},
{-2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f},
{-2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f},
{6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f}
{5.96945309e-11f, -4.85742887e-08f, -9.70622247e-05f, -4.07936148e-03f},
{2.40430366e-11f, 5.55021075e-08f, -1.98503712e-04f, 2.89312858e-02f},
{-1.40949732e-11f, 1.89878968e-07f, -3.56632824e-04f, 9.10767778e-02f},
{-3.61460868e-11f, 2.84822009e-07f, -4.93211319e-04f, 1.56723440e-01f},
{-1.97075738e-11f, 1.75359352e-07f, -2.50542825e-04f, -2.22783266e-02f},
{-1.61997957e-13f, -1.64216008e-08f, 3.86216271e-04f, -7.38077418e-01f},
{6.72650283e-13f, -2.73078809e-08f, 4.24098264e-04f, -7.52335691e-01f}
};
ccl_inline_constant float cie_colour_match[][3] = {

View File

@ -64,6 +64,10 @@ const char *name_from_type(ImageDataType type)
return "nanovdb_float";
case IMAGE_DATA_TYPE_NANOVDB_FLOAT3:
return "nanovdb_float3";
case IMAGE_DATA_TYPE_NANOVDB_FPN:
return "nanovdb_fpn";
case IMAGE_DATA_TYPE_NANOVDB_FP16:
return "nanovdb_fp16";
case IMAGE_DATA_NUM_TYPES:
assert(!"System enumerator type, should never be used");
return "";
@ -378,7 +382,9 @@ void ImageManager::load_image_metadata(Image *img)
metadata.detect_colorspace();
assert(features.has_nanovdb || (metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT ||
metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3));
metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3 ||
metadata.type != IMAGE_DATA_TYPE_NANOVDB_FPN ||
metadata.type != IMAGE_DATA_TYPE_NANOVDB_FP16));
img->need_metadata = false;
}
@ -796,7 +802,8 @@ void ImageManager::device_load_image(Device *device, Scene *scene, int slot, Pro
}
}
#ifdef WITH_NANOVDB
else if (type == IMAGE_DATA_TYPE_NANOVDB_FLOAT || type == IMAGE_DATA_TYPE_NANOVDB_FLOAT3) {
else if (type == IMAGE_DATA_TYPE_NANOVDB_FLOAT || type == IMAGE_DATA_TYPE_NANOVDB_FLOAT3 ||
type == IMAGE_DATA_TYPE_NANOVDB_FPN || type == IMAGE_DATA_TYPE_NANOVDB_FP16) {
thread_scoped_lock device_lock(device_mutex);
void *pixels = img->mem->alloc(img->metadata.byte_size, 0);

View File

@ -199,6 +199,8 @@ bool OIIOImageLoader::load_pixels(const ImageMetaData &metadata,
break;
case IMAGE_DATA_TYPE_NANOVDB_FLOAT:
case IMAGE_DATA_TYPE_NANOVDB_FLOAT3:
case IMAGE_DATA_TYPE_NANOVDB_FPN:
case IMAGE_DATA_TYPE_NANOVDB_FP16:
case IMAGE_DATA_NUM_TYPES:
break;
}

View File

@ -44,14 +44,30 @@ struct ToDenseOp {
# ifdef WITH_NANOVDB
struct ToNanoOp {
nanovdb::GridHandle<> nanogrid;
int precision;
template<typename GridType, typename FloatGridType, typename FloatDataType, int channels>
bool operator()(const openvdb::GridBase::ConstPtr &grid)
{
if constexpr (!std::is_same_v<GridType, openvdb::MaskGrid>) {
try {
nanogrid = nanovdb::openToNanoVDB(
FloatGridType(*openvdb::gridConstPtrCast<GridType>(grid)));
FloatGridType floatgrid(*openvdb::gridConstPtrCast<GridType>(grid));
if constexpr (std::is_same_v<FloatGridType, openvdb::FloatGrid>) {
if (precision == 0) {
nanogrid = nanovdb::openToNanoVDB<nanovdb::HostBuffer,
typename FloatGridType::TreeType,
nanovdb::FpN>(floatgrid);
return true;
}
else if (precision == 16) {
nanogrid = nanovdb::openToNanoVDB<nanovdb::HostBuffer,
typename FloatGridType::TreeType,
nanovdb::Fp16>(floatgrid);
return true;
}
}
nanogrid = nanovdb::openToNanoVDB(floatgrid);
}
catch (const std::exception &e) {
VLOG(1) << "Error converting OpenVDB to NanoVDB grid: " << e.what();
@ -102,6 +118,7 @@ bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMet
openvdb::tools::pruneInactive(pruned_grid.tree());
nanogrid = nanovdb::openToNanoVDB(pruned_grid);*/
ToNanoOp op;
op.precision = precision;
if (!openvdb::grid_type_operation(grid, op)) {
return false;
}
@ -124,7 +141,15 @@ bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMet
if (nanogrid) {
metadata.byte_size = nanogrid.size();
if (metadata.channels == 1) {
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT;
if (precision == 0) {
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FPN;
}
else if (precision == 16) {
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FP16;
}
else {
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT;
}
}
else {
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT3;

View File

@ -51,6 +51,7 @@ class VDBImageLoader : public ImageLoader {
#endif
#ifdef WITH_NANOVDB
nanovdb::GridHandle<> nanogrid;
int precision = 0;
#endif
};

View File

@ -327,9 +327,11 @@ float Object::compute_volume_step_size() const
/* Auto detect step size. */
float3 size = one_float3();
#ifdef WITH_NANOVDB
/* Dimensions were not applied to image transform with NanOVDB (see image_vdb.cpp) */
/* Dimensions were not applied to image transform with NanoVDB (see image_vdb.cpp) */
if (metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT &&
metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3)
metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3 &&
metadata.type != IMAGE_DATA_TYPE_NANOVDB_FPN &&
metadata.type != IMAGE_DATA_TYPE_NANOVDB_FP16)
#endif
size /= make_float3(metadata.width, metadata.height, metadata.depth);

View File

@ -5882,7 +5882,7 @@ void BlackbodyNode::constant_fold(const ConstantFolder &folder)
if (folder.all_inputs_constant()) {
const float3 rgb_rec709 = svm_math_blackbody_color_rec709(temperature);
const float3 rgb = folder.scene->shader_manager->rec709_to_scene_linear(rgb_rec709);
folder.make_constant(rgb);
folder.make_constant(max(rgb, zero_float3()));
}
}

View File

@ -946,7 +946,7 @@ TEST_F(RenderGraph, constant_fold_bright_contrast)
TEST_F(RenderGraph, constant_fold_blackbody)
{
EXPECT_ANY_MESSAGE(log);
CORRECT_INFO_MESSAGE(log, "Folding Blackbody::Color to constant (3.94163, 0.226523, 0).");
CORRECT_INFO_MESSAGE(log, "Folding Blackbody::Color to constant (3.96553, 0.227897, 0).");
builder
.add_node(ShaderNodeBuilder<BlackbodyNode>(graph, "Blackbody").set("Temperature", 1200.0f))

View File

@ -37,6 +37,8 @@ typedef enum ImageDataType {
IMAGE_DATA_TYPE_USHORT = 7,
IMAGE_DATA_TYPE_NANOVDB_FLOAT = 8,
IMAGE_DATA_TYPE_NANOVDB_FLOAT3 = 9,
IMAGE_DATA_TYPE_NANOVDB_FPN = 10,
IMAGE_DATA_TYPE_NANOVDB_FP16 = 11,
IMAGE_DATA_NUM_TYPES
} ImageDataType;

View File

@ -138,10 +138,10 @@ ATTR_NO_ASAN static int weight_pixel_format(PIXELFORMATDESCRIPTOR &pfd,
/* cull unusable pixel formats */
/* if no formats can be found, can we determine why it was rejected? */
if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
!(pfd.dwFlags & PFD_DOUBLEBUFFER) || /* Blender _needs_ this */
!(pfd.dwFlags & PFD_DOUBLEBUFFER) || /* Blender _needs_ this. */
!(pfd.iPixelType == PFD_TYPE_RGBA) ||
(pfd.cColorBits > 32) || /* 64 bit formats disable aero */
(pfd.dwFlags & PFD_GENERIC_FORMAT)) /* no software renderers */
(pfd.cColorBits > 32) || /* 64 bit formats disable AERO. */
(pfd.dwFlags & PFD_GENERIC_FORMAT)) /* No software renderers. */
{
return 0;
}

View File

@ -967,7 +967,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
return anyProcessed;
}
// Note: called from NSApplication delegate
/* NOTE: called from #NSApplication delegate. */
GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
{
for (GHOST_IWindow *iwindow : m_windowManager->getWindows()) {
@ -1046,7 +1046,7 @@ void GHOST_SystemCocoa::notifyExternalEventProcessed()
m_outsideLoopEventProcessed = true;
}
// Note: called from NSWindow delegate
/* NOTE: called from #NSWindow delegate. */
GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
GHOST_WindowCocoa *window)
{
@ -1108,7 +1108,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
return GHOST_kSuccess;
}
// Note: called from NSWindow subclass
/* NOTE: called from #NSWindow subclass. */
GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType,
GHOST_TDragnDropTypes draggedObjectType,
GHOST_WindowCocoa *window,

View File

@ -761,7 +761,7 @@ static void data_device_selection(void *data,
input->data_offer_copy_paste = data_offer;
std::string mime_receive;
for (const std::string &type : {mime_text_utf8, mime_text_plain}) {
for (const std::string type : {mime_text_utf8, mime_text_plain}) {
if (data_offer->types.count(type)) {
mime_receive = type;
break;

View File

@ -63,7 +63,7 @@
#include <stdio.h> /* for fprintf only */
#include <vector>
/* for debugging - so we can breakpoint X11 errors */
/* For debugging, so we can break-point X11 errors. */
// #define USE_X11_ERROR_HANDLERS
#ifdef WITH_X11_XINPUT
@ -1117,7 +1117,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
#else
/* In keyboards like Latin ones,
* numbers needs a 'Shift' to be accessed but key_sym
* is unmodified (or anyone swapping the keys with xmodmap).
* is unmodified (or anyone swapping the keys with `xmodmap`).
*
* Here we look at the 'Shifted' version of the key.
* If it is a number, then we take it instead of the normal key.
@ -2492,7 +2492,7 @@ GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType,
}
#endif
/**
* These callbacks can be used for debugging, so we can breakpoint on an X11 error.
* These callbacks can be used for debugging, so we can break-point on an X11 error.
*
* Dummy function to get around IO Handler exiting if device invalid
* Basically it will not crash blender now if you have a X device that

View File

@ -426,8 +426,8 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
[m_window close];
}
// Check for other blender opened windows and make the frontmost key
// Note: for some reason the closed window is still in the list
/* Check for other blender opened windows and make the front-most key
* NOTE: for some reason the closed window is still in the list. */
NSArray *windowsList = [NSApp orderedWindows];
for (int a = 0; a < [windowsList count]; a++) {
if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) {

View File

@ -322,7 +322,7 @@ void GHOST_WindowWin32::adjustWindowRectForClosestMonitor(LPRECT win_rect,
}
/* Adjust to allow for caption, borders, shadows, scaling, etc. Resulting values can be
* correctly outside of monitor bounds. Note: You cannot specify WS_OVERLAPPED when calling. */
* correctly outside of monitor bounds. NOTE: You cannot specify #WS_OVERLAPPED when calling. */
if (fpAdjustWindowRectExForDpi) {
UINT dpiX, dpiY;
GetDpiForMonitor(hmonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);

View File

@ -54,7 +54,7 @@
# define DEBUG_MEMCOUNTER_ERROR_VAL 0
static int _mallocn_count = 0;
/* breakpoint here */
/* Break-point here. */
static void memcount_raise(const char *name)
{
fprintf(stderr, "%s: memcount-leak, %d\n", name, _mallocn_count);

View File

@ -116,7 +116,7 @@ void IK_QOrientationTask::ComputeJacobian(IK_QJacobian &jacobian)
}
// IK_QCenterOfMassTask
// Note: implementation not finished!
// NOTE: implementation not finished!
IK_QCenterOfMassTask::IK_QCenterOfMassTask(bool primary,
const IK_QSegment *segment,

View File

@ -118,7 +118,7 @@ void EuclideanResectionAnsarDaniilidis(const Mat2X& x_camera,
* This is the algorithm described in:
* "{EP$n$P: An Accurate $O(n)$ Solution to the P$n$P Problem", by V. Lepetit
* and F. Moreno-Noguer and P. Fua, IJCV 2009. vol. 81, no. 2
* \note: the non-linear optimization is not implemented here.
* \note the non-linear optimization is not implemented here.
*/
bool EuclideanResectionEPnP(const Mat2X& x_camera,
const Mat3X& X_world,

View File

@ -241,10 +241,11 @@ void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/,
rgb[2] = 0.0722f;
}
void FallbackImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr * /*config*/, float xyz_to_rgb[3][3])
void FallbackImpl::configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr * /*config*/,
float xyz_to_scene_linear[3][3])
{
/* Default to ITU-BT.709. */
memcpy(xyz_to_rgb, OCIO_XYZ_TO_LINEAR_SRGB, sizeof(OCIO_XYZ_TO_LINEAR_SRGB));
memcpy(xyz_to_scene_linear, OCIO_XYZ_TO_REC709, sizeof(OCIO_XYZ_TO_REC709));
}
int FallbackImpl::configGetNumLooks(OCIO_ConstConfigRcPtr * /*config*/)

View File

@ -118,9 +118,9 @@ void OCIO_configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb)
impl->configGetDefaultLumaCoefs(config, rgb);
}
void OCIO_configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3])
void OCIO_configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr *config, float xyz_to_scene_linear[3][3])
{
impl->configGetXYZtoRGB(config, xyz_to_rgb);
impl->configGetXYZtoSceneLinear(config, xyz_to_scene_linear);
}
int OCIO_configGetNumLooks(OCIO_ConstConfigRcPtr *config)

View File

@ -31,10 +31,15 @@ OCIO_DECLARE_HANDLE(OCIO_ConstContextRcPtr);
OCIO_DECLARE_HANDLE(OCIO_PackedImageDesc);
OCIO_DECLARE_HANDLE(OCIO_ConstLookRcPtr);
/* Standard XYZ to linear sRGB transform, for fallback. */
static const float OCIO_XYZ_TO_LINEAR_SRGB[3][3] = {{3.2404542f, -0.9692660f, 0.0556434f},
{-1.5371385f, 1.8760108f, -0.2040259f},
{-0.4985314f, 0.0415560f, 1.0572252f}};
/* Standard XYZ (D65) to linear Rec.709 transform. */
static const float OCIO_XYZ_TO_REC709[3][3] = {{3.2404542f, -0.9692660f, 0.0556434f},
{-1.5371385f, 1.8760108f, -0.2040259f},
{-0.4985314f, 0.0415560f, 1.0572252f}};
/* Standard ACES to XYZ (D65) transform.
* Matches OpenColorIO builtin transform: UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD. */
static const float OCIO_ACES_TO_XYZ[3][3] = {{0.938280f, 0.337369f, 0.001174f},
{-0.004451f, 0.729522f, -0.003711f},
{0.016628f, -0.066890f, 1.091595f}};
/* This structure is used to pass curve mapping settings from
* blender's DNA structure stored in view transform settings
@ -130,7 +135,8 @@ const char *OCIO_configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
const char *view);
void OCIO_configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
void OCIO_configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
void OCIO_configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr *config,
float xyz_to_scene_linear[3][3]);
int OCIO_configGetNumLooks(OCIO_ConstConfigRcPtr *config);
const char *OCIO_configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);

View File

@ -311,13 +311,14 @@ static bool to_scene_linear_matrix(ConstConfigRcPtr &config,
return true;
}
void OCIOImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config_, float xyz_to_rgb[3][3])
void OCIOImpl::configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr *config_,
float xyz_to_scene_linear[3][3])
{
ConstConfigRcPtr config = (*(ConstConfigRcPtr *)config_);
/* Default to ITU-BT.709 in case no appropriate transform found.
* Note XYZ is defined here as having a D65 white point. */
memcpy(xyz_to_rgb, OCIO_XYZ_TO_LINEAR_SRGB, sizeof(OCIO_XYZ_TO_LINEAR_SRGB));
memcpy(xyz_to_scene_linear, OCIO_XYZ_TO_REC709, sizeof(OCIO_XYZ_TO_REC709));
/* Get from OpenColorO config if it has the required roles. */
if (!config->hasRole(ROLE_SCENE_LINEAR)) {
@ -326,22 +327,17 @@ void OCIOImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config_, float xyz_to_rg
if (config->hasRole("aces_interchange")) {
/* Standard OpenColorIO role, defined as ACES AP0 (ACES2065-1). */
float aces_to_rgb[3][3];
if (to_scene_linear_matrix(config, "aces_interchange", aces_to_rgb)) {
/* This is the OpenColorIO builtin transform:
* UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD. */
const float ACES_AP0_to_xyz_D65[3][3] = {{0.938280f, 0.337369f, 0.001174f},
{-0.004451f, 0.729522f, -0.003711f},
{0.016628f, -0.066890f, 1.091595f}};
float aces_to_scene_linear[3][3];
if (to_scene_linear_matrix(config, "aces_interchange", aces_to_scene_linear)) {
float xyz_to_aces[3][3];
invert_m3_m3(xyz_to_aces, ACES_AP0_to_xyz_D65);
invert_m3_m3(xyz_to_aces, OCIO_ACES_TO_XYZ);
mul_m3_m3m3(xyz_to_rgb, aces_to_rgb, xyz_to_aces);
mul_m3_m3m3(xyz_to_scene_linear, aces_to_scene_linear, xyz_to_aces);
}
}
else if (config->hasRole("XYZ")) {
/* Custom role used before the standard existed. */
to_scene_linear_matrix(config, "XYZ", xyz_to_rgb);
to_scene_linear_matrix(config, "XYZ", xyz_to_scene_linear);
}
}

View File

@ -48,7 +48,8 @@ class IOCIOImpl {
const char *view) = 0;
virtual void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb) = 0;
virtual void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]) = 0;
virtual void configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr *config,
float xyz_to_scene_linear[3][3]) = 0;
virtual int configGetNumLooks(OCIO_ConstConfigRcPtr *config) = 0;
virtual const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index) = 0;
@ -167,7 +168,7 @@ class FallbackImpl : public IOCIOImpl {
const char *view);
void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
void configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr *config, float xyz_to_scene_linear[3][3]);
int configGetNumLooks(OCIO_ConstConfigRcPtr *config);
const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
@ -257,7 +258,7 @@ class OCIOImpl : public IOCIOImpl {
const char *view);
void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
void configGetXYZtoSceneLinear(OCIO_ConstConfigRcPtr *config, float xyz_to_scene_linear[3][3]);
int configGetNumLooks(OCIO_ConstConfigRcPtr *config);
const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);

View File

@ -46,6 +46,8 @@ class EvalOutputAPI::EvalOutput {
virtual void updateVaryingData(const float *src, int start_vertex, int num_vertices) = 0;
virtual void updateVertexData(const float *src, int start_vertex, int num_vertices) = 0;
virtual void updateFaceVaryingData(const int face_varying_channel,
const float *src,
int start_vertex,
@ -70,6 +72,11 @@ class EvalOutputAPI::EvalOutput {
const int num_patch_coords,
float *varying) = 0;
// NOTE: vertex_data must point to a memory of at least float*num_vertex_data.
virtual void evalPatchesVertexData(const PatchCoord *patch_coord,
const int num_patch_coords,
float *vertex_data) = 0;
virtual void evalPatchesFaceVarying(const int face_varying_channel,
const PatchCoord *patch_coord,
const int num_patch_coords,
@ -96,6 +103,10 @@ class EvalOutputAPI::EvalOutput {
{
}
virtual void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer * /*src_buffer*/)
{
}
virtual void fillFVarPatchArraysBuffer(const int /*face_varying_channel*/,
OpenSubdiv_Buffer * /*patch_arrays_buffer*/)
{
@ -115,6 +126,11 @@ class EvalOutputAPI::EvalOutput {
OpenSubdiv_Buffer * /*src_buffer*/)
{
}
virtual bool hasVertexData() const
{
return false;
}
};
namespace {
@ -331,11 +347,13 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
const StencilTable *varying_stencils,
const vector<const StencilTable *> &all_face_varying_stencils,
const int face_varying_width,
const int vertex_data_width,
const PatchTable *patch_table,
EvaluatorCache *evaluator_cache = NULL,
DEVICE_CONTEXT *device_context = NULL)
: src_desc_(0, 3, 3),
src_varying_desc_(0, 3, 3),
src_vertex_data_desc_(0, vertex_data_width, vertex_data_width),
face_varying_width_(face_varying_width),
evaluator_cache_(evaluator_cache),
device_context_(device_context)
@ -352,16 +370,26 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
device_context_);
varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
device_context_);
// Optionally allocate additional data to be subdivided like vertex coordinates.
if (vertex_data_width > 0) {
src_vertex_data_ = SRC_VERTEX_BUFFER::Create(
vertex_data_width, num_total_vertices, device_context_);
}
else {
src_vertex_data_ = NULL;
}
// Create evaluators for every face varying channel.
face_varying_evaluators.reserve(all_face_varying_stencils.size());
face_varying_evaluators_.reserve(all_face_varying_stencils.size());
int face_varying_channel = 0;
for (const StencilTable *face_varying_stencils : all_face_varying_stencils) {
face_varying_evaluators.push_back(new FaceVaryingEval(face_varying_channel,
face_varying_stencils,
face_varying_width,
patch_table_,
evaluator_cache_,
device_context_));
face_varying_evaluators_.push_back(new FaceVaryingEval(face_varying_channel,
face_varying_stencils,
face_varying_width,
patch_table_,
evaluator_cache_,
device_context_));
++face_varying_channel;
}
}
@ -370,10 +398,11 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
{
delete src_data_;
delete src_varying_data_;
delete src_vertex_data_;
delete patch_table_;
delete vertex_stencils_;
delete varying_stencils_;
for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators) {
for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators_) {
delete face_varying_evaluator;
}
}
@ -390,14 +419,19 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
src_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
}
void updateVertexData(const float *src, int start_vertex, int num_vertices) override
{
src_vertex_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
}
void updateFaceVaryingData(const int face_varying_channel,
const float *src,
int start_vertex,
int num_vertices) override
{
assert(face_varying_channel >= 0);
assert(face_varying_channel < face_varying_evaluators.size());
face_varying_evaluators[face_varying_channel]->updateData(src, start_vertex, num_vertices);
assert(face_varying_channel < face_varying_evaluators_.size());
face_varying_evaluators_[face_varying_channel]->updateData(src, start_vertex, num_vertices);
}
bool hasVaryingData() const
@ -409,7 +443,12 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
bool hasFaceVaryingData() const
{
return face_varying_evaluators.size() != 0;
return face_varying_evaluators_.size() != 0;
}
bool hasVertexData() const override
{
return src_vertex_data_ != nullptr;
}
void refine() override
@ -426,6 +465,22 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
vertex_stencils_,
eval_instance,
device_context_);
// Evaluate smoothly interpolated vertex data.
if (src_vertex_data_) {
BufferDescriptor dst_vertex_data_desc = src_vertex_data_desc_;
dst_vertex_data_desc.offset += num_coarse_vertices_ * src_vertex_data_desc_.stride;
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
evaluator_cache_, src_vertex_data_desc_, dst_vertex_data_desc, device_context_);
EVALUATOR::EvalStencils(src_vertex_data_,
src_vertex_data_desc_,
src_vertex_data_,
dst_vertex_data_desc,
vertex_stencils_,
eval_instance,
device_context_);
}
// Evaluate varying data.
if (hasVaryingData()) {
BufferDescriptor dst_varying_desc = src_varying_desc_;
@ -442,7 +497,7 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
}
// Evaluate face-varying data.
if (hasFaceVaryingData()) {
for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators) {
for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators_) {
face_varying_evaluator->refine();
}
}
@ -521,14 +576,35 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
device_context_);
}
// NOTE: data must point to a memory of at least float*num_vertex_data.
void evalPatchesVertexData(const PatchCoord *patch_coord,
const int num_patch_coords,
float *data) override
{
RawDataWrapperBuffer<float> vertex_data(data);
BufferDescriptor vertex_desc(0, src_vertex_data_desc_.length, src_vertex_data_desc_.length);
ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
evaluator_cache_, src_vertex_data_desc_, vertex_desc, device_context_);
EVALUATOR::EvalPatches(src_vertex_data_,
src_vertex_data_desc_,
&vertex_data,
vertex_desc,
patch_coord_buffer.GetNumVertices(),
&patch_coord_buffer,
patch_table_,
eval_instance,
device_context_);
}
void evalPatchesFaceVarying(const int face_varying_channel,
const PatchCoord *patch_coord,
const int num_patch_coords,
float face_varying[2]) override
{
assert(face_varying_channel >= 0);
assert(face_varying_channel < face_varying_evaluators.size());
face_varying_evaluators[face_varying_channel]->evalPatches(
assert(face_varying_channel < face_varying_evaluators_.size());
face_varying_evaluators_[face_varying_channel]->evalPatches(
patch_coord, num_patch_coords, face_varying);
}
@ -537,6 +613,11 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
return src_data_;
}
SRC_VERTEX_BUFFER *getSrcVertexDataBuffer() const
{
return src_vertex_data_;
}
PATCH_TABLE *getPatchTable() const
{
return patch_table_;
@ -544,25 +625,27 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
SRC_VERTEX_BUFFER *getFVarSrcBuffer(const int face_varying_channel) const
{
return face_varying_evaluators[face_varying_channel]->getSrcBuffer();
return face_varying_evaluators_[face_varying_channel]->getSrcBuffer();
}
int getFVarSrcBufferOffset(const int face_varying_channel) const
{
return face_varying_evaluators[face_varying_channel]->getFVarSrcBufferOffset();
return face_varying_evaluators_[face_varying_channel]->getFVarSrcBufferOffset();
}
PATCH_TABLE *getFVarPatchTable(const int face_varying_channel) const
{
return face_varying_evaluators[face_varying_channel]->getPatchTable();
return face_varying_evaluators_[face_varying_channel]->getPatchTable();
}
private:
SRC_VERTEX_BUFFER *src_data_;
SRC_VERTEX_BUFFER *src_varying_data_;
SRC_VERTEX_BUFFER *src_vertex_data_;
PATCH_TABLE *patch_table_;
BufferDescriptor src_desc_;
BufferDescriptor src_varying_desc_;
BufferDescriptor src_vertex_data_desc_;
int num_coarse_vertices_;
@ -570,7 +653,7 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
const STENCIL_TABLE *varying_stencils_;
int face_varying_width_;
vector<FaceVaryingEval *> face_varying_evaluators;
vector<FaceVaryingEval *> face_varying_evaluators_;
EvaluatorCache *evaluator_cache_;
DEVICE_CONTEXT *device_context_;

View File

@ -32,7 +32,7 @@ using OpenSubdiv::Osd::CpuVertexBuffer;
namespace blender {
namespace opensubdiv {
// Note: Define as a class instead of typedef to make it possible
// NOTE: Define as a class instead of typedef to make it possible
// to have anonymous class in opensubdiv_evaluator_internal.h
class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
CpuVertexBuffer,
@ -44,6 +44,7 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
const StencilTable *varying_stencils,
const vector<const StencilTable *> &all_face_varying_stencils,
const int face_varying_width,
const int vertex_data_width,
const PatchTable *patch_table,
EvaluatorCache *evaluator_cache = NULL)
: VolatileEvalOutput<CpuVertexBuffer,
@ -54,6 +55,7 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
varying_stencils,
all_face_varying_stencils,
face_varying_width,
vertex_data_width,
patch_table,
evaluator_cache)
{

View File

@ -45,6 +45,7 @@ GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils,
const StencilTable *varying_stencils,
const vector<const StencilTable *> &all_face_varying_stencils,
const int face_varying_width,
const int vertex_data_width,
const PatchTable *patch_table,
VolatileEvalOutput::EvaluatorCache *evaluator_cache)
: VolatileEvalOutput<GLVertexBuffer,
@ -55,6 +56,7 @@ GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils,
varying_stencils,
all_face_varying_stencils,
face_varying_width,
vertex_data_width,
patch_table,
evaluator_cache)
{
@ -84,6 +86,12 @@ void GpuEvalOutput::wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer)
src_buffer->wrap_device_handle(src_buffer, vertex_buffer->BindVBO());
}
void GpuEvalOutput::wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer)
{
GLVertexBuffer *vertex_buffer = getSrcVertexDataBuffer();
src_buffer->wrap_device_handle(src_buffer, vertex_buffer->BindVBO());
}
void GpuEvalOutput::fillFVarPatchArraysBuffer(const int face_varying_channel,
OpenSubdiv_Buffer *patch_arrays_buffer)
{

View File

@ -40,6 +40,7 @@ class GpuEvalOutput : public VolatileEvalOutput<GLVertexBuffer,
const StencilTable *varying_stencils,
const vector<const StencilTable *> &all_face_varying_stencils,
const int face_varying_width,
const int vertex_data_width,
const PatchTable *patch_table,
EvaluatorCache *evaluator_cache = NULL);
@ -51,6 +52,8 @@ class GpuEvalOutput : public VolatileEvalOutput<GLVertexBuffer,
void wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer) override;
void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer) override;
void fillFVarPatchArraysBuffer(const int face_varying_channel,
OpenSubdiv_Buffer *patch_arrays_buffer) override;

View File

@ -36,6 +36,14 @@ void setCoarsePositions(OpenSubdiv_Evaluator *evaluator,
evaluator->impl->eval_output->setCoarsePositions(positions, start_vertex_index, num_vertices);
}
void setVertexData(OpenSubdiv_Evaluator *evaluator,
const float *vertex_data,
const int start_vertex_index,
const int num_vertices)
{
evaluator->impl->eval_output->setVertexData(vertex_data, start_vertex_index, num_vertices);
}
void setVaryingData(OpenSubdiv_Evaluator *evaluator,
const float *varying_data,
const int start_vertex_index,
@ -115,6 +123,15 @@ void evaluatePatchesLimit(OpenSubdiv_Evaluator *evaluator,
patch_coords, num_patch_coords, P, dPdu, dPdv);
}
void evaluateVertexData(OpenSubdiv_Evaluator *evaluator,
const int ptex_face_index,
float face_u,
float face_v,
float vertex_data[3])
{
evaluator->impl->eval_output->evaluateVertexData(ptex_face_index, face_u, face_v, vertex_data);
}
void evaluateVarying(OpenSubdiv_Evaluator *evaluator,
const int ptex_face_index,
float face_u,
@ -174,6 +191,12 @@ void wrapSrcBuffer(struct OpenSubdiv_Evaluator *evaluator, struct OpenSubdiv_Buf
evaluator->impl->eval_output->wrapSrcBuffer(src_buffer);
}
void wrapSrcVertexDataBuffer(struct OpenSubdiv_Evaluator *evaluator,
struct OpenSubdiv_Buffer *src_buffer)
{
evaluator->impl->eval_output->wrapSrcVertexDataBuffer(src_buffer);
}
void fillFVarPatchArraysBuffer(struct OpenSubdiv_Evaluator *evaluator,
const int face_varying_channel,
struct OpenSubdiv_Buffer *patch_array_buffer)
@ -203,9 +226,15 @@ void wrapFVarSrcBuffer(struct OpenSubdiv_Evaluator *evaluator,
evaluator->impl->eval_output->wrapFVarSrcBuffer(face_varying_channel, src_buffer);
}
bool hasVertexData(struct OpenSubdiv_Evaluator *evaluator)
{
return evaluator->impl->eval_output->hasVertexData();
}
void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
{
evaluator->setCoarsePositions = setCoarsePositions;
evaluator->setVertexData = setVertexData;
evaluator->setVaryingData = setVaryingData;
evaluator->setFaceVaryingData = setFaceVaryingData;
@ -217,6 +246,7 @@ void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
evaluator->evaluateLimit = evaluateLimit;
evaluator->evaluateVarying = evaluateVarying;
evaluator->evaluateVertexData = evaluateVertexData;
evaluator->evaluateFaceVarying = evaluateFaceVarying;
evaluator->evaluatePatchesLimit = evaluatePatchesLimit;
@ -227,11 +257,14 @@ void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
evaluator->wrapPatchIndexBuffer = wrapPatchIndexBuffer;
evaluator->wrapPatchParamBuffer = wrapPatchParamBuffer;
evaluator->wrapSrcBuffer = wrapSrcBuffer;
evaluator->wrapSrcVertexDataBuffer = wrapSrcVertexDataBuffer;
evaluator->fillFVarPatchArraysBuffer = fillFVarPatchArraysBuffer;
evaluator->wrapFVarPatchIndexBuffer = wrapFVarPatchIndexBuffer;
evaluator->wrapFVarPatchParamBuffer = wrapFVarPatchParamBuffer;
evaluator->wrapFVarSrcBuffer = wrapFVarSrcBuffer;
evaluator->hasVertexData = hasVertexData;
}
} // namespace
@ -239,12 +272,16 @@ void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
OpenSubdiv_TopologyRefiner *topology_refiner,
eOpenSubdivEvaluator evaluator_type,
OpenSubdiv_EvaluatorCache *evaluator_cache)
OpenSubdiv_EvaluatorCache *evaluator_cache,
const OpenSubdiv_EvaluatorSettings *settings)
{
OpenSubdiv_Evaluator *evaluator = MEM_new<OpenSubdiv_Evaluator>(__func__);
assignFunctionPointers(evaluator);
evaluator->impl = openSubdiv_createEvaluatorInternal(
topology_refiner, evaluator_type, evaluator_cache ? evaluator_cache->impl : nullptr);
evaluator->impl = openSubdiv_createEvaluatorInternal(topology_refiner,
evaluator_type,
evaluator_cache ? evaluator_cache->impl :
nullptr,
settings);
evaluator->type = evaluator->impl ? evaluator_type : static_cast<eOpenSubdivEvaluator>(0);
return evaluator;
}

View File

@ -182,6 +182,14 @@ void EvalOutputAPI::setVaryingData(const float *varying_data,
implementation_->updateVaryingData(varying_data, start_vertex_index, num_vertices);
}
void EvalOutputAPI::setVertexData(const float *vertex_data,
const int start_vertex_index,
const int num_vertices)
{
// TODO(sergey): Add sanity check on indices.
implementation_->updateVertexData(vertex_data, start_vertex_index, num_vertices);
}
void EvalOutputAPI::setFaceVaryingData(const int face_varying_channel,
const float *face_varying_data,
const int start_vertex_index,
@ -286,6 +294,20 @@ void EvalOutputAPI::evaluateVarying(const int ptex_face_index,
implementation_->evalPatchesVarying(&patch_coord, 1, varying);
}
void EvalOutputAPI::evaluateVertexData(const int ptex_face_index,
float face_u,
float face_v,
float vertex_data[])
{
assert(face_u >= 0.0f);
assert(face_u <= 1.0f);
assert(face_v >= 0.0f);
assert(face_v <= 1.0f);
const PatchTable::PatchHandle *handle = patch_map_->FindPatch(ptex_face_index, face_u, face_v);
PatchCoord patch_coord(*handle, face_u, face_v);
implementation_->evalPatchesVertexData(&patch_coord, 1, vertex_data);
}
void EvalOutputAPI::evaluateFaceVarying(const int face_varying_channel,
const int ptex_face_index,
float face_u,
@ -361,6 +383,11 @@ void EvalOutputAPI::wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer)
implementation_->wrapSrcBuffer(src_buffer);
}
void EvalOutputAPI::wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer)
{
implementation_->wrapSrcVertexDataBuffer(src_buffer);
}
void EvalOutputAPI::fillFVarPatchArraysBuffer(const int face_varying_channel,
OpenSubdiv_Buffer *patch_arrays_buffer)
{
@ -385,6 +412,11 @@ void EvalOutputAPI::wrapFVarSrcBuffer(const int face_varying_channel,
implementation_->wrapFVarSrcBuffer(face_varying_channel, src_buffer);
}
bool EvalOutputAPI::hasVertexData() const
{
return implementation_->hasVertexData();
}
} // namespace opensubdiv
} // namespace blender
@ -403,7 +435,8 @@ OpenSubdiv_EvaluatorImpl::~OpenSubdiv_EvaluatorImpl()
OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
OpenSubdiv_TopologyRefiner *topology_refiner,
eOpenSubdivEvaluator evaluator_type,
OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr)
OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr,
const OpenSubdiv_EvaluatorSettings *settings)
{
// Only CPU and GLCompute are implemented at the moment.
if (evaluator_type != OPENSUBDIV_EVALUATOR_CPU &&
@ -422,6 +455,7 @@ OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
const bool has_face_varying_data = (num_face_varying_channels != 0);
const int level = topology_refiner->getSubdivisionLevel(topology_refiner);
const bool is_adaptive = topology_refiner->getIsAdaptive(topology_refiner);
const int vertex_data_width = settings->num_vertex_data;
// Common settings for stencils and patches.
const bool stencil_generate_intermediate_levels = is_adaptive;
const bool stencil_generate_offsets = true;
@ -526,12 +560,17 @@ OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
varying_stencils,
all_face_varying_stencils,
2,
vertex_data_width,
patch_table,
evaluator_cache);
}
else {
eval_output = new blender::opensubdiv::CpuEvalOutput(
vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
eval_output = new blender::opensubdiv::CpuEvalOutput(vertex_stencils,
varying_stencils,
all_face_varying_stencils,
2,
vertex_data_width,
patch_table);
}
blender::opensubdiv::PatchMap *patch_map = new blender::opensubdiv::PatchMap(*patch_table);

View File

@ -32,6 +32,7 @@
struct OpenSubdiv_Buffer;
struct OpenSubdiv_EvaluatorCacheImpl;
struct OpenSubdiv_EvaluatorSettings;
struct OpenSubdiv_PatchCoord;
struct OpenSubdiv_TopologyRefiner;
@ -60,6 +61,8 @@ class EvalOutputAPI {
void setCoarsePositions(const float *positions,
const int start_vertex_index,
const int num_vertices);
// Set vertex data from a continuous array of data.
void setVertexData(const float *data, const int start_vertex_index, const int num_vertices);
// Set varying data from a continuous array of data.
void setVaryingData(const float *varying_data,
const int start_vertex_index,
@ -114,6 +117,9 @@ class EvalOutputAPI {
float dPdu[3],
float dPdv[3]);
// Evaluate varying data at a given bilinear coordinate of given ptex face.
void evaluateVertexData(const int ptes_face_index, float face_u, float face_v, float data[]);
// Evaluate varying data at a given bilinear coordinate of given ptex face.
void evaluateVarying(const int ptes_face_index, float face_u, float face_v, float varying[3]);
@ -157,6 +163,9 @@ class EvalOutputAPI {
// Wrap the buffer used by OpenSubDiv for the source data with the given buffer.
void wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer);
// Wrap the buffer used by OpenSubDiv for the extra source data with the given buffer.
void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer);
// Copy the patch arrays buffer used by OpenSubDiv for the face varying channel with the given
// buffer.
void fillFVarPatchArraysBuffer(const int face_varying_channel,
@ -175,6 +184,9 @@ class EvalOutputAPI {
// Wrap thebuffer used by OpenSubDiv for the face varying channel with the given buffer.
void wrapFVarSrcBuffer(const int face_varying_channel, OpenSubdiv_Buffer *src_buffer);
// Return true if source vertex data has been set.
bool hasVertexData() const;
protected:
PatchMap *patch_map_;
EvalOutput *implementation_;
@ -198,7 +210,8 @@ struct OpenSubdiv_EvaluatorImpl {
OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
struct OpenSubdiv_TopologyRefiner *topology_refiner,
eOpenSubdivEvaluator evaluator_type,
OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr);
OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr,
const OpenSubdiv_EvaluatorSettings *settings);
void openSubdiv_deleteEvaluatorInternal(OpenSubdiv_EvaluatorImpl *evaluator);

View File

@ -69,6 +69,11 @@ typedef struct OpenSubdiv_Evaluator {
const float *positions,
const int start_vertex_index,
const int num_vertices);
// Set vertex data from a continuous array of coordinates.
void (*setVertexData)(struct OpenSubdiv_Evaluator *evaluator,
const float *data,
const int start_vertex_index,
const int num_vertices);
// Set varying data from a continuous array of data.
void (*setVaryingData)(struct OpenSubdiv_Evaluator *evaluator,
const float *varying_data,
@ -129,6 +134,13 @@ typedef struct OpenSubdiv_Evaluator {
float dPdu[3],
float dPdv[3]);
// Evaluate vertex data at a given bilinear coordinate of given ptex face.
void (*evaluateVertexData)(struct OpenSubdiv_Evaluator *evaluator,
const int ptex_face_index,
float face_u,
float face_v,
float data[]);
// Evaluate varying data at a given bilinear coordinate of given ptex face.
void (*evaluateVarying)(struct OpenSubdiv_Evaluator *evaluator,
const int ptex_face_index,
@ -183,6 +195,10 @@ typedef struct OpenSubdiv_Evaluator {
void (*wrapSrcBuffer)(struct OpenSubdiv_Evaluator *evaluator,
struct OpenSubdiv_Buffer *src_buffer);
// Fill the given buffer with data from the evaluator's extra source buffer.
void (*wrapSrcVertexDataBuffer)(struct OpenSubdiv_Evaluator *evaluator,
struct OpenSubdiv_Buffer *src_buffer);
// Fill the given buffer with data from the evaluator's face varying patch array buffer.
void (*fillFVarPatchArraysBuffer)(struct OpenSubdiv_Evaluator *evaluator,
const int face_varying_channel,
@ -203,6 +219,9 @@ typedef struct OpenSubdiv_Evaluator {
const int face_varying_channel,
struct OpenSubdiv_Buffer *src_buffer);
// Return true if the evaluator has source vertex data set.
bool (*hasVertexData)(struct OpenSubdiv_Evaluator *evaluator);
// Implementation of the evaluator.
struct OpenSubdiv_EvaluatorImpl *impl;
@ -215,10 +234,16 @@ typedef struct OpenSubdiv_EvaluatorCache {
struct OpenSubdiv_EvaluatorCacheImpl *impl;
} OpenSubdiv_EvaluatorCache;
typedef struct OpenSubdiv_EvaluatorSettings {
// Number of smoothly interpolated vertex data channels.
int num_vertex_data;
} OpenSubdiv_EvaluatorSettings;
OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
struct OpenSubdiv_TopologyRefiner *topology_refiner,
eOpenSubdivEvaluator evaluator_type,
OpenSubdiv_EvaluatorCache *evaluator_cache);
OpenSubdiv_EvaluatorCache *evaluator_cache,
const OpenSubdiv_EvaluatorSettings *settings);
void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator *evaluator);

View File

@ -23,7 +23,8 @@
OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
struct OpenSubdiv_TopologyRefiner * /*topology_refiner*/,
eOpenSubdivEvaluator /*evaluator_type*/,
OpenSubdiv_EvaluatorCache * /*evaluator_cache*/)
OpenSubdiv_EvaluatorCache * /*evaluator_cache*/,
const OpenSubdiv_EvaluatorSettings * /*settings*/)
{
return NULL;
}

View File

@ -14,7 +14,7 @@ extern "C" {
#endif
/* API Notes:
* Currently, this API is optimised for Bullet RigidBodies, and doesn't
* Currently, this API is optimized for Bullet RigidBodies, and doesn't
* take into account other Physics Engines. Some tweaking may be necessary
* to allow other systems to be used, in particular there may be references
* to datatypes that aren't used here...

View File

@ -20,11 +20,6 @@ ignore = [
# Why disable? Re-ordering imports is disruptive and breaks some scripts
# that need to check if a module has already been loaded in the case of reloading.
"E402",
# Info: Try to make lines fit within --max-line-length characters.
# Why disable? Causes lines to be wrapped, where long lines have the trailing bracket moved to the end of the line.
# If trailing commas were respected as they are by clang-format this might be acceptable.
# Note that this doesn't disable all line wrapping.
"E501",
# Info: Fix various deprecated code (via lib2to3)
# Why disable? Does nothing besides incorrectly adding a duplicate import,
# could be reported as a bug except this is likely to be removed soon, see:

View File

@ -45,6 +45,8 @@ import bpy
# Generic functions
OBJECTS_TYPES_MESH_COMPATIBLE = {'CURVE', 'MESH'}
def area_tri_signed_2x_v2(v1, v2, v3):
return (v1[0] - v2[0]) * (v2[1] - v3[1]) + (v1[1] - v2[1]) * (v3[0] - v2[0])
@ -70,13 +72,14 @@ class TriMesh:
@staticmethod
def _tri_copy_from_object(ob):
import bmesh
assert(ob.type == 'MESH')
assert(ob.type in OBJECTS_TYPES_MESH_COMPATIBLE)
bm = bmesh.new()
bm.from_mesh(ob.data)
bm.from_mesh(ob.to_mesh())
bmesh.ops.triangulate(bm, faces=bm.faces)
me = bpy.data.meshes.new(ob.name + ".copy")
bm.to_mesh(me)
bm.free()
ob.to_mesh_clear()
return me
@ -125,8 +128,7 @@ def get_active_vcol(me):
def mesh_data_lists_from_mesh(me, material_colors):
me_loops = me.loops[:]
me_loops_color = get_active_vcol(me)
me_loops_color = me_loops_color.data[:] if me_loops_color else None
me_loops_color = me.attributes.active_color.data[:]
me_verts = me.vertices[:]
me_polys = me.polygons[:]
@ -178,16 +180,30 @@ def mesh_data_lists_from_mesh(me, material_colors):
v1.co.xy[:],
v2.co.xy[:],
),
# RGBA color.
tuple((
[int(c * b * 255) for c, b in zip(cn.color, base_color)]
for cn in (c0, c1, c2)
)),
# RGBA color in sRGB color space.
(
color_multiply_and_from_linear_to_srgb(base_color, c0),
color_multiply_and_from_linear_to_srgb(base_color, c1),
color_multiply_and_from_linear_to_srgb(base_color, c2),
),
))
i1 = i2
return tris_data
def color_multiply_and_from_linear_to_srgb(base_color, vertex_color):
"""
Return the RGBA color in sRGB and byte format (0-255).
base_color and vertex_color are expected in linear space.
The final color is the product between the base color and the vertex color.
"""
import mathutils
color_linear = [c * b for c, b in zip(vertex_color.color, base_color)]
color_srgb = mathutils.Color(color_linear[:3]).from_scene_linear_to_srgb()
return tuple(round(c * 255) for c in (*color_srgb, color_linear[3]))
def mesh_data_lists_from_objects(ob_parent, ob_children):
tris_data = []
@ -217,7 +233,7 @@ def write_mesh_to_py(fh, ob, ob_children):
assert(axis_range <= 255)
# -1..1 -> 0..255
f = (f + 1.0) * 0.5
f = int(round(f * axis_range))
f = round(f * axis_range)
return min(max(f, 0), axis_range)
def vert_as_byte_pair(v):
@ -314,6 +330,7 @@ def main():
args = parser.parse_args(argv)
objects = []
depsgraph = bpy.context.view_layer.depsgraph
if args.group:
group = bpy.data.collections.get(args.group)
@ -328,23 +345,25 @@ def main():
for ob in objects_source:
# Skip non-mesh objects
if ob.type != 'MESH':
if ob.type not in OBJECTS_TYPES_MESH_COMPATIBLE:
continue
name = ob.name
ob_eval = ob.evaluated_get(depsgraph)
name = ob_eval.name
# Skip copies of objects
if name.rpartition(".")[2].isdigit():
continue
if not ob.data.vertex_colors:
if not ob_eval.data.attributes.active_color:
print("Skipping:", name, "(no vertex colors)")
continue
objects.append((name, ob))
objects.append((name, ob_eval))
objects.sort(key=lambda a: a[0])
objects_children = object_child_map(bpy.data.objects)
objects_children = object_child_map(depsgraph.objects)
for name, ob in objects:
if ob.parent:

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