Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-02-16 18:02:30 +0300
committerHans Goudey <h.goudey@me.com>2022-02-16 18:02:30 +0300
commit5d0bd68cc06897c7e62988abe26268783cfb1bb9 (patch)
tree6642554c8927280a8ba49bd9c329f2a133afa60a
parent6d89120248f3dd24d2090814b29af0ca12d5d7c6 (diff)
parent5b3a415a59cef7183a2539fcc12de8fd1ebf8814 (diff)
Merge branch 'master' into bli-math-basic-typesbli-math-basic-types
-rw-r--r--extern/audaspace/plugins/wasapi/WASAPIDevice.cpp2
-rw-r--r--intern/cycles/app/CMakeLists.txt24
-rw-r--r--intern/cycles/app/cycles_standalone.cpp38
-rw-r--r--intern/cycles/app/opengl/display_driver.cpp385
-rw-r--r--intern/cycles/app/opengl/display_driver.h117
-rw-r--r--intern/cycles/app/opengl/shader.cpp197
-rw-r--r--intern/cycles/app/opengl/shader.h45
-rw-r--r--intern/cycles/app/opengl/window.cpp352
-rw-r--r--intern/cycles/app/opengl/window.h35
-rw-r--r--intern/cycles/cmake/external_libs.cmake20
-rw-r--r--intern/cycles/device/hip/device_impl.h2
-rw-r--r--intern/cycles/util/CMakeLists.txt10
-rw-r--r--intern/cycles/util/view.cpp269
-rw-r--r--intern/cycles/util/view.h35
-rw-r--r--release/scripts/startup/bl_ui/space_image.py2
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py4
-rw-r--r--source/blender/blenkernel/BKE_animsys.h3
-rw-r--r--source/blender/blenkernel/BKE_curves.h2
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h2
-rw-r--r--source/blender/blenkernel/BKE_gpencil_update_cache.h6
-rw-r--r--source/blender/blenkernel/BKE_image_partial_update.hh2
-rw-r--r--source/blender/blenkernel/BKE_modifier.h8
-rw-r--r--source/blender/blenkernel/BKE_node_tree_update.h2
-rw-r--r--source/blender/blenkernel/intern/gpencil.c2
-rw-r--r--source/blender/blenkernel/intern/gpencil_update_cache.c8
-rw-r--r--source/blender/blenkernel/intern/image_gpu.cc3
-rw-r--r--source/blender/blenkernel/intern/image_partial_update.cc2
-rw-r--r--source/blender/blenkernel/intern/mesh_calc_edges.cc1
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.cc8
-rw-r--r--source/blender/blenkernel/intern/modifier.c23
-rw-r--r--source/blender/blenkernel/intern/object.cc4
-rw-r--r--source/blender/blenlib/BLI_math_vec_types.hh8
-rw-r--r--source/blender/blenlib/intern/winstuff.c2
-rw-r--r--source/blender/blenloader/BLO_undofile.h2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl27
-rw-r--r--source/blender/draw/intern/draw_cache_impl_subdivision.cc32
-rw-r--r--source/blender/draw/intern/draw_subdivision.h5
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc39
-rw-r--r--source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl4
-rw-r--r--source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl21
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c2
-rw-r--r--source/blender/editors/include/ED_util.h2
-rw-r--r--source/blender/editors/include/ED_uvedit.h9
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate.h4
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_path.c48
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c109
-rw-r--r--source/blender/gpu/GPU_texture.h6
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc19
-rw-r--r--source/blender/io/usd/intern/usd_writer_material.h4
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h10
-rw-r--r--source/blender/makesdna/DNA_space_types.h12
-rw-r--r--source/blender/makesrna/intern/rna_scene.c26
-rw-r--r--source/blender/makesrna/intern/rna_space.c27
-rw-r--r--source/blender/python/mathutils/mathutils_noise.c40
-rw-r--r--source/blender/render/RE_pipeline.h2
58 files changed, 1469 insertions, 611 deletions
diff --git a/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp b/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
index a8387dd9489..cbf35520c3d 100644
--- a/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
+++ b/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
@@ -71,7 +71,7 @@ void WASAPIDevice::runMixingThread()
IAudioRenderClient* render_client = nullptr;
- std::chrono::milliseconds sleep_duration;
+ std::chrono::milliseconds sleep_duration(0);
bool run_init = true;
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index 75ff7114dd7..ab38e103311 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -33,15 +33,13 @@ else()
endif()
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
- list(APPEND LIBRARIES ${GLUT_LIBRARIES})
+ add_definitions(${GL_DEFINITIONS})
+ list(APPEND INC_SYS ${GLEW_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS})
+ list(APPEND LIBRARIES ${CYCLES_GL_LIBRARIES} ${SDL2_LIBRARIES})
endif()
-list(APPEND LIBRARIES ${CYCLES_GL_LIBRARIES})
-
# Common configuration.
-add_definitions(${GL_DEFINITIONS})
-
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
@@ -55,6 +53,18 @@ if(WITH_CYCLES_STANDALONE)
oiio_output_driver.cpp
oiio_output_driver.h
)
+
+ if(WITH_CYCLES_STANDALONE_GUI)
+ list(APPEND SRC
+ opengl/display_driver.cpp
+ opengl/display_driver.h
+ opengl/shader.cpp
+ opengl/shader.h
+ opengl/window.cpp
+ opengl/window.h
+ )
+ endif()
+
add_executable(cycles ${SRC} ${INC} ${INC_SYS})
unset(SRC)
@@ -69,6 +79,10 @@ if(WITH_CYCLES_STANDALONE)
# OpenImageDenoise uses BNNS from the Accelerate framework.
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework Accelerate")
endif()
+ if(WITH_CYCLES_STANDALONE_GUI)
+ set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS
+ " -framework Cocoa -framework CoreAudio -framework AudioUnit -framework AudioToolbox -framework ForceFeedback -framework CoreVideo")
+ endif()
endif()
if(UNIX AND NOT APPLE)
diff --git a/intern/cycles/app/cycles_standalone.cpp b/intern/cycles/app/cycles_standalone.cpp
index 0e425ac3d8f..ef20f64debd 100644
--- a/intern/cycles/app/cycles_standalone.cpp
+++ b/intern/cycles/app/cycles_standalone.cpp
@@ -27,11 +27,10 @@
#include "app/oiio_output_driver.h"
#ifdef WITH_CYCLES_STANDALONE_GUI
-# include "util/view.h"
+# include "opengl/display_driver.h"
+# include "opengl/window.h"
#endif
-#include "app/cycles_xml.h"
-
CCL_NAMESPACE_BEGIN
struct Options {
@@ -117,7 +116,14 @@ static void session_init()
options.output_pass = "combined";
options.session = new Session(options.session_params, options.scene_params);
- if (!options.output_filepath.empty()) {
+#ifdef WITH_CYCLES_STANDALONE_GUI
+ if (!options.session_params.background) {
+ options.session->set_display_driver(make_unique<OpenGLDisplayDriver>(
+ window_opengl_context_enable, window_opengl_context_disable));
+ }
+ else
+#endif
+ if (!options.output_filepath.empty()) {
options.session->set_output_driver(make_unique<OIIOOutputDriver>(
options.output_filepath, options.output_pass, session_print));
}
@@ -126,7 +132,7 @@ static void session_init()
options.session->progress.set_update_callback(function_bind(&session_print_status));
#ifdef WITH_CYCLES_STANDALONE_GUI
else
- options.session->progress.set_update_callback(function_bind(&view_redraw));
+ options.session->progress.set_update_callback(function_bind(&window_redraw));
#endif
/* load scene */
@@ -191,10 +197,10 @@ static void display_info(Progress &progress)
sample_time,
interactive.c_str());
- view_display_info(str.c_str());
+ window_display_info(str.c_str());
if (options.show_help)
- view_display_help();
+ window_display_help();
}
static void display()
@@ -525,15 +531,15 @@ int main(int argc, const char **argv)
string title = "Cycles: " + path_filename(options.filepath);
/* init/exit are callback so they run while GL is initialized */
- view_main_loop(title.c_str(),
- options.width,
- options.height,
- session_init,
- session_exit,
- resize,
- display,
- keyboard,
- motion);
+ window_main_loop(title.c_str(),
+ options.width,
+ options.height,
+ session_init,
+ session_exit,
+ resize,
+ display,
+ keyboard,
+ motion);
}
#endif
diff --git a/intern/cycles/app/opengl/display_driver.cpp b/intern/cycles/app/opengl/display_driver.cpp
new file mode 100644
index 00000000000..6e610b8b02c
--- /dev/null
+++ b/intern/cycles/app/opengl/display_driver.cpp
@@ -0,0 +1,385 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#include "app/opengl/display_driver.h"
+#include "app/opengl/shader.h"
+
+#include "util/log.h"
+#include "util/string.h"
+
+#include <GL/glew.h>
+#include <SDL.h>
+
+CCL_NAMESPACE_BEGIN
+
+/* --------------------------------------------------------------------
+ * OpenGLDisplayDriver.
+ */
+
+OpenGLDisplayDriver::OpenGLDisplayDriver(const function<bool()> &gl_context_enable,
+ const function<void()> &gl_context_disable)
+ : gl_context_enable_(gl_context_enable), gl_context_disable_(gl_context_disable)
+{
+}
+
+OpenGLDisplayDriver::~OpenGLDisplayDriver()
+{
+}
+
+/* --------------------------------------------------------------------
+ * Update procedure.
+ */
+
+void OpenGLDisplayDriver::next_tile_begin()
+{
+ /* Assuming no tiles used in interactive display. */
+}
+
+bool OpenGLDisplayDriver::update_begin(const Params &params, int texture_width, int texture_height)
+{
+ /* Note that it's the responsibility of OpenGLDisplayDriver to ensure updating and drawing
+ * the texture does not happen at the same time. This is achieved indirectly.
+ *
+ * When enabling the OpenGL context, it uses an internal mutex lock DST.gl_context_lock.
+ * This same lock is also held when do_draw() is called, which together ensure mutual
+ * exclusion.
+ *
+ * This locking is not performed on the Cycles side, because that would cause lock inversion. */
+ if (!gl_context_enable_()) {
+ return false;
+ }
+
+ if (gl_render_sync_) {
+ glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
+ }
+
+ if (!gl_texture_resources_ensure()) {
+ gl_context_disable_();
+ return false;
+ }
+
+ /* Update texture dimensions if needed. */
+ if (texture_.width != texture_width || texture_.height != texture_height) {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
+ glTexImage2D(
+ GL_TEXTURE_2D, 0, GL_RGBA16F, texture_width, texture_height, 0, GL_RGBA, GL_HALF_FLOAT, 0);
+ texture_.width = texture_width;
+ texture_.height = texture_height;
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* Texture did change, and no pixel storage was provided. Tag for an explicit zeroing out to
+ * avoid undefined content. */
+ texture_.need_clear = true;
+ }
+
+ /* Update PBO dimensions if needed.
+ *
+ * NOTE: Allocate the PBO for the the size which will fit the final render resolution (as in,
+ * at a resolution divider 1. This was we don't need to recreate graphics interoperability
+ * objects which are costly and which are tied to the specific underlying buffer size.
+ * The downside of this approach is that when graphics interoperability is not used we are
+ * sending too much data to GPU when resolution divider is not 1. */
+ const int buffer_width = params.full_size.x;
+ const int buffer_height = params.full_size.y;
+ if (texture_.buffer_width != buffer_width || texture_.buffer_height != buffer_height) {
+ const size_t size_in_bytes = sizeof(half4) * buffer_width * buffer_height;
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER, size_in_bytes, 0, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ texture_.buffer_width = buffer_width;
+ texture_.buffer_height = buffer_height;
+ }
+
+ /* New content will be provided to the texture in one way or another, so mark this in a
+ * centralized place. */
+ texture_.need_update = true;
+
+ return true;
+}
+
+void OpenGLDisplayDriver::update_end()
+{
+ gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ glFlush();
+
+ gl_context_disable_();
+}
+
+/* --------------------------------------------------------------------
+ * Texture buffer mapping.
+ */
+
+half4 *OpenGLDisplayDriver::map_texture_buffer()
+{
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
+
+ half4 *mapped_rgba_pixels = reinterpret_cast<half4 *>(
+ glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
+ if (!mapped_rgba_pixels) {
+ LOG(ERROR) << "Error mapping OpenGLDisplayDriver pixel buffer object.";
+ }
+
+ if (texture_.need_clear) {
+ const int64_t texture_width = texture_.width;
+ const int64_t texture_height = texture_.height;
+ memset(reinterpret_cast<void *>(mapped_rgba_pixels),
+ 0,
+ texture_width * texture_height * sizeof(half4));
+ texture_.need_clear = false;
+ }
+
+ return mapped_rgba_pixels;
+}
+
+void OpenGLDisplayDriver::unmap_texture_buffer()
+{
+ glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
+
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+}
+
+/* --------------------------------------------------------------------
+ * Graphics interoperability.
+ */
+
+OpenGLDisplayDriver::GraphicsInterop OpenGLDisplayDriver::graphics_interop_get()
+{
+ GraphicsInterop interop_dst;
+
+ interop_dst.buffer_width = texture_.buffer_width;
+ interop_dst.buffer_height = texture_.buffer_height;
+ interop_dst.opengl_pbo_id = texture_.gl_pbo_id;
+
+ interop_dst.need_clear = texture_.need_clear;
+ texture_.need_clear = false;
+
+ return interop_dst;
+}
+
+void OpenGLDisplayDriver::graphics_interop_activate()
+{
+ gl_context_enable_();
+}
+
+void OpenGLDisplayDriver::graphics_interop_deactivate()
+{
+ gl_context_disable_();
+}
+
+/* --------------------------------------------------------------------
+ * Drawing.
+ */
+
+void OpenGLDisplayDriver::clear()
+{
+ texture_.need_clear = true;
+}
+
+void OpenGLDisplayDriver::draw(const Params &params)
+{
+ /* See do_update_begin() for why no locking is required here. */
+ if (texture_.need_clear) {
+ /* Texture is requested to be cleared and was not yet cleared.
+ * Do early return which should be equivalent of drawing all-zero texture. */
+ return;
+ }
+
+ if (!gl_draw_resources_ensure()) {
+ return;
+ }
+
+ if (gl_upload_sync_) {
+ glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
+ }
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ display_shader_.bind(params.full_size.x, params.full_size.y);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
+
+ if (texture_.width != params.size.x || texture_.height != params.size.y) {
+ /* Resolution divider is different from 1, force nearest interpolation. */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+ else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
+
+ texture_update_if_needed();
+ vertex_buffer_update(params);
+
+ GLuint vertex_array_object;
+ glGenVertexArrays(1, &vertex_array_object);
+ glBindVertexArray(vertex_array_object);
+
+ const int texcoord_attribute = display_shader_.get_tex_coord_attrib_location();
+ const int position_attribute = display_shader_.get_position_attrib_location();
+
+ glEnableVertexAttribArray(texcoord_attribute);
+ glEnableVertexAttribArray(position_attribute);
+
+ glVertexAttribPointer(
+ texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
+ glVertexAttribPointer(position_attribute,
+ 2,
+ GL_FLOAT,
+ GL_FALSE,
+ 4 * sizeof(float),
+ (const GLvoid *)(sizeof(float) * 2));
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glDeleteVertexArrays(1, &vertex_array_object);
+
+ display_shader_.unbind();
+
+ glDisable(GL_BLEND);
+
+ gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ glFlush();
+}
+
+bool OpenGLDisplayDriver::gl_draw_resources_ensure()
+{
+ if (!texture_.gl_id) {
+ /* If there is no texture allocated, there is nothing to draw. Inform the draw call that it can
+ * can not continue. Note that this is not an unrecoverable error, so once the texture is known
+ * we will come back here and create all the GPU resources needed for draw. */
+ return false;
+ }
+
+ if (gl_draw_resource_creation_attempted_) {
+ return gl_draw_resources_created_;
+ }
+ gl_draw_resource_creation_attempted_ = true;
+
+ if (!vertex_buffer_) {
+ glGenBuffers(1, &vertex_buffer_);
+ if (!vertex_buffer_) {
+ LOG(ERROR) << "Error creating vertex buffer.";
+ return false;
+ }
+ }
+
+ gl_draw_resources_created_ = true;
+
+ return true;
+}
+
+void OpenGLDisplayDriver::gl_resources_destroy()
+{
+ gl_context_enable_();
+
+ if (vertex_buffer_ != 0) {
+ glDeleteBuffers(1, &vertex_buffer_);
+ }
+
+ if (texture_.gl_pbo_id) {
+ glDeleteBuffers(1, &texture_.gl_pbo_id);
+ texture_.gl_pbo_id = 0;
+ }
+
+ if (texture_.gl_id) {
+ glDeleteTextures(1, &texture_.gl_id);
+ texture_.gl_id = 0;
+ }
+
+ gl_context_disable_();
+}
+
+bool OpenGLDisplayDriver::gl_texture_resources_ensure()
+{
+ if (texture_.creation_attempted) {
+ return texture_.is_created;
+ }
+ texture_.creation_attempted = true;
+
+ DCHECK(!texture_.gl_id);
+ DCHECK(!texture_.gl_pbo_id);
+
+ /* Create texture. */
+ glGenTextures(1, &texture_.gl_id);
+ if (!texture_.gl_id) {
+ LOG(ERROR) << "Error creating texture.";
+ return false;
+ }
+
+ /* Configure the texture. */
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* Create PBO for the texture. */
+ glGenBuffers(1, &texture_.gl_pbo_id);
+ if (!texture_.gl_pbo_id) {
+ LOG(ERROR) << "Error creating texture pixel buffer object.";
+ return false;
+ }
+
+ /* Creation finished with a success. */
+ texture_.is_created = true;
+
+ return true;
+}
+
+void OpenGLDisplayDriver::texture_update_if_needed()
+{
+ if (!texture_.need_update) {
+ return;
+ }
+
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
+ glTexSubImage2D(
+ GL_TEXTURE_2D, 0, 0, 0, texture_.width, texture_.height, GL_RGBA, GL_HALF_FLOAT, 0);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ texture_.need_update = false;
+}
+
+void OpenGLDisplayDriver::vertex_buffer_update(const Params &params)
+{
+ /* Invalidate old contents - avoids stalling if the buffer is still waiting in queue to be
+ * rendered. */
+ glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+
+ float *vpointer = reinterpret_cast<float *>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
+ if (!vpointer) {
+ return;
+ }
+
+ vpointer[0] = 0.0f;
+ vpointer[1] = 0.0f;
+ vpointer[2] = params.full_offset.x;
+ vpointer[3] = params.full_offset.y;
+
+ vpointer[4] = 1.0f;
+ vpointer[5] = 0.0f;
+ vpointer[6] = (float)params.size.x + params.full_offset.x;
+ vpointer[7] = params.full_offset.y;
+
+ vpointer[8] = 1.0f;
+ vpointer[9] = 1.0f;
+ vpointer[10] = (float)params.size.x + params.full_offset.x;
+ vpointer[11] = (float)params.size.y + params.full_offset.y;
+
+ vpointer[12] = 0.0f;
+ vpointer[13] = 1.0f;
+ vpointer[14] = params.full_offset.x;
+ vpointer[15] = (float)params.size.y + params.full_offset.y;
+
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/app/opengl/display_driver.h b/intern/cycles/app/opengl/display_driver.h
new file mode 100644
index 00000000000..92578412d68
--- /dev/null
+++ b/intern/cycles/app/opengl/display_driver.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#pragma once
+
+#include <atomic>
+
+#include "app/opengl/shader.h"
+
+#include "session/display_driver.h"
+
+#include "util/function.h"
+#include "util/unique_ptr.h"
+
+CCL_NAMESPACE_BEGIN
+
+class OpenGLDisplayDriver : public DisplayDriver {
+ public:
+ /* Callbacks for enabling and disabling the OpenGL context. Must be provided to support enabling
+ * the context on the Cycles render thread independent of the main thread. */
+ OpenGLDisplayDriver(const function<bool()> &gl_context_enable,
+ const function<void()> &gl_context_disable);
+ ~OpenGLDisplayDriver();
+
+ virtual void graphics_interop_activate() override;
+ virtual void graphics_interop_deactivate() override;
+
+ virtual void clear() override;
+
+ void set_zoom(float zoom_x, float zoom_y);
+
+ protected:
+ virtual void next_tile_begin() override;
+
+ virtual bool update_begin(const Params &params, int texture_width, int texture_height) override;
+ virtual void update_end() override;
+
+ virtual half4 *map_texture_buffer() override;
+ virtual void unmap_texture_buffer() override;
+
+ virtual GraphicsInterop graphics_interop_get() override;
+
+ virtual void draw(const Params &params) override;
+
+ /* Make sure texture is allocated and its initial configuration is performed. */
+ bool gl_texture_resources_ensure();
+
+ /* Ensure all runtime GPU resources needed for drawing are allocated.
+ * Returns true if all resources needed for drawing are available. */
+ bool gl_draw_resources_ensure();
+
+ /* Destroy all GPU resources which are being used by this object. */
+ void gl_resources_destroy();
+
+ /* Update GPU texture dimensions and content if needed (new pixel data was provided).
+ *
+ * NOTE: The texture needs to be bound. */
+ void texture_update_if_needed();
+
+ /* Update vertex buffer with new coordinates of vertex positions and texture coordinates.
+ * This buffer is used to render texture in the viewport.
+ *
+ * NOTE: The buffer needs to be bound. */
+ void vertex_buffer_update(const Params &params);
+
+ /* Texture which contains pixels of the render result. */
+ struct {
+ /* Indicates whether texture creation was attempted and succeeded.
+ * Used to avoid multiple attempts of texture creation on GPU issues or GPU context
+ * misconfiguration. */
+ bool creation_attempted = false;
+ bool is_created = false;
+
+ /* OpenGL resource IDs of the texture itself and Pixel Buffer Object (PBO) used to write
+ * pixels to it.
+ *
+ * NOTE: Allocated on the engine's context. */
+ uint gl_id = 0;
+ uint gl_pbo_id = 0;
+
+ /* Is true when new data was written to the PBO, meaning, the texture might need to be resized
+ * and new data is to be uploaded to the GPU. */
+ bool need_update = false;
+
+ /* Content of the texture is to be filled with zeroes. */
+ std::atomic<bool> need_clear = true;
+
+ /* Dimensions of the texture in pixels. */
+ int width = 0;
+ int height = 0;
+
+ /* Dimensions of the underlying PBO. */
+ int buffer_width = 0;
+ int buffer_height = 0;
+ } texture_;
+
+ OpenGLShader display_shader_;
+
+ /* Special track of whether GPU resources were attempted to be created, to avoid attempts of
+ * their re-creation on failure on every redraw. */
+ bool gl_draw_resource_creation_attempted_ = false;
+ bool gl_draw_resources_created_ = false;
+
+ /* Vertex buffer which hold vertices of a triangle fan which is textures with the texture
+ * holding the render result. */
+ uint vertex_buffer_ = 0;
+
+ void *gl_render_sync_ = nullptr;
+ void *gl_upload_sync_ = nullptr;
+
+ float2 zoom_ = make_float2(1.0f, 1.0f);
+
+ function<bool()> gl_context_enable_ = nullptr;
+ function<void()> gl_context_disable_ = nullptr;
+};
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/app/opengl/shader.cpp b/intern/cycles/app/opengl/shader.cpp
new file mode 100644
index 00000000000..9db9ea7fce9
--- /dev/null
+++ b/intern/cycles/app/opengl/shader.cpp
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#include "app/opengl/shader.h"
+
+#include "util/log.h"
+#include "util/string.h"
+
+#include <GL/glew.h>
+
+CCL_NAMESPACE_BEGIN
+
+/* --------------------------------------------------------------------
+ * OpenGLShader.
+ */
+
+static const char *VERTEX_SHADER =
+ "#version 330\n"
+ "uniform vec2 fullscreen;\n"
+ "in vec2 texCoord;\n"
+ "in vec2 pos;\n"
+ "out vec2 texCoord_interp;\n"
+ "\n"
+ "vec2 normalize_coordinates()\n"
+ "{\n"
+ " return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
+ "}\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
+ " texCoord_interp = texCoord;\n"
+ "}\n\0";
+
+static const char *FRAGMENT_SHADER =
+ "#version 330\n"
+ "uniform sampler2D image_texture;\n"
+ "in vec2 texCoord_interp;\n"
+ "out vec4 fragColor;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " vec4 rgba = texture(image_texture, texCoord_interp);\n"
+ /* Harcoded Rec.709 gamma, should use OpenColorIO eventually. */
+ " fragColor = pow(rgba, vec4(0.45, 0.45, 0.45, 1.0));\n"
+ "}\n\0";
+
+static void shader_print_errors(const char *task, const char *log, const char *code)
+{
+ LOG(ERROR) << "Shader: " << task << " error:";
+ LOG(ERROR) << "===== shader string ====";
+
+ stringstream stream(code);
+ string partial;
+
+ int line = 1;
+ while (getline(stream, partial, '\n')) {
+ if (line < 10) {
+ LOG(ERROR) << " " << line << " " << partial;
+ }
+ else {
+ LOG(ERROR) << line << " " << partial;
+ }
+ line++;
+ }
+ LOG(ERROR) << log;
+}
+
+static int compile_shader_program(void)
+{
+ const struct Shader {
+ const char *source;
+ const GLenum type;
+ } shaders[2] = {{VERTEX_SHADER, GL_VERTEX_SHADER}, {FRAGMENT_SHADER, GL_FRAGMENT_SHADER}};
+
+ const GLuint program = glCreateProgram();
+
+ for (int i = 0; i < 2; i++) {
+ const GLuint shader = glCreateShader(shaders[i].type);
+
+ string source_str = shaders[i].source;
+ const char *c_str = source_str.c_str();
+
+ glShaderSource(shader, 1, &c_str, NULL);
+ glCompileShader(shader);
+
+ GLint compile_status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
+
+ if (!compile_status) {
+ GLchar log[5000];
+ GLsizei length = 0;
+ glGetShaderInfoLog(shader, sizeof(log), &length, log);
+ shader_print_errors("compile", log, c_str);
+ return 0;
+ }
+
+ glAttachShader(program, shader);
+ }
+
+ /* Link output. */
+ glBindFragDataLocation(program, 0, "fragColor");
+
+ /* Link and error check. */
+ glLinkProgram(program);
+
+ GLint link_status;
+ glGetProgramiv(program, GL_LINK_STATUS, &link_status);
+ if (!link_status) {
+ GLchar log[5000];
+ GLsizei length = 0;
+ glGetShaderInfoLog(program, sizeof(log), &length, log);
+ shader_print_errors("linking", log, VERTEX_SHADER);
+ shader_print_errors("linking", log, FRAGMENT_SHADER);
+ return 0;
+ }
+
+ return program;
+}
+
+int OpenGLShader::get_position_attrib_location()
+{
+ if (position_attribute_location_ == -1) {
+ const uint shader_program = get_shader_program();
+ position_attribute_location_ = glGetAttribLocation(shader_program, position_attribute_name);
+ }
+ return position_attribute_location_;
+}
+
+int OpenGLShader::get_tex_coord_attrib_location()
+{
+ if (tex_coord_attribute_location_ == -1) {
+ const uint shader_program = get_shader_program();
+ tex_coord_attribute_location_ = glGetAttribLocation(shader_program, tex_coord_attribute_name);
+ }
+ return tex_coord_attribute_location_;
+}
+
+void OpenGLShader::bind(int width, int height)
+{
+ create_shader_if_needed();
+
+ if (!shader_program_) {
+ return;
+ }
+
+ glUseProgram(shader_program_);
+ glUniform1i(image_texture_location_, 0);
+ glUniform2f(fullscreen_location_, width, height);
+}
+
+void OpenGLShader::unbind()
+{
+}
+
+uint OpenGLShader::get_shader_program()
+{
+ return shader_program_;
+}
+
+void OpenGLShader::create_shader_if_needed()
+{
+ if (shader_program_ || shader_compile_attempted_) {
+ return;
+ }
+
+ shader_compile_attempted_ = true;
+
+ shader_program_ = compile_shader_program();
+ if (!shader_program_) {
+ return;
+ }
+
+ glUseProgram(shader_program_);
+
+ image_texture_location_ = glGetUniformLocation(shader_program_, "image_texture");
+ if (image_texture_location_ < 0) {
+ LOG(ERROR) << "Shader doesn't contain the 'image_texture' uniform.";
+ destroy_shader();
+ return;
+ }
+
+ fullscreen_location_ = glGetUniformLocation(shader_program_, "fullscreen");
+ if (fullscreen_location_ < 0) {
+ LOG(ERROR) << "Shader doesn't contain the 'fullscreen' uniform.";
+ destroy_shader();
+ return;
+ }
+}
+
+void OpenGLShader::destroy_shader()
+{
+ glDeleteProgram(shader_program_);
+ shader_program_ = 0;
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/app/opengl/shader.h b/intern/cycles/app/opengl/shader.h
new file mode 100644
index 00000000000..6ca121ca6ff
--- /dev/null
+++ b/intern/cycles/app/opengl/shader.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 OpenGL Foundation */
+
+#pragma once
+
+#include "util/types.h"
+
+CCL_NAMESPACE_BEGIN
+
+class OpenGLShader {
+ public:
+ static constexpr const char *position_attribute_name = "pos";
+ static constexpr const char *tex_coord_attribute_name = "texCoord";
+
+ OpenGLShader() = default;
+ virtual ~OpenGLShader() = default;
+
+ /* Get attribute location for position and texture coordinate respectively.
+ * NOTE: The shader needs to be bound to have access to those. */
+ int get_position_attrib_location();
+ int get_tex_coord_attrib_location();
+
+ void bind(int width, int height);
+ void unbind();
+
+ protected:
+ uint get_shader_program();
+
+ void create_shader_if_needed();
+ void destroy_shader();
+
+ /* Cached values of various OpenGL resources. */
+ int position_attribute_location_ = -1;
+ int tex_coord_attribute_location_ = -1;
+
+ uint shader_program_ = 0;
+ int image_texture_location_ = -1;
+ int fullscreen_location_ = -1;
+
+ /* Shader compilation attempted. Which means, that if the shader program is 0 then compilation or
+ * linking has failed. Do not attempt to re-compile the shader. */
+ bool shader_compile_attempted_ = false;
+};
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/app/opengl/window.cpp b/intern/cycles/app/opengl/window.cpp
new file mode 100644
index 00000000000..7351ae3eecd
--- /dev/null
+++ b/intern/cycles/app/opengl/window.cpp
@@ -0,0 +1,352 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "app/opengl/window.h"
+
+#include "util/string.h"
+#include "util/thread.h"
+#include "util/time.h"
+#include "util/version.h"
+
+#include <GL/glew.h>
+#include <SDL.h>
+
+CCL_NAMESPACE_BEGIN
+
+/* structs */
+
+struct Window {
+ WindowInitFunc initf = nullptr;
+ WindowExitFunc exitf = nullptr;
+ WindowResizeFunc resize = nullptr;
+ WindowDisplayFunc display = nullptr;
+ WindowKeyboardFunc keyboard = nullptr;
+ WindowMotionFunc motion = nullptr;
+
+ bool first_display = true;
+ bool redraw = false;
+
+ int mouseX = 0, mouseY = 0;
+ int mouseBut0 = 0, mouseBut2 = 0;
+
+ int width = 0, height = 0;
+
+ SDL_Window *window = nullptr;
+ SDL_GLContext gl_context = nullptr;
+ thread_mutex gl_context_mutex;
+} V;
+
+/* public */
+
+static void window_display_text(int x, int y, const char *text)
+{
+/* Not currently supported, need to add text rendering support. */
+#if 0
+ const char *c;
+
+ glRasterPos3f(x, y, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ printf("display %s\n", text);
+
+ for (c = text; *c != '\0'; c++) {
+ const uint8_t *bitmap = helvetica10_character_map[*c];
+ glBitmap(bitmap[0],
+ helvetica10_height,
+ helvetica10_x_offset,
+ helvetica10_y_offset,
+ bitmap[0],
+ 0.0f,
+ bitmap + 1);
+ }
+#else
+ static string last_text = "";
+
+ if (text != last_text) {
+ printf("%s\n", text);
+ last_text = text;
+ }
+#endif
+}
+
+void window_display_info(const char *info)
+{
+ const int height = 20;
+
+#if 0
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glColor4f(0.1f, 0.1f, 0.1f, 0.8f);
+ glRectf(0.0f, V.height - height, V.width, V.height);
+ glDisable(GL_BLEND);
+
+ glColor3f(0.5f, 0.5f, 0.5f);
+#endif
+
+ window_display_text(10, 7 + V.height - height, info);
+
+#if 0
+ glColor3f(1.0f, 1.0f, 1.0f);
+#endif
+}
+
+void window_display_help()
+{
+ const int w = (int)((float)V.width / 1.15f);
+ const int h = (int)((float)V.height / 1.15f);
+
+ const int x1 = (V.width - w) / 2;
+#if 0
+ const int x2 = x1 + w;
+#endif
+
+ const int y1 = (V.height - h) / 2;
+ const int y2 = y1 + h;
+
+#if 0
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glColor4f(0.5f, 0.5f, 0.5f, 0.8f);
+ glRectf(x1, y1, x2, y2);
+ glDisable(GL_BLEND);
+
+ glColor3f(0.8f, 0.8f, 0.8f);
+#endif
+
+ string info = string("Cycles Renderer ") + CYCLES_VERSION_STRING;
+
+ window_display_text(x1 + 20, y2 - 20, info.c_str());
+ window_display_text(x1 + 20, y2 - 40, "(C) 2011-2016 Blender Foundation");
+ window_display_text(x1 + 20, y2 - 80, "Controls:");
+ window_display_text(x1 + 20, y2 - 100, "h: Info/Help");
+ window_display_text(x1 + 20, y2 - 120, "r: Reset");
+ window_display_text(x1 + 20, y2 - 140, "p: Pause");
+ window_display_text(x1 + 20, y2 - 160, "esc: Cancel");
+ window_display_text(x1 + 20, y2 - 180, "q: Quit program");
+
+ window_display_text(x1 + 20, y2 - 210, "i: Interactive mode");
+ window_display_text(x1 + 20, y2 - 230, "Left mouse: Move camera");
+ window_display_text(x1 + 20, y2 - 250, "Right mouse: Rotate camera");
+ window_display_text(x1 + 20, y2 - 270, "W/A/S/D: Move camera");
+ window_display_text(x1 + 20, y2 - 290, "0/1/2/3: Set max bounces");
+
+#if 0
+ glColor3f(1.0f, 1.0f, 1.0f);
+#endif
+}
+
+static void window_display()
+{
+ if (V.first_display) {
+ if (V.initf) {
+ V.initf();
+ }
+ if (V.exitf) {
+ atexit(V.exitf);
+ }
+
+ V.first_display = false;
+ }
+
+ window_opengl_context_enable();
+
+ glViewport(0, 0, V.width, V.height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glClearColor(0.05f, 0.05f, 0.05f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, V.width, 0, V.height, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glRasterPos3f(0, 0, 0);
+
+ if (V.display)
+ V.display();
+
+ SDL_GL_SwapWindow(V.window);
+ window_opengl_context_disable();
+}
+
+static void window_reshape(int width, int height)
+{
+ if (V.width != width || V.height != height) {
+ if (V.resize) {
+ V.resize(width, height);
+ }
+ }
+
+ V.width = width;
+ V.height = height;
+}
+
+static bool window_keyboard(unsigned char key)
+{
+ if (V.keyboard)
+ V.keyboard(key);
+
+ if (key == 'q') {
+ if (V.exitf)
+ V.exitf();
+ return true;
+ }
+
+ return false;
+}
+
+static void window_mouse(int button, int state, int x, int y)
+{
+ if (button == SDL_BUTTON_LEFT) {
+ if (state == SDL_MOUSEBUTTONDOWN) {
+ V.mouseX = x;
+ V.mouseY = y;
+ V.mouseBut0 = 1;
+ }
+ else if (state == SDL_MOUSEBUTTONUP) {
+ V.mouseBut0 = 0;
+ }
+ }
+ else if (button == SDL_BUTTON_RIGHT) {
+ if (state == SDL_MOUSEBUTTONDOWN) {
+ V.mouseX = x;
+ V.mouseY = y;
+ V.mouseBut2 = 1;
+ }
+ else if (state == SDL_MOUSEBUTTONUP) {
+ V.mouseBut2 = 0;
+ }
+ }
+}
+
+static void window_motion(int x, int y)
+{
+ const int but = V.mouseBut0 ? 0 : 2;
+ const int distX = x - V.mouseX;
+ const int distY = y - V.mouseY;
+
+ if (V.motion)
+ V.motion(distX, distY, but);
+
+ V.mouseX = x;
+ V.mouseY = y;
+}
+
+bool window_opengl_context_enable()
+{
+ V.gl_context_mutex.lock();
+ SDL_GL_MakeCurrent(V.window, V.gl_context);
+ return true;
+}
+
+void window_opengl_context_disable()
+{
+ SDL_GL_MakeCurrent(V.window, nullptr);
+ V.gl_context_mutex.unlock();
+}
+
+void window_main_loop(const char *title,
+ int width,
+ int height,
+ WindowInitFunc initf,
+ WindowExitFunc exitf,
+ WindowResizeFunc resize,
+ WindowDisplayFunc display,
+ WindowKeyboardFunc keyboard,
+ WindowMotionFunc motion)
+{
+ V.width = width;
+ V.height = height;
+ V.first_display = true;
+ V.redraw = false;
+ V.initf = initf;
+ V.exitf = exitf;
+ V.resize = resize;
+ V.display = display;
+ V.keyboard = keyboard;
+ V.motion = motion;
+
+ SDL_Init(SDL_INIT_VIDEO);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+ SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
+ V.window = SDL_CreateWindow(title,
+ SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ width,
+ height,
+ SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
+ if (V.window == nullptr) {
+ fprintf(stderr, "Failed to create window: %s\n", SDL_GetError());
+ return;
+ }
+
+ SDL_RaiseWindow(V.window);
+
+ V.gl_context = SDL_GL_CreateContext(V.window);
+ glewInit();
+ SDL_GL_MakeCurrent(V.window, nullptr);
+
+ window_reshape(width, height);
+ window_display();
+
+ while (true) {
+ bool quit = false;
+ SDL_Event event;
+ while (!quit && SDL_PollEvent(&event)) {
+ if (event.type == SDL_TEXTINPUT) {
+ quit = window_keyboard(event.text.text[0]);
+ }
+ else if (event.type == SDL_MOUSEMOTION) {
+ window_motion(event.motion.x, event.motion.y);
+ }
+ else if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
+ window_mouse(event.button.button, event.button.state, event.button.x, event.button.y);
+ }
+ else if (event.type == SDL_WINDOWEVENT) {
+ if (event.window.event == SDL_WINDOWEVENT_RESIZED ||
+ event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+ window_reshape(event.window.data1, event.window.data2);
+ }
+ }
+ else if (event.type == SDL_QUIT) {
+ if (V.exitf) {
+ V.exitf();
+ }
+ quit = true;
+ }
+ }
+
+ if (quit) {
+ break;
+ }
+
+ if (V.redraw) {
+ V.redraw = false;
+ window_display();
+ }
+
+ SDL_WaitEventTimeout(NULL, 100);
+ }
+
+ SDL_GL_DeleteContext(V.gl_context);
+ SDL_DestroyWindow(V.window);
+ SDL_Quit();
+}
+
+void window_redraw()
+{
+ V.redraw = true;
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/app/opengl/window.h b/intern/cycles/app/opengl/window.h
new file mode 100644
index 00000000000..531b5cab3fc
--- /dev/null
+++ b/intern/cycles/app/opengl/window.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#pragma once
+
+/* Functions to display a simple OpenGL window using SDL, simplified to the
+ * bare minimum we need to reduce boilerplate code in tests apps. */
+
+CCL_NAMESPACE_BEGIN
+
+typedef void (*WindowInitFunc)();
+typedef void (*WindowExitFunc)();
+typedef void (*WindowResizeFunc)(int width, int height);
+typedef void (*WindowDisplayFunc)();
+typedef void (*WindowKeyboardFunc)(unsigned char key);
+typedef void (*WindowMotionFunc)(int x, int y, int button);
+
+void window_main_loop(const char *title,
+ int width,
+ int height,
+ WindowInitFunc initf,
+ WindowExitFunc exitf,
+ WindowResizeFunc resize,
+ WindowDisplayFunc display,
+ WindowKeyboardFunc keyboard,
+ WindowMotionFunc motion);
+
+void window_display_info(const char *info);
+void window_display_help();
+void window_redraw();
+
+bool window_opengl_context_enable();
+void window_opengl_context_disable();
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake
index c964fbe0d72..6ad64d684c0 100644
--- a/intern/cycles/cmake/external_libs.cmake
+++ b/intern/cycles/cmake/external_libs.cmake
@@ -479,26 +479,22 @@ else()
endif()
###########################################################################
-# GLUT
+# SDL
###########################################################################
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
- if(MSVC AND EXISTS ${_cycles_lib_dir})
- add_definitions(-DFREEGLUT_STATIC -DFREEGLUT_LIB_PRAGMAS=0)
- set(GLUT_LIBRARIES "${_cycles_lib_dir}/opengl/lib/freeglut_static.lib")
- set(GLUT_INCLUDE_DIR "${_cycles_lib_dir}/opengl/include")
- else()
- find_package(GLUT)
+ # We can't use the version from the Blender precompiled libraries because
+ # it does not include the video subsystem.
+ find_package(SDL2)
- if(NOT GLUT_FOUND)
- set(WITH_CYCLES_STANDALONE_GUI OFF)
- message(STATUS "GLUT not found, disabling Cycles standalone GUI")
- endif()
+ if(NOT SDL2_FOUND)
+ set(WITH_CYCLES_STANDALONE_GUI OFF)
+ message(STATUS "SDL not found, disabling Cycles standalone GUI")
endif()
include_directories(
SYSTEM
- ${GLUT_INCLUDE_DIR}
+ ${SDL2_INCLUDE_DIRS}
)
endif()
diff --git a/intern/cycles/device/hip/device_impl.h b/intern/cycles/device/hip/device_impl.h
index 00269ac287c..9afef3789af 100644
--- a/intern/cycles/device/hip/device_impl.h
+++ b/intern/cycles/device/hip/device_impl.h
@@ -12,8 +12,6 @@
# ifdef WITH_HIP_DYNLOAD
# include "hipew.h"
-# else
-# include "util/opengl.h"
# endif
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index 0e348b1ac0f..fddac1dbbcf 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -7,7 +7,6 @@ set(INC
)
set(INC_SYS
- ${GLEW_INCLUDE_DIR}
)
set(SRC
@@ -34,14 +33,6 @@ set(LIB
${TBB_LIBRARIES}
)
-if(WITH_CYCLES_STANDALONE)
- if(WITH_CYCLES_STANDALONE_GUI)
- list(APPEND SRC
- view.cpp
- )
- endif()
-endif()
-
set(SRC_HEADERS
algorithm.h
aligned_malloc.h
@@ -142,7 +133,6 @@ set(SRC_HEADERS
unique_ptr.h
vector.h
version.h
- view.h
windows.h
xml.h
)
diff --git a/intern/cycles/util/view.cpp b/intern/cycles/util/view.cpp
deleted file mode 100644
index 475f8dbcee8..00000000000
--- a/intern/cycles/util/view.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2022 Blender Foundation */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "util/opengl.h"
-#include "util/string.h"
-#include "util/time.h"
-#include "util/version.h"
-#include "util/view.h"
-
-#ifdef __APPLE__
-# include <GLUT/glut.h>
-#else
-# include <GL/glut.h>
-#endif
-
-CCL_NAMESPACE_BEGIN
-
-/* structs */
-
-struct View {
- ViewInitFunc initf;
- ViewExitFunc exitf;
- ViewResizeFunc resize;
- ViewDisplayFunc display;
- ViewKeyboardFunc keyboard;
- ViewMotionFunc motion;
-
- bool first_display;
- bool redraw;
-
- int mouseX, mouseY;
- int mouseBut0, mouseBut2;
-
- int width, height;
-} V;
-
-/* public */
-
-static void view_display_text(int x, int y, const char *text)
-{
- const char *c;
-
- glRasterPos3f(x, y, 0);
-
- for (c = text; *c != '\0'; c++)
- glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c);
-}
-
-void view_display_info(const char *info)
-{
- const int height = 20;
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(0.1f, 0.1f, 0.1f, 0.8f);
- glRectf(0.0f, V.height - height, V.width, V.height);
- glDisable(GL_BLEND);
-
- glColor3f(0.5f, 0.5f, 0.5f);
-
- view_display_text(10, 7 + V.height - height, info);
-
- glColor3f(1.0f, 1.0f, 1.0f);
-}
-
-void view_display_help()
-{
- const int w = (int)((float)V.width / 1.15f);
- const int h = (int)((float)V.height / 1.15f);
-
- const int x1 = (V.width - w) / 2;
- const int x2 = x1 + w;
-
- const int y1 = (V.height - h) / 2;
- const int y2 = y1 + h;
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(0.5f, 0.5f, 0.5f, 0.8f);
- glRectf(x1, y1, x2, y2);
- glDisable(GL_BLEND);
-
- glColor3f(0.8f, 0.8f, 0.8f);
-
- string info = string("Cycles Renderer ") + CYCLES_VERSION_STRING;
-
- view_display_text(x1 + 20, y2 - 20, info.c_str());
- view_display_text(x1 + 20, y2 - 40, "(C) 2011-2022 Blender Foundation");
- view_display_text(x1 + 20, y2 - 80, "Controls:");
- view_display_text(x1 + 20, y2 - 100, "h: Info/Help");
- view_display_text(x1 + 20, y2 - 120, "r: Reset");
- view_display_text(x1 + 20, y2 - 140, "p: Pause");
- view_display_text(x1 + 20, y2 - 160, "esc: Cancel");
- view_display_text(x1 + 20, y2 - 180, "q: Quit program");
-
- view_display_text(x1 + 20, y2 - 210, "i: Interactive mode");
- view_display_text(x1 + 20, y2 - 230, "Left mouse: Move camera");
- view_display_text(x1 + 20, y2 - 250, "Right mouse: Rotate camera");
- view_display_text(x1 + 20, y2 - 270, "W/A/S/D: Move camera");
- view_display_text(x1 + 20, y2 - 290, "0/1/2/3: Set max bounces");
-
- glColor3f(1.0f, 1.0f, 1.0f);
-}
-
-static void view_display()
-{
- if (V.first_display) {
- if (V.initf)
- V.initf();
- if (V.exitf)
- atexit(V.exitf);
-
- V.first_display = false;
- }
-
- glClearColor(0.05f, 0.05f, 0.05f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, V.width, 0, V.height, -1, 1);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glRasterPos3f(0, 0, 0);
-
- if (V.display)
- V.display();
-
- glutSwapBuffers();
-}
-
-static void view_reshape(int width, int height)
-{
- if (width <= 0 || height <= 0)
- return;
-
- V.width = width;
- V.height = height;
-
- glViewport(0, 0, width, height);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- if (V.resize)
- V.resize(width, height);
-}
-
-static void view_keyboard(unsigned char key, int x, int y)
-{
- if (V.keyboard)
- V.keyboard(key);
-
- if (key == 'm')
- printf("mouse %d %d\n", x, y);
- if (key == 'q') {
- if (V.exitf)
- V.exitf();
- exit(0);
- }
-}
-
-static void view_mouse(int button, int state, int x, int y)
-{
- if (button == 0) {
- if (state == GLUT_DOWN) {
- V.mouseX = x;
- V.mouseY = y;
- V.mouseBut0 = 1;
- }
- else if (state == GLUT_UP) {
- V.mouseBut0 = 0;
- }
- }
- else if (button == 2) {
- if (state == GLUT_DOWN) {
- V.mouseX = x;
- V.mouseY = y;
- V.mouseBut2 = 1;
- }
- else if (state == GLUT_UP) {
- V.mouseBut2 = 0;
- }
- }
-}
-
-static void view_motion(int x, int y)
-{
- const int but = V.mouseBut0 ? 0 : 2;
- const int distX = x - V.mouseX;
- const int distY = y - V.mouseY;
-
- if (V.motion)
- V.motion(distX, distY, but);
-
- V.mouseX = x;
- V.mouseY = y;
-}
-
-static void view_idle()
-{
- if (V.redraw) {
- V.redraw = false;
- glutPostRedisplay();
- }
-
- time_sleep(0.1);
-}
-
-void view_main_loop(const char *title,
- int width,
- int height,
- ViewInitFunc initf,
- ViewExitFunc exitf,
- ViewResizeFunc resize,
- ViewDisplayFunc display,
- ViewKeyboardFunc keyboard,
- ViewMotionFunc motion)
-{
- const char *name = "app";
- char *argv = (char *)name;
- int argc = 1;
-
- memset(&V, 0, sizeof(V));
- V.width = width;
- V.height = height;
- V.first_display = true;
- V.redraw = false;
- V.initf = initf;
- V.exitf = exitf;
- V.resize = resize;
- V.display = display;
- V.keyboard = keyboard;
- V.motion = motion;
-
- glutInit(&argc, &argv);
- glutInitWindowSize(width, height);
- glutInitWindowPosition(0, 0);
- glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
- glutCreateWindow(title);
-
- glewInit();
-
- view_reshape(width, height);
-
- glutDisplayFunc(view_display);
- glutIdleFunc(view_idle);
- glutReshapeFunc(view_reshape);
- glutKeyboardFunc(view_keyboard);
- glutMouseFunc(view_mouse);
- glutMotionFunc(view_motion);
-
- glutMainLoop();
-}
-
-void view_redraw()
-{
- V.redraw = true;
-}
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/util/view.h b/intern/cycles/util/view.h
deleted file mode 100644
index 51c242c21f7..00000000000
--- a/intern/cycles/util/view.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2022 Blender Foundation */
-
-#ifndef __UTIL_VIEW_H__
-#define __UTIL_VIEW_H__
-
-/* Functions to display a simple OpenGL window using GLUT, simplified to the
- * bare minimum we need to reduce boilerplate code in tests apps. */
-
-CCL_NAMESPACE_BEGIN
-
-typedef void (*ViewInitFunc)();
-typedef void (*ViewExitFunc)();
-typedef void (*ViewResizeFunc)(int width, int height);
-typedef void (*ViewDisplayFunc)();
-typedef void (*ViewKeyboardFunc)(unsigned char key);
-typedef void (*ViewMotionFunc)(int x, int y, int button);
-
-void view_main_loop(const char *title,
- int width,
- int height,
- ViewInitFunc initf,
- ViewExitFunc exitf,
- ViewResizeFunc resize,
- ViewDisplayFunc display,
- ViewKeyboardFunc keyboard,
- ViewMotionFunc motion);
-
-void view_display_info(const char *info);
-void view_display_help();
-void view_redraw();
-
-CCL_NAMESPACE_END
-
-#endif /*__UTIL_VIEW_H__*/
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 16e3f32e88a..5b840fae341 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -780,7 +780,7 @@ class IMAGE_HT_header(Header):
layout.template_edit_mode_selection()
else:
layout.prop(tool_settings, "uv_select_mode", text="", expand=True)
- layout.prop(uvedit, "sticky_select_mode", icon_only=True)
+ layout.prop(tool_settings, "uv_sticky_select_mode", icon_only=True)
IMAGE_MT_editor_menus.draw_collapsible(context, layout)
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index e93d9179f82..61ba6189be4 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -823,7 +823,7 @@ class VIEW3D_MT_editor_menus(Menu):
layout.menu("VIEW3D_MT_select_paint_mask")
elif mesh.use_paint_mask_vertex and mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX'}:
layout.menu("VIEW3D_MT_select_paint_mask_vertex")
- elif mode_string not in ('SCULPT', 'SCULPT_CURVES'):
+ elif mode_string not in {'SCULPT', 'SCULPT_CURVES'}:
layout.menu("VIEW3D_MT_select_%s" % mode_string.lower())
if gp_edit:
@@ -866,7 +866,7 @@ class VIEW3D_MT_editor_menus(Menu):
layout.menu("VIEW3D_MT_edit_curve_segments")
elif obj:
- if mode_string not in ('PAINT_TEXTURE', 'SCULPT_CURVES'):
+ if mode_string not in {'PAINT_TEXTURE', 'SCULPT_CURVES'}:
layout.menu("VIEW3D_MT_%s" % mode_string.lower())
if mode_string == 'SCULPT':
layout.menu("VIEW3D_MT_mask")
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index b448214ce28..ded64b68f79 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -88,7 +88,8 @@ struct KS_Path *BKE_keyingset_find_path(struct KeyingSet *ks,
void BKE_keyingsets_copy(struct ListBase *newlist, const struct ListBase *list);
/** Process the ID pointers inside a scene's keyingsets, in see `BKE_lib_query.h` for details. */
-void BKE_keyingsets_foreach_id(struct LibraryForeachIDData *data, const struct ListBase *keyingsets);
+void BKE_keyingsets_foreach_id(struct LibraryForeachIDData *data,
+ const struct ListBase *keyingsets);
/* Free the given Keying Set path */
void BKE_keyingset_free_path(struct KeyingSet *ks, struct KS_Path *ksp);
diff --git a/source/blender/blenkernel/BKE_curves.h b/source/blender/blenkernel/BKE_curves.h
index 7ad915b50d7..2cce15fbfd6 100644
--- a/source/blender/blenkernel/BKE_curves.h
+++ b/source/blender/blenkernel/BKE_curves.h
@@ -12,9 +12,9 @@ extern "C" {
#endif
struct BoundBox;
+struct Curves;
struct CustomDataLayer;
struct Depsgraph;
-struct Curves;
struct Main;
struct Object;
struct Scene;
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index a40a354eef7..e586bc4247d 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -16,6 +16,7 @@ struct Brush;
struct CurveMapping;
struct Depsgraph;
struct GHash;
+struct GPencilUpdateCache;
struct ListBase;
struct MDeformVert;
struct Main;
@@ -32,7 +33,6 @@ struct bGPDlayer;
struct bGPDlayer_Mask;
struct bGPDstroke;
struct bGPdata;
-struct GPencilUpdateCache;
#define GPENCIL_SIMPLIFY(scene) (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE)
#define GPENCIL_SIMPLIFY_ONPLAY(playing) \
diff --git a/source/blender/blenkernel/BKE_gpencil_update_cache.h b/source/blender/blenkernel/BKE_gpencil_update_cache.h
index a4fd70eb883..52b8716bab5 100644
--- a/source/blender/blenkernel/BKE_gpencil_update_cache.h
+++ b/source/blender/blenkernel/BKE_gpencil_update_cache.h
@@ -14,11 +14,11 @@ extern "C" {
#include "BLI_sys_types.h" /* for bool */
struct DLRBT_Tree;
-struct bGPdata;
-struct bGPDlayer;
+struct GPencilUpdateCache;
struct bGPDframe;
+struct bGPDlayer;
struct bGPDstroke;
-struct GPencilUpdateCache;
+struct bGPdata;
/* GPencilUpdateCache.flag */
typedef enum eGPUpdateCacheNodeFlag {
diff --git a/source/blender/blenkernel/BKE_image_partial_update.hh b/source/blender/blenkernel/BKE_image_partial_update.hh
index 3804936d00f..45b08e17920 100644
--- a/source/blender/blenkernel/BKE_image_partial_update.hh
+++ b/source/blender/blenkernel/BKE_image_partial_update.hh
@@ -21,8 +21,8 @@
#include "DNA_image_types.h"
extern "C" {
-struct PartialUpdateUser;
struct PartialUpdateRegister;
+struct PartialUpdateUser;
}
namespace blender::bke::image {
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 9a212cb1275..acdca23b21c 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -409,14 +409,18 @@ void BKE_modifier_session_uuid_generate(struct ModifierData *md);
bool BKE_modifier_unique_name(struct ListBase *modifiers, struct ModifierData *md);
+struct ModifierData *BKE_modifier_copy_ex(const struct ModifierData *md, int flag);
+
/**
* Callback's can use this to avoid copying every member.
*/
void BKE_modifier_copydata_generic(const struct ModifierData *md,
struct ModifierData *md_dst,
int flag);
-void BKE_modifier_copydata(struct ModifierData *md, struct ModifierData *target);
-void BKE_modifier_copydata_ex(struct ModifierData *md, struct ModifierData *target, int flag);
+void BKE_modifier_copydata(const struct ModifierData *md, struct ModifierData *target);
+void BKE_modifier_copydata_ex(const struct ModifierData *md,
+ struct ModifierData *target,
+ int flag);
bool BKE_modifier_depends_ontime(struct Scene *scene, struct ModifierData *md, int dag_eval_mode);
bool BKE_modifier_supports_mapping(struct ModifierData *md);
bool BKE_modifier_supports_cage(struct Scene *scene, struct ModifierData *md);
diff --git a/source/blender/blenkernel/BKE_node_tree_update.h b/source/blender/blenkernel/BKE_node_tree_update.h
index 7998a5ec017..5e377728bb7 100644
--- a/source/blender/blenkernel/BKE_node_tree_update.h
+++ b/source/blender/blenkernel/BKE_node_tree_update.h
@@ -7,12 +7,12 @@
*/
struct ID;
+struct ImageUser;
struct Main;
struct bNode;
struct bNodeLink;
struct bNodeSocket;
struct bNodeTree;
-struct ImageUser;
#ifdef __cplusplus
extern "C" {
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index fe3b1d0c306..16d43d40c50 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -2823,7 +2823,7 @@ void BKE_gpencil_frame_selected_hash(bGPdata *gpd, struct GHash *r_list)
bool BKE_gpencil_can_avoid_full_copy_on_write(const Depsgraph *depsgraph, bGPdata *gpd)
{
- /* For now, we only use the update cache in the active depsgraph. Othwerwise we might access the
+ /* For now, we only use the update cache in the active depsgraph. Otherwise we might access the
* cache while another depsgraph frees it. */
if (!DEG_is_active(depsgraph)) {
return false;
diff --git a/source/blender/blenkernel/intern/gpencil_update_cache.c b/source/blender/blenkernel/intern/gpencil_update_cache.c
index 2258f8c353f..bbe576eb847 100644
--- a/source/blender/blenkernel/intern/gpencil_update_cache.c
+++ b/source/blender/blenkernel/intern/gpencil_update_cache.c
@@ -99,7 +99,7 @@ static void update_cache_node_create_ex(GPencilUpdateCache *root_cache,
bool full_copy)
{
if (root_cache->flag == GP_UPDATE_NODE_FULL_COPY) {
- /* Entire data-block has to be recaculated, e.g. nothing else needs to be added to the cache.
+ /* Entire data-block has to be recalculated, e.g. nothing else needs to be added to the cache.
*/
return;
}
@@ -110,14 +110,14 @@ static void update_cache_node_create_ex(GPencilUpdateCache *root_cache,
root_cache->data = (bGPdata *)data;
root_cache->flag = node_flag;
if (full_copy) {
- /* Entire data-block has to be recaculated, remove all caches of "lower" elements. */
+ /* Entire data-block has to be recalculated, remove all caches of "lower" elements. */
BLI_dlrbTree_free(root_cache->children, cache_node_free);
}
return;
}
const bool is_layer_update_node = (gpf_index == -1);
- /* If the data pointer in GPencilUpdateCache is NULL, this element is not actually cached
+ /* If the data pointer in #GPencilUpdateCache is NULL, this element is not actually cached
* and does not need to be updated, but we do need the index to find elements that are in
* levels below. E.g. if a stroke needs to be updated, the frame it is in would not hold a
* pointer to it's data. */
@@ -174,7 +174,7 @@ static void update_cache_node_create(
}
if (root_cache->flag == GP_UPDATE_NODE_FULL_COPY) {
- /* Entire data-block has to be recaculated, e.g. nothing else needs to be added to the cache.
+ /* Entire data-block has to be recalculated, e.g. nothing else needs to be added to the cache.
*/
return;
}
diff --git a/source/blender/blenkernel/intern/image_gpu.cc b/source/blender/blenkernel/intern/image_gpu.cc
index 5675641deb4..444cbbe4bf9 100644
--- a/source/blender/blenkernel/intern/image_gpu.cc
+++ b/source/blender/blenkernel/intern/image_gpu.cc
@@ -431,7 +431,8 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
if (ibuf_intern == nullptr) {
ibuf_intern = BKE_image_acquire_ibuf(ima, iuser, nullptr);
if (ibuf_intern == nullptr) {
- return image_gpu_texture_error_create(textarget);
+ *tex = image_gpu_texture_error_create(textarget);
+ return *tex;
}
}
diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc
index e1e4a12533a..9d5635f49ab 100644
--- a/source/blender/blenkernel/intern/image_partial_update.cc
+++ b/source/blender/blenkernel/intern/image_partial_update.cc
@@ -90,8 +90,8 @@ static int chunk_number_for_pixel(int pixel_offset)
return chunk_offset;
}
-struct PartialUpdateUserImpl;
struct PartialUpdateRegisterImpl;
+struct PartialUpdateUserImpl;
/**
* Wrap PartialUpdateUserImpl to its C-struct (PartialUpdateUser).
diff --git a/source/blender/blenkernel/intern/mesh_calc_edges.cc b/source/blender/blenkernel/intern/mesh_calc_edges.cc
index 0524412e302..5895eb7fd71 100644
--- a/source/blender/blenkernel/intern/mesh_calc_edges.cc
+++ b/source/blender/blenkernel/intern/mesh_calc_edges.cc
@@ -7,6 +7,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+
#include "BLI_map.hh"
#include "BLI_task.hh"
#include "BLI_threads.h"
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index c3d819bf46e..121bfbff394 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -1041,7 +1041,7 @@ static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh)
BKE_mesh_wrapper_ensure_mdata(mesh);
}
else {
- BKE_mesh_wrapper_ensure_subdivision(object, mesh);
+ mesh = BKE_mesh_wrapper_ensure_subdivision(object, mesh);
}
Mesh *mesh_result = (Mesh *)BKE_id_copy_ex(
@@ -1079,8 +1079,7 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph,
mask.pmask |= CD_MASK_ORIGINDEX;
}
Mesh *result = mesh_create_eval_final(depsgraph, scene, &object_for_eval, &mask);
- BKE_mesh_wrapper_ensure_subdivision(object, result);
- return result;
+ return BKE_mesh_wrapper_ensure_subdivision(object, result);
}
static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph,
@@ -1223,6 +1222,9 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, nullptr, &CD_MASK_MESH, true);
+ /* Anonymous attributes shouldn't exist on original data. */
+ BKE_mesh_anonymous_attributes_remove(mesh_in_bmain);
+
/* User-count is required because so far mesh was in a limbo, where library management does
* not perform any user management (i.e. copy of a mesh will not increase users of materials). */
BKE_library_foreach_ID_link(
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 46fea5ae115..837c1fe179f 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -131,7 +131,7 @@ void BKE_modifier_panel_expand(ModifierData *md)
/***/
-ModifierData *BKE_modifier_new(int type)
+static ModifierData *modifier_allocate_and_init(int type)
{
const ModifierTypeInfo *mti = BKE_modifier_get_info(type);
ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
@@ -152,6 +152,13 @@ ModifierData *BKE_modifier_new(int type)
mti->initData(md);
}
+ return md;
+}
+
+ModifierData *BKE_modifier_new(int type)
+{
+ ModifierData *md = modifier_allocate_and_init(type);
+
BKE_modifier_session_uuid_generate(md);
return md;
@@ -315,6 +322,16 @@ void BKE_modifiers_foreach_tex_link(Object *ob, TexWalkFunc walk, void *userData
}
}
+ModifierData *BKE_modifier_copy_ex(const ModifierData *md, int flag)
+{
+ ModifierData *md_dst = modifier_allocate_and_init(md->type);
+
+ BLI_strncpy(md_dst->name, md->name, sizeof(md_dst->name));
+ BKE_modifier_copydata_ex(md, md_dst, flag);
+
+ return md_dst;
+}
+
void BKE_modifier_copydata_generic(const ModifierData *md_src,
ModifierData *md_dst,
const int UNUSED(flag))
@@ -348,7 +365,7 @@ static void modifier_copy_data_id_us_cb(void *UNUSED(userData),
}
}
-void BKE_modifier_copydata_ex(ModifierData *md, ModifierData *target, const int flag)
+void BKE_modifier_copydata_ex(const ModifierData *md, ModifierData *target, const int flag)
{
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
@@ -378,7 +395,7 @@ void BKE_modifier_copydata_ex(ModifierData *md, ModifierData *target, const int
}
}
-void BKE_modifier_copydata(ModifierData *md, ModifierData *target)
+void BKE_modifier_copydata(const ModifierData *md, ModifierData *target)
{
BKE_modifier_copydata_ex(md, target, 0);
}
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index 579e61750f0..3a8d7d6bc8a 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -1599,9 +1599,7 @@ bool BKE_object_modifier_stack_copy(Object *ob_dst,
continue;
}
- ModifierData *md_dst = BKE_modifier_new(md_src->type);
- BLI_strncpy(md_dst->name, md_src->name, sizeof(md_dst->name));
- BKE_modifier_copydata_ex(md_src, md_dst, flag_subdata);
+ ModifierData *md_dst = BKE_modifier_copy_ex(md_src, flag_subdata);
BLI_addtail(&ob_dst->modifiers, md_dst);
}
diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh
index eac43506874..b6b3d15aefe 100644
--- a/source/blender/blenlib/BLI_math_vec_types.hh
+++ b/source/blender/blenlib/BLI_math_vec_types.hh
@@ -353,7 +353,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
friend vec_base operator/(const vec_base &a, const vec_base &b)
{
- BLI_assert(!math::is_any_zero());
+ BLI_assert(!math::is_any_zero(b));
BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] / b[i]);
}
@@ -365,7 +365,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
friend vec_base operator/(T a, const vec_base &b)
{
- BLI_assert(!math::is_any_zero());
+ BLI_assert(!math::is_any_zero(b));
BLI_VEC_OP_IMPL(ret, i, ret[i] = a / b[i]);
}
@@ -377,7 +377,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
vec_base &operator/=(const vec_base &b)
{
- BLI_assert(!b != T(0));
+ BLI_assert(b != T(0));
BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b[i]);
}
@@ -509,7 +509,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
BLI_INT_OP(T) friend vec_base operator%(const vec_base &a, const vec_base &b)
{
- BLI_assert(!math::is_any_zero());
+ BLI_assert(!math::is_any_zero(b));
BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] % b[i]);
}
diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c
index 485836eca72..e90a0ee02db 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -3,7 +3,7 @@
/** \file
* \ingroup bli
- * Windows-posix compatibility layer, windows-specific functions.
+ * WIN32-POSIX compatibility layer, MS-Windows-specific functions.
*/
#ifdef WIN32
diff --git a/source/blender/blenloader/BLO_undofile.h b/source/blender/blenloader/BLO_undofile.h
index 49f7f62cb9b..48334444c4c 100644
--- a/source/blender/blenloader/BLO_undofile.h
+++ b/source/blender/blenloader/BLO_undofile.h
@@ -5,7 +5,7 @@
/** \file
* \ingroup blenloader
- * External writefile function prototypes.
+ * External write-file function prototypes.
*/
#include "BLI_filereader.h"
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
index e9525ce9de0..d8f8a1cc03f 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
@@ -254,31 +254,8 @@ void main()
* Morgan McGuire and Kyle Whitson
* http://graphics.cs.williams.edu
*
- *
- * Copyright (c) Morgan McGuire and Williams College, 2006
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-2-Clause
+ * Copyright 2006 Morgan McGuire and Williams College, All rights reserved.
*/
#ifdef BLUR2
diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
index 7efd0de7a44..ac2e5bbca2e 100644
--- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc
+++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
@@ -1340,8 +1340,9 @@ void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache,
drw_subdiv_compute_dispatch(cache, shader, 0, dst_offset, cache->num_subdiv_quads);
- /* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array. */
- GPU_memory_barrier(GPU_BARRIER_VERTEX_ATTRIB_ARRAY);
+ /* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array. Put
+ * a barrier on the shader storage as we may use the result in another compute shader. */
+ GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE | GPU_BARRIER_VERTEX_ATTRIB_ARRAY);
/* Cleanup. */
GPU_shader_unbind();
@@ -1422,6 +1423,28 @@ void draw_subdiv_finalize_normals(const DRWSubdivCache *cache,
GPU_shader_unbind();
}
+void draw_subdiv_finalize_custom_normals(const DRWSubdivCache *cache,
+ GPUVertBuf *src_custom_normals,
+ GPUVertBuf *pos_nor)
+{
+ GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_FINALIZE, "#define CUSTOM_NORMALS");
+ GPU_shader_bind(shader);
+
+ GPU_vertbuf_bind_as_ssbo(src_custom_normals, 0);
+ /* outputPosNor is bound at index 2 in the base shader. */
+ GPU_vertbuf_bind_as_ssbo(pos_nor, 2);
+
+ drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads);
+
+ /* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array.
+ * We also need it for subsequent compute shaders, so a barrier on the shader storage is also
+ * needed. */
+ GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE | GPU_BARRIER_VERTEX_ATTRIB_ARRAY);
+
+ /* Cleanup. */
+ GPU_shader_unbind();
+}
+
void draw_subdiv_build_tris_buffer(const DRWSubdivCache *cache,
GPUIndexBuf *subdiv_tris,
const int material_count)
@@ -1813,6 +1836,11 @@ static bool draw_subdiv_create_requested_buffers(const Scene *scene,
/* We can only evaluate limit normals if the patches are adaptive. */
draw_cache->do_limit_normals = settings.is_adaptive;
+ draw_cache->use_custom_loop_normals = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) &&
+ (mesh_eval->flag & ME_AUTOSMOOTH) &&
+ CustomData_has_layer(&mesh_eval->ldata,
+ CD_CUSTOMLOOPNORMAL);
+
if (DRW_ibo_requested(mbc->buff.ibo.tris)) {
draw_subdiv_cache_ensure_mat_offsets(draw_cache, mesh_eval, batch_cache->mat_len);
}
diff --git a/source/blender/draw/intern/draw_subdivision.h b/source/blender/draw/intern/draw_subdivision.h
index 394482c0862..6714ba571e5 100644
--- a/source/blender/draw/intern/draw_subdivision.h
+++ b/source/blender/draw/intern/draw_subdivision.h
@@ -52,6 +52,7 @@ typedef struct DRWSubdivCache {
struct Subdiv *subdiv;
bool optimal_display;
bool do_limit_normals;
+ bool use_custom_loop_normals;
/* Coordinates used to evaluate patches for UVs, positions, and normals. */
struct GPUVertBuf *patch_coords;
@@ -171,6 +172,10 @@ void draw_subdiv_finalize_normals(const DRWSubdivCache *cache,
struct GPUVertBuf *subdiv_loop_subdiv_vert_index,
struct GPUVertBuf *pos_nor);
+void draw_subdiv_finalize_custom_normals(const DRWSubdivCache *cache,
+ GPUVertBuf *src_custom_normals,
+ GPUVertBuf *pos_nor);
+
void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache,
struct GPUVertBuf *pos_nor,
bool do_limit_normals);
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
index 6e2cb8ad3e3..bd7f1ba0128 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
@@ -200,6 +200,16 @@ static GPUVertFormat *get_normals_format()
return &format;
}
+static GPUVertFormat *get_custom_normals_format()
+{
+ static GPUVertFormat format = {0};
+ if (format.attr_len == 0) {
+ GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ GPU_vertformat_alias_add(&format, "lnor");
+ }
+ return &format;
+}
+
static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
struct MeshBatchCache *UNUSED(cache),
@@ -207,7 +217,8 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
void *UNUSED(data))
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
- const bool do_limit_normals = subdiv_cache->do_limit_normals;
+ const bool do_limit_normals = subdiv_cache->do_limit_normals &&
+ !subdiv_cache->use_custom_loop_normals;
/* Initialize the vertex buffer, it was already allocated. */
GPU_vertbuf_init_build_on_device(
@@ -215,7 +226,31 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
draw_subdiv_extract_pos_nor(subdiv_cache, vbo, do_limit_normals);
- if (!do_limit_normals) {
+ if (subdiv_cache->use_custom_loop_normals) {
+ Mesh *coarse_mesh = subdiv_cache->mesh;
+ float(*lnors)[3] = static_cast<float(*)[3]>(
+ CustomData_get_layer(&coarse_mesh->ldata, CD_NORMAL));
+ BLI_assert(lnors != NULL);
+
+ GPUVertBuf *src_custom_normals = GPU_vertbuf_calloc();
+ GPU_vertbuf_init_with_format(src_custom_normals, get_custom_normals_format());
+ GPU_vertbuf_data_alloc(src_custom_normals, coarse_mesh->totloop);
+
+ memcpy(
+ GPU_vertbuf_get_data(src_custom_normals), lnors, sizeof(float[3]) * coarse_mesh->totloop);
+
+ GPUVertBuf *dst_custom_normals = GPU_vertbuf_calloc();
+ GPU_vertbuf_init_build_on_device(
+ dst_custom_normals, get_custom_normals_format(), subdiv_cache->num_subdiv_loops);
+
+ draw_subdiv_interp_custom_data(subdiv_cache, src_custom_normals, dst_custom_normals, 3, 0);
+
+ draw_subdiv_finalize_custom_normals(subdiv_cache, dst_custom_normals, vbo);
+
+ GPU_vertbuf_discard(src_custom_normals);
+ GPU_vertbuf_discard(dst_custom_normals);
+ }
+ else if (!do_limit_normals) {
/* We cannot evaluate vertex normals using the limit surface, so compute them manually. */
GPUVertBuf *subdiv_loop_subdiv_vert_index = draw_subdiv_build_origindex_buffer(
subdiv_cache->subdiv_loop_subdiv_vert_index, subdiv_cache->num_subdiv_loops);
diff --git a/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl
index 36c3970d9a0..df0016761e2 100644
--- a/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl
+++ b/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl
@@ -185,7 +185,7 @@ void main()
}
else {
/* Interpolate the src data for the center. */
- uint loop_end = loop_start + number_of_vertices - 1;
+ uint loop_end = loop_start + number_of_vertices;
Vertex center_value;
clear(center_value);
@@ -202,7 +202,7 @@ void main()
uint prev_coarse_corner = (current_coarse_corner + number_of_vertices - 1) %
number_of_vertices;
- v0 = read_vertex(loop_start);
+ v0 = read_vertex(loop_start + current_coarse_corner);
v1 = average(v0, read_vertex(loop_start + next_coarse_corner));
v3 = average(v0, read_vertex(loop_start + prev_coarse_corner));
diff --git a/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl
index 84cd65d4161..c2e0e752783 100644
--- a/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl
+++ b/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl
@@ -1,6 +1,18 @@
/* To be compile with common_subdiv_lib.glsl */
+#ifdef CUSTOM_NORMALS
+struct CustomNormal {
+ float x;
+ float y;
+ float z;
+};
+
+layout(std430, binding = 0) readonly buffer inputNormals
+{
+ CustomNormal custom_normals[];
+};
+#else
layout(std430, binding = 0) readonly buffer inputNormals
{
vec3 vertex_normals[];
@@ -10,6 +22,7 @@ layout(std430, binding = 1) readonly buffer inputSubdivVertLoopMap
{
uint vert_loop_map[];
};
+#endif
layout(std430, binding = 2) buffer outputPosNor
{
@@ -26,9 +39,17 @@ void main()
uint start_loop_index = quad_index * 4;
+#ifdef CUSTOM_NORMALS
+ for (int i = 0; i < 4; i++) {
+ CustomNormal custom_normal = custom_normals[start_loop_index + i];
+ vec3 nor = vec3(custom_normal.x, custom_normal.y, custom_normal.z);
+ set_vertex_nor(pos_nor[start_loop_index + i], normalize(nor));
+ }
+#else
for (int i = 0; i < 4; i++) {
uint subdiv_vert_index = vert_loop_map[start_loop_index + i];
vec3 nor = vertex_normals[subdiv_vert_index];
set_vertex_nor(pos_nor[start_loop_index + i], nor);
}
+#endif
}
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 976c5988aa6..e8f097d0018 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -1811,7 +1811,7 @@ static void gpencil_sculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *
gso->mval[1] = mouse[1] = (int)(mousef[1]);
/* If the mouse/pen has not moved, no reason to continue. This also avoid a small
- * drift due precision acumulation errors. */
+ * drift due precision accumulation errors. */
if ((gso->mval[0] == gso->mval_prev[0]) && (gso->mval[1] == gso->mval_prev[1])) {
return;
}
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 87d5adda213..bd3a6bce8e8 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -15,9 +15,9 @@ extern "C" {
#endif
struct GPUBatch;
+struct IDRemapper;
struct Main;
struct bContext;
-struct IDRemapper;
/* ed_util.c */
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 0c9ddc97508..26af378b1b7 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -97,8 +97,7 @@ bool uvedit_face_select_test(const struct Scene *scene, struct BMFace *efa, int
bool uvedit_edge_select_test(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset);
bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset);
/* uv face */
-void uvedit_face_select_set_with_sticky(const struct SpaceImage *sima,
- const struct Scene *scene,
+void uvedit_face_select_set_with_sticky(const struct Scene *scene,
struct BMEditMesh *em,
struct BMFace *efa,
bool select,
@@ -120,8 +119,7 @@ void uvedit_face_select_disable(const struct Scene *scene,
struct BMFace *efa,
int cd_loop_uv_offset);
/* uv edge */
-void uvedit_edge_select_set_with_sticky(const struct SpaceImage *sima,
- const struct Scene *scene,
+void uvedit_edge_select_set_with_sticky(const struct Scene *scene,
struct BMEditMesh *em,
struct BMLoop *l,
bool select,
@@ -143,8 +141,7 @@ void uvedit_edge_select_disable(const struct Scene *scene,
struct BMLoop *l,
int cd_loop_uv_offset);
/* uv vert */
-void uvedit_uv_select_set_with_sticky(const struct SpaceImage *sima,
- const struct Scene *scene,
+void uvedit_uv_select_set_with_sticky(const struct Scene *scene,
struct BMEditMesh *em,
struct BMLoop *l,
bool select,
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index db66aad4a7c..12215083eb6 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -6059,7 +6059,8 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
view_data = IDP_GetPropertyTypeFromGroup(idgroup, PROJ_VIEW_DATA_ID, IDP_ARRAY);
/* type check to make sure its ok */
- if (view_data->len != PROJ_VIEW_DATA_SIZE || view_data->subtype != IDP_FLOAT) {
+ if (view_data != NULL &&
+ (view_data->len != PROJ_VIEW_DATA_SIZE || view_data->subtype != IDP_FLOAT)) {
BKE_report(op->reports, RPT_ERROR, "Image project data invalid");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate.h b/source/blender/editors/space_view3d/view3d_navigate.h
index 5fbfb3e9bd8..127d08580dc 100644
--- a/source/blender/editors/space_view3d/view3d_navigate.h
+++ b/source/blender/editors/space_view3d/view3d_navigate.h
@@ -14,15 +14,15 @@
#define V3D_OP_TRACKBALLSIZE (1.1f)
struct ARegion;
-struct bContext;
struct Depsgraph;
struct Dial;
struct Main;
-struct rcti;
struct RegionView3D;
struct Scene;
struct ScrArea;
struct View3D;
+struct bContext;
+struct rcti;
struct wmEvent;
struct wmOperator;
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 3d5b9207ad1..ccaabe18620 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -1572,7 +1572,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
const ToolSettings *ts = scene->toolsettings;
const bool use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
- const bool stickymode = sima ? (sima->sticky != SI_STICKY_DISABLE) : 1;
+ const bool stickymode = sima ? (ts->uv_sticky != SI_STICKY_DISABLE) : 1;
const bool select = RNA_boolean_get(op->ptr, "select");
uint objects_len = 0;
diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c
index 225b595852f..33621c1f0b6 100644
--- a/source/blender/editors/uvedit/uvedit_path.c
+++ b/source/blender/editors/uvedit/uvedit_path.c
@@ -138,7 +138,6 @@ struct PathSelectParams {
};
struct UserData_UV {
- const SpaceImage *sima;
Scene *scene;
BMEditMesh *em;
uint cd_loop_uv_offset;
@@ -226,8 +225,7 @@ static void looptag_set_cb(BMLoop *l, bool val, void *user_data_v)
}
}
-static int mouse_mesh_uv_shortest_path_vert(const SpaceImage *sima,
- Scene *scene,
+static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
Object *obedit,
const struct PathSelectParams *op_params,
BMLoop *l_src,
@@ -269,7 +267,6 @@ static int mouse_mesh_uv_shortest_path_vert(const SpaceImage *sima,
}
struct UserData_UV user_data = {
- .sima = sima,
.scene = scene,
.em = em,
.cd_loop_uv_offset = cd_loop_uv_offset,
@@ -389,15 +386,13 @@ static bool facetag_test_cb(BMFace *f, void *user_data_v)
static void facetag_set_cb(BMFace *f, bool val, void *user_data_v)
{
struct UserData_UV *user_data = user_data_v;
- const SpaceImage *sima = user_data->sima;
const Scene *scene = user_data->scene;
BMEditMesh *em = user_data->em;
const uint cd_loop_uv_offset = user_data->cd_loop_uv_offset;
- uvedit_face_select_set_with_sticky(sima, scene, em, f, val, false, cd_loop_uv_offset);
+ uvedit_face_select_set_with_sticky(scene, em, f, val, false, cd_loop_uv_offset);
}
-static int mouse_mesh_uv_shortest_path_face(const SpaceImage *sima,
- Scene *scene,
+static int mouse_mesh_uv_shortest_path_face(Scene *scene,
Object *obedit,
const struct PathSelectParams *op_params,
BMFace *f_src,
@@ -410,7 +405,6 @@ static int mouse_mesh_uv_shortest_path_face(const SpaceImage *sima,
int flush = 0;
struct UserData_UV user_data = {
- .sima = sima,
.scene = scene,
.em = em,
.cd_loop_uv_offset = cd_loop_uv_offset,
@@ -489,8 +483,7 @@ static int mouse_mesh_uv_shortest_path_face(const SpaceImage *sima,
static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op);
-static bool uv_shortest_path_pick_ex(const SpaceImage *sima,
- Scene *scene,
+static bool uv_shortest_path_pick_ex(Scene *scene,
Depsgraph *depsgraph,
Object *obedit,
const struct PathSelectParams *op_params,
@@ -508,8 +501,7 @@ static bool uv_shortest_path_pick_ex(const SpaceImage *sima,
/* pass */
}
else if (ele_src->head.htype == BM_FACE) {
- flush = mouse_mesh_uv_shortest_path_face(sima,
- scene,
+ flush = mouse_mesh_uv_shortest_path_face(scene,
obedit,
op_params,
(BMFace *)ele_src,
@@ -519,8 +511,7 @@ static bool uv_shortest_path_pick_ex(const SpaceImage *sima,
ok = true;
}
else if (ele_src->head.htype == BM_LOOP) {
- flush = mouse_mesh_uv_shortest_path_vert(sima,
- scene,
+ flush = mouse_mesh_uv_shortest_path_vert(scene,
obedit,
op_params,
(BMLoop *)ele_src,
@@ -560,7 +551,6 @@ static bool uv_shortest_path_pick_ex(const SpaceImage *sima,
static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
const char uv_selectmode = ED_uvedit_select_mode_get(scene);
@@ -667,7 +657,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
}
uv_shortest_path_pick_ex(
- sima, scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset);
+ scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset);
/* To support redo. */
int index;
@@ -691,7 +681,6 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- const SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
const char uv_selectmode = ED_uvedit_select_mode_get(scene);
Object *obedit = CTX_data_edit_object(C);
@@ -742,15 +731,8 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op)
path_select_params_from_op(op, &op_params);
op_params.track_active = true;
- if (!uv_shortest_path_pick_ex(sima,
- scene,
- depsgraph,
- obedit,
- &op_params,
- ele_src,
- ele_dst,
- aspect_y,
- cd_loop_uv_offset)) {
+ if (!uv_shortest_path_pick_ex(
+ scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset)) {
return OPERATOR_CANCELLED;
}
@@ -791,7 +773,6 @@ void UV_OT_shortest_path_pick(wmOperatorType *ot)
static int uv_shortest_path_select_exec(bContext *C, wmOperator *op)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- const SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
const char uv_selectmode = ED_uvedit_select_mode_get(scene);
bool found_valid_elements = false;
@@ -840,15 +821,8 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op)
struct PathSelectParams op_params;
path_select_params_from_op(op, &op_params);
- uv_shortest_path_pick_ex(sima,
- scene,
- depsgraph,
- obedit,
- &op_params,
- ele_src,
- ele_dst,
- aspect_y,
- cd_loop_uv_offset);
+ uv_shortest_path_pick_ex(
+ scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset);
found_valid_elements = true;
}
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index 75bcf7c546e..4454a8414b5 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -63,14 +63,8 @@ static void uv_select_all_perform_multi(Scene *scene,
const uint objects_len,
int action);
-static void uv_select_flush_from_tag_face(SpaceImage *sima,
- Scene *scene,
- Object *obedit,
- const bool select);
-static void uv_select_flush_from_tag_loop(SpaceImage *sima,
- Scene *scene,
- Object *obedit,
- const bool select);
+static void uv_select_flush_from_tag_face(Scene *scene, Object *obedit, const bool select);
+static void uv_select_flush_from_tag_loop(Scene *scene, Object *obedit, const bool select);
static void uv_select_tag_update_for_object(Depsgraph *depsgraph,
const ToolSettings *ts,
Object *obedit);
@@ -234,8 +228,7 @@ bool uvedit_face_select_test(const Scene *scene, BMFace *efa, const int cd_loop_
return uvedit_face_select_test_ex(scene->toolsettings, efa, cd_loop_uv_offset);
}
-void uvedit_face_select_set_with_sticky(const SpaceImage *sima,
- const Scene *scene,
+void uvedit_face_select_set_with_sticky(const Scene *scene,
BMEditMesh *em,
BMFace *efa,
const bool select,
@@ -251,8 +244,7 @@ void uvedit_face_select_set_with_sticky(const SpaceImage *sima,
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
do {
- uvedit_uv_select_set_with_sticky(
- sima, scene, em, l_iter, select, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(scene, em, l_iter, select, do_history, cd_loop_uv_offset);
} while ((l_iter = l_iter->next) != l_first);
}
@@ -344,8 +336,7 @@ bool uvedit_edge_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv
return uvedit_edge_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset);
}
-void uvedit_edge_select_set_with_sticky(const struct SpaceImage *sima,
- const Scene *scene,
+void uvedit_edge_select_set_with_sticky(const Scene *scene,
BMEditMesh *em,
BMLoop *l,
const bool select,
@@ -358,9 +349,8 @@ void uvedit_edge_select_set_with_sticky(const struct SpaceImage *sima,
return;
}
- uvedit_uv_select_set_with_sticky(sima, scene, em, l, select, do_history, cd_loop_uv_offset);
- uvedit_uv_select_set_with_sticky(
- sima, scene, em, l->next, select, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(scene, em, l, select, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(scene, em, l->next, select, do_history, cd_loop_uv_offset);
}
void uvedit_edge_select_set(const Scene *scene,
@@ -463,8 +453,7 @@ bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_o
return uvedit_uv_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset);
}
-void uvedit_uv_select_set_with_sticky(const struct SpaceImage *sima,
- const Scene *scene,
+void uvedit_uv_select_set_with_sticky(const Scene *scene,
BMEditMesh *em,
BMLoop *l,
const bool select,
@@ -477,7 +466,7 @@ void uvedit_uv_select_set_with_sticky(const struct SpaceImage *sima,
return;
}
- const int sticky = sima->sticky;
+ const int sticky = ts->uv_sticky;
switch (sticky) {
case SI_STICKY_DISABLE: {
uvedit_uv_select_set(scene, em, l, select, do_history, cd_loop_uv_offset);
@@ -1133,8 +1122,7 @@ static void uv_select_edgeloop_single_side_tag(const Scene *scene,
}
}
-static int uv_select_edgeloop(
- SpaceImage *sima, Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend)
+static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
bool select;
@@ -1197,8 +1185,7 @@ static int uv_select_edgeloop(
BMLoop *l_iter;
BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l_iter, BM_ELEM_TAG)) {
- uvedit_edge_select_set_with_sticky(
- sima, scene, em, l_iter, select, false, cd_loop_uv_offset);
+ uvedit_edge_select_set_with_sticky(scene, em, l_iter, select, false, cd_loop_uv_offset);
}
}
}
@@ -1213,8 +1200,7 @@ static int uv_select_edgeloop(
/** \name Edge Ring Select
* \{ */
-static int uv_select_edgering(
- const SpaceImage *sima, Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend)
+static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend)
{
const ToolSettings *ts = scene->toolsettings;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -1253,12 +1239,10 @@ static int uv_select_edgering(
}
if (use_face_select) {
- uvedit_face_select_set_with_sticky(
- sima, scene, em, l_step->f, select, false, cd_loop_uv_offset);
+ uvedit_face_select_set_with_sticky(scene, em, l_step->f, select, false, cd_loop_uv_offset);
}
else {
- uvedit_edge_select_set_with_sticky(
- sima, scene, em, l_step, select, false, cd_loop_uv_offset);
+ uvedit_edge_select_set_with_sticky(scene, em, l_step, select, false, cd_loop_uv_offset);
}
BM_elem_flag_enable(l_step->e, BM_ELEM_TAG);
@@ -1544,7 +1528,6 @@ static int uv_select_more_less(bContext *C, const bool select)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- SpaceImage *sima = CTX_wm_space_image(C);
BMFace *efa;
BMLoop *l;
@@ -1643,11 +1626,11 @@ static int uv_select_more_less(bContext *C, const bool select)
if (changed) {
if (is_uv_face_selectmode) {
/* Select tagged faces. */
- uv_select_flush_from_tag_face(sima, scene, obedit, select);
+ uv_select_flush_from_tag_face(scene, obedit, select);
}
else {
/* Select tagged loops. */
- uv_select_flush_from_tag_loop(sima, scene, obedit, select);
+ uv_select_flush_from_tag_loop(scene, obedit, select);
}
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
@@ -1877,7 +1860,6 @@ static int uv_mouse_select_multi(bContext *C,
const bool deselect_all)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- SpaceImage *sima = CTX_wm_space_image(C);
const ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
@@ -1907,7 +1889,7 @@ static int uv_mouse_select_multi(bContext *C,
}
else {
selectmode = ts->uv_selectmode;
- sticky = (sima) ? sima->sticky : SI_STICKY_DISABLE;
+ sticky = ts->uv_sticky;
}
/* find nearest element */
@@ -1991,20 +1973,19 @@ static int uv_mouse_select_multi(bContext *C,
if (selectmode == UV_SELECT_VERTEX) {
/* (de)select uv vertex */
select = !uvedit_uv_select_test(scene, hit.l, cd_loop_uv_offset);
- uvedit_uv_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset);
flush = 1;
}
else if (selectmode == UV_SELECT_EDGE) {
/* (de)select edge */
select = !(uvedit_edge_select_test(scene, hit.l, cd_loop_uv_offset));
- uvedit_edge_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset);
+ uvedit_edge_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset);
flush = 1;
}
else if (selectmode == UV_SELECT_FACE) {
/* (de)select face */
select = !(uvedit_face_select_test(scene, hit.efa, cd_loop_uv_offset));
- uvedit_face_select_set_with_sticky(
- sima, scene, em, hit.efa, select, true, cd_loop_uv_offset);
+ uvedit_face_select_set_with_sticky(scene, em, hit.efa, select, true, cd_loop_uv_offset);
flush = -1;
}
@@ -2027,18 +2008,17 @@ static int uv_mouse_select_multi(bContext *C,
if (selectmode == UV_SELECT_VERTEX) {
/* select vertex */
- uvedit_uv_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset);
flush = 1;
}
else if (selectmode == UV_SELECT_EDGE) {
/* select edge */
- uvedit_edge_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset);
+ uvedit_edge_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset);
flush = 1;
}
else if (selectmode == UV_SELECT_FACE) {
/* select face */
- uvedit_face_select_set_with_sticky(
- sima, scene, em, hit.efa, select, true, cd_loop_uv_offset);
+ uvedit_face_select_set_with_sticky(scene, em, hit.efa, select, true, cd_loop_uv_offset);
flush = 1;
}
}
@@ -2154,7 +2134,6 @@ static int uv_mouse_select_loop_generic_multi(bContext *C,
const bool extend,
enum eUVLoopGenericType loop_type)
{
- SpaceImage *sima = CTX_wm_space_image(C);
const ARegion *region = CTX_wm_region(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
@@ -2179,10 +2158,10 @@ static int uv_mouse_select_loop_generic_multi(bContext *C,
}
if (loop_type == UV_LOOP_SELECT) {
- flush = uv_select_edgeloop(sima, scene, obedit, &hit, extend);
+ flush = uv_select_edgeloop(scene, obedit, &hit, extend);
}
else if (loop_type == UV_RING_SELECT) {
- flush = uv_select_edgering(sima, scene, obedit, &hit, extend);
+ flush = uv_select_edgering(scene, obedit, &hit, extend);
}
else {
BLI_assert_unreachable();
@@ -2686,10 +2665,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal(Scene *scene,
* \note This function is very similar to #uv_select_flush_from_tag_loop,
* be sure to update both upon changing.
*/
-static void uv_select_flush_from_tag_face(SpaceImage *sima,
- Scene *scene,
- Object *obedit,
- const bool select)
+static void uv_select_flush_from_tag_face(Scene *scene, Object *obedit, const bool select)
{
/* Selecting UV Faces with some modes requires us to change
* the selection in other faces (depending on the sticky mode).
@@ -2704,7 +2680,7 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima,
BMIter iter, liter;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_VERTEX) {
+ if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_VERTEX) {
/* Tag all verts as untouched, then touch the ones that have a face center
* in the loop and select all MLoopUV's that use a touched vert. */
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
@@ -2728,7 +2704,7 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima,
}
}
}
- else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_LOC) {
+ else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_LOC) {
struct UvVertMap *vmap;
uint efa_index;
@@ -2769,10 +2745,7 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima,
* \note This function is very similar to #uv_select_flush_from_tag_loop,
* be sure to update both upon changing.
*/
-static void uv_select_flush_from_tag_loop(SpaceImage *sima,
- Scene *scene,
- Object *obedit,
- const bool select)
+static void uv_select_flush_from_tag_loop(Scene *scene, Object *obedit, const bool select)
{
/* Selecting UV Loops with some modes requires us to change
* the selection in other faces (depending on the sticky mode).
@@ -2788,7 +2761,7 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima,
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_VERTEX) {
+ if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_VERTEX) {
/* Tag all verts as untouched, then touch the ones that have a face center
* in the loop and select all MLoopUV's that use a touched vert. */
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
@@ -2812,7 +2785,7 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima,
}
}
}
- else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_LOC) {
+ else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_LOC) {
struct UvVertMap *vmap;
uint efa_index;
@@ -2854,7 +2827,6 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima,
static int uv_box_select_exec(bContext *C, wmOperator *op)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -2923,7 +2895,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
/* (de)selects all tagged faces and deals with sticky modes */
if (changed) {
- uv_select_flush_from_tag_face(sima, scene, obedit, select);
+ uv_select_flush_from_tag_face(scene, obedit, select);
}
}
else if (use_edge && !pinned) {
@@ -2939,7 +2911,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (BLI_rctf_isect_pt_v(&rectf, luv->uv) && BLI_rctf_isect_pt_v(&rectf, luv_prev->uv)) {
uvedit_edge_select_set_with_sticky(
- sima, scene, em, l_prev, select, false, cd_loop_uv_offset);
+ scene, em, l_prev, select, false, cd_loop_uv_offset);
changed = true;
}
l_prev = l;
@@ -2985,7 +2957,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
}
}
- if (sima->sticky == SI_STICKY_VERTEX) {
+ if (ts->uv_sticky == SI_STICKY_VERTEX) {
uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
}
}
@@ -3142,7 +3114,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
/* (de)selects all tagged faces and deals with sticky modes */
if (changed) {
- uv_select_flush_from_tag_face(sima, scene, obedit, select);
+ uv_select_flush_from_tag_face(scene, obedit, select);
}
}
else if (use_edge) {
@@ -3158,7 +3130,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (uv_circle_select_is_edge_inside(luv->uv, luv_prev->uv, offset, ellipse)) {
uvedit_edge_select_set_with_sticky(
- sima, scene, em, l_prev, select, false, cd_loop_uv_offset);
+ scene, em, l_prev, select, false, cd_loop_uv_offset);
changed = true;
}
l_prev = l;
@@ -3194,7 +3166,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
}
}
- if (sima->sticky == SI_STICKY_VERTEX) {
+ if (ts->uv_sticky == SI_STICKY_VERTEX) {
uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
}
}
@@ -3262,7 +3234,6 @@ static bool do_lasso_select_mesh_uv(bContext *C,
const eSelectOp sel_op)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- SpaceImage *sima = CTX_wm_space_image(C);
const ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
@@ -3321,7 +3292,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
/* (de)selects all tagged faces and deals with sticky modes */
if (changed) {
- uv_select_flush_from_tag_face(sima, scene, obedit, select);
+ uv_select_flush_from_tag_face(scene, obedit, select);
}
}
else if (use_edge) {
@@ -3340,7 +3311,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
do_lasso_select_mesh_uv_is_point_inside(
region, &rect, mcoords, mcoords_len, luv_prev->uv)) {
uvedit_edge_select_set_with_sticky(
- sima, scene, em, l_prev, select, false, cd_loop_uv_offset);
+ scene, em, l_prev, select, false, cd_loop_uv_offset);
changed = true;
}
l_prev = l;
@@ -3377,7 +3348,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
}
}
- if (sima->sticky == SI_STICKY_VERTEX) {
+ if (ts->uv_sticky == SI_STICKY_VERTEX) {
uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
}
}
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 9472aed79a5..d689fbe14b5 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -287,6 +287,12 @@ void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter);
void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp);
void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4]);
+/**
+ * Return the number of dimensions of the texture ignoring dimension of layers (1, 2 or 3).
+ * Cube textures are considered 2D.
+ */
+int GPU_texture_dimensions(const GPUTexture *tex);
+
int GPU_texture_width(const GPUTexture *tex);
int GPU_texture_height(const GPUTexture *tex);
int GPU_texture_orig_width(const GPUTexture *tex);
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index 19c7c5d78ff..da5f08f003e 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -507,6 +507,25 @@ void GPU_texture_ref(GPUTexture *tex)
reinterpret_cast<Texture *>(tex)->refcount++;
}
+int GPU_texture_dimensions(const GPUTexture *tex_)
+{
+ eGPUTextureType type = reinterpret_cast<const Texture *>(tex_)->type_get();
+ if (type & GPU_TEXTURE_1D) {
+ return 1;
+ }
+ else if (type & GPU_TEXTURE_2D) {
+ return 2;
+ }
+ else if (type & GPU_TEXTURE_3D) {
+ return 3;
+ }
+ else if (type & GPU_TEXTURE_CUBE) {
+ return 2;
+ }
+ /* GPU_TEXTURE_BUFFER */
+ return 1;
+}
+
int GPU_texture_width(const GPUTexture *tex)
{
return reinterpret_cast<const Texture *>(tex)->width_get();
diff --git a/source/blender/io/usd/intern/usd_writer_material.h b/source/blender/io/usd/intern/usd_writer_material.h
index 80b5626e3bd..3e9b84477d5 100644
--- a/source/blender/io/usd/intern/usd_writer_material.h
+++ b/source/blender/io/usd/intern/usd_writer_material.h
@@ -8,10 +8,10 @@
#include <string>
-struct bNode;
-struct bNodeTree;
struct Material;
struct USDExportParams;
+struct bNode;
+struct bNodeTree;
namespace blender::io::usd {
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index c0a9cc1ec41..fe3613548a6 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -18,8 +18,8 @@ extern "C" {
struct AnimData;
struct Curve;
struct Curve;
-struct MDeformVert;
struct GPencilUpdateCache;
+struct MDeformVert;
#define GP_DEFAULT_PIX_FACTOR 1.0f
#define GP_DEFAULT_GRID_LINES 4
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index a3e4551a865..0d42abdb363 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1391,13 +1391,14 @@ typedef struct ToolSettings {
char object_flag;
/* Selection Mode for Mesh */
- short selectmode;
+ char selectmode;
/* UV Calculation */
char unwrapper;
char uvcalc_flag;
char uv_flag;
char uv_selectmode;
+ char uv_sticky;
float uvcalc_margin;
@@ -2300,6 +2301,13 @@ enum {
#define UV_SELECT_FACE 4
#define UV_SELECT_ISLAND 8
+/** #ToolSettings.uv_sticky */
+enum {
+ SI_STICKY_LOC = 0,
+ SI_STICKY_DISABLE = 1,
+ SI_STICKY_VERTEX = 2,
+};
+
/** #ToolSettings.gpencil_flags */
typedef enum eGPencil_Flags {
/* When creating new frames, the last frame gets used as the basis for the new one */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index ad7f8cc1e40..b1212965992 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -1214,11 +1214,10 @@ typedef struct SpaceImage {
/** UV draw type. */
char dt_uv;
/** Sticky selection type. */
- char sticky;
char dt_uvstretch;
char around;
- char _pad1[3];
+ char _pad1[4];
int flag;
@@ -1265,15 +1264,6 @@ typedef enum eSpaceImage_Mode {
SI_MODE_UV = 3,
} eSpaceImage_Mode;
-/* SpaceImage.sticky
- * Note DISABLE should be 0, however would also need to re-arrange icon order,
- * also, sticky loc is the default mode so this means we don't need to 'do_versions' */
-typedef enum eSpaceImage_Sticky {
- SI_STICKY_LOC = 0,
- SI_STICKY_DISABLE = 1,
- SI_STICKY_VERTEX = 2,
-} eSpaceImage_Sticky;
-
/** #SpaceImage.flag */
typedef enum eSpaceImage_Flag {
SI_FLAG_UNUSED_0 = (1 << 0), /* cleared */
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index c8f65e5e153..178029ef340 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -2883,6 +2883,25 @@ static void rna_def_tool_settings(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem uv_sticky_mode_items[] = {
+ {SI_STICKY_DISABLE,
+ "DISABLED",
+ ICON_STICKY_UVS_DISABLE,
+ "Disabled",
+ "Sticky vertex selection disabled"},
+ {SI_STICKY_LOC,
+ "SHARED_LOCATION",
+ ICON_STICKY_UVS_LOC,
+ "Shared Location",
+ "Select UVs that are at the same location and share a mesh vertex"},
+ {SI_STICKY_VERTEX,
+ "SHARED_VERTEX",
+ ICON_STICKY_UVS_VERT,
+ "Shared Vertex",
+ "Select UVs that share a mesh vertex, whether or not they are at the same location"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
srna = RNA_def_struct(brna, "ToolSettings", NULL);
RNA_def_struct_path_func(srna, "rna_ToolSettings_path");
RNA_def_struct_ui_text(srna, "Tool Settings", "");
@@ -3454,6 +3473,13 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "UV Selection Mode", "UV selection and display mode");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
+ prop = RNA_def_property(srna, "uv_sticky_select_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "uv_sticky");
+ RNA_def_property_enum_items(prop, uv_sticky_mode_items);
+ RNA_def_property_ui_text(
+ prop, "Sticky Selection Mode", "Method for extending UV vertex selection");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
+
prop = RNA_def_property(srna, "use_uv_select_sync", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uv_flag", UV_SYNC_SELECTION);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 20fa8b87cd2..c51f0c00498 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -3428,25 +3428,6 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static const EnumPropertyItem sticky_mode_items[] = {
- {SI_STICKY_DISABLE,
- "DISABLED",
- ICON_STICKY_UVS_DISABLE,
- "Disabled",
- "Sticky vertex selection disabled"},
- {SI_STICKY_LOC,
- "SHARED_LOCATION",
- ICON_STICKY_UVS_LOC,
- "Shared Location",
- "Select UVs that are at the same location and share a mesh vertex"},
- {SI_STICKY_VERTEX,
- "SHARED_VERTEX",
- ICON_STICKY_UVS_VERT,
- "Shared Vertex",
- "Select UVs that share a mesh vertex, whether or not they are at the same location"},
- {0, NULL, 0, NULL, NULL},
- };
-
static const EnumPropertyItem dt_uvstretch_items[] = {
{SI_UVDT_STRETCH_ANGLE, "ANGLE", 0, "Angle", "Angular distortion between UV and 3D angles"},
{SI_UVDT_STRETCH_AREA, "AREA", 0, "Area", "Area distortion between UV and 3D faces"},
@@ -3466,14 +3447,6 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_SpaceUVEditor_path");
RNA_def_struct_ui_text(srna, "Space UV Editor", "UV editor data for the image editor space");
- /* selection */
- prop = RNA_def_property(srna, "sticky_select_mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "sticky");
- RNA_def_property_enum_items(prop, sticky_mode_items);
- RNA_def_property_ui_text(
- prop, "Sticky Selection Mode", "Method for extending UV vertex selection");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
-
/* drawing */
prop = RNA_def_property(srna, "edge_display_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "dt_uv");
diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c
index 1c0b5fc782c..0853c5dd3ea 100644
--- a/source/blender/python/mathutils/mathutils_noise.c
+++ b/source/blender/python/mathutils/mathutils_noise.c
@@ -27,48 +27,20 @@
/*-----------------------------------------*/
/* 'mersenne twister' random number generator */
-/*
- * A C-program for MT19937, with initialization improved 2002/2/10.
+/* A C-program for MT19937, with initialization improved 2002/2/10.
* Coded by Takuji Nishimura and Makoto Matsumoto.
* This is a faster version by taking Shawn Cokus's optimization,
* Matthe Bellew's simplification, Isaku Wada's real version.
*
- * Before using, initialize the state by using init_genrand(seed)
- * or init_by_array(init_key, key_length).
+ * Before using, initialize the state by using
+ * `init_genrand(seed)` or `init_by_array(init_key, key_length)`.
*
- * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
- * All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 1997-2002 Makoto Matsumoto and Takuji Nishimura, All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. The names of its contributors may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Any feedback is very welcome.
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
- * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
- */
+ * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space). */
/* Period parameters */
#define N 624
diff --git a/source/blender/render/RE_pipeline.h b/source/blender/render/RE_pipeline.h
index 6250f61b11c..2d43aa7b27f 100644
--- a/source/blender/render/RE_pipeline.h
+++ b/source/blender/render/RE_pipeline.h
@@ -11,11 +11,11 @@
#include "DNA_listBase.h"
#include "DNA_vec_types.h"
+struct ImBuf;
struct Image;
struct ImageFormatData;
struct Main;
struct Object;
-struct ImBuf;
struct RenderData;
struct RenderResult;
struct ReportList;