Attributes: Add quaternion rotation type #108678
|
@ -914,10 +914,9 @@ set_and_warn_dependency(WITH_TBB WITH_MOD_FLUID OFF)
|
|||
# NanoVDB requires OpenVDB to convert the data structure
|
||||
set_and_warn_dependency(WITH_OPENVDB WITH_NANOVDB OFF)
|
||||
|
||||
# OpenVDB, Alembic and Vulkan, OSL uses 'half' or 'imath' from OpenEXR
|
||||
# OpenVDB, Alembic and OSL uses 'half' or 'imath' from OpenEXR
|
||||
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENVDB OFF)
|
||||
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_ALEMBIC OFF)
|
||||
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_VULKAN_BACKEND OFF)
|
||||
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_CYCLES_OSL OFF)
|
||||
|
||||
# auto enable openimageio for cycles
|
||||
|
|
|
@ -5,8 +5,24 @@
|
|||
#ifdef DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H
|
||||
# undef DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H
|
||||
-# define _DEBUG
|
||||
+// BLENDER: TBB excepts this to have a value.
|
||||
+// BLENDER: TBB expects this to have a value.
|
||||
+# define _DEBUG 1
|
||||
# ifdef _CRT_NOFORCE_MANIFEST_DEFINED_FROM_WRAP_PYTHON_H
|
||||
# undef _CRT_NOFORCE_MANIFEST_DEFINED_FROM_WRAP_PYTHON_H
|
||||
# undef _CRT_NOFORCE_MANIFEST
|
||||
--- a/boost/config/stdlib/libcpp.hpp 2022-08-03 22:47:07.000000000 -0400
|
||||
+++ b/boost/config/stdlib/libcpp.hpp 2022-09-16 22:16:17.044119011 -0400
|
||||
@@ -168,4 +168,13 @@
|
||||
# define BOOST_NO_CXX14_HDR_SHARED_MUTEX
|
||||
#endif
|
||||
|
||||
+#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 15000
|
||||
+//
|
||||
+// Unary function is now deprecated in C++11 and later:
|
||||
+//
|
||||
+#if __cplusplus >= 201103L
|
||||
+#define BOOST_NO_CXX98_FUNCTION_BASE
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
// --- end ---
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
# NOTE: Resolved up-stream, quiet noisy compiler warnings for now.
|
||||
add_cxx_flag("-Wno-uninitialized")
|
||||
endif()
|
||||
|
||||
set(INC
|
||||
include
|
||||
)
|
||||
|
|
|
@ -104,7 +104,7 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
|
|||
float cosHI = fabsf(dot(wi, H));
|
||||
float cosNH = dot(N, H);
|
||||
|
||||
if (!(fabsf(cosNI) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHI > 1e-5f)) {
|
||||
if (!(cosNI > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHI > 1e-5f)) {
|
||||
*pdf = 0.0f;
|
||||
*eval = zero_spectrum();
|
||||
return LABEL_NONE;
|
||||
|
|
|
@ -79,6 +79,7 @@ struct CCLShadowContext
|
|||
#endif
|
||||
IntegratorShadowState isect_s;
|
||||
float throughput;
|
||||
float max_t;
|
||||
bool opaque_hit;
|
||||
numhit_t max_hits;
|
||||
numhit_t num_hits;
|
||||
|
@ -314,7 +315,7 @@ ccl_device_forceinline void kernel_embree_filter_occluded_shadow_all_func_impl(
|
|||
/* Current implementation in Cycles assumes only single-ray intersection queries. */
|
||||
assert(args->N == 1);
|
||||
|
||||
RTCRay *ray = (RTCRay *)args->ray;
|
||||
const RTCRay *ray = (RTCRay *)args->ray;
|
||||
RTCHit *hit = (RTCHit *)args->hit;
|
||||
#if EMBREE_MAJOR_VERSION >= 4
|
||||
CCLShadowContext *ctx = (CCLShadowContext *)(args->context);
|
||||
|
@ -367,42 +368,51 @@ ccl_device_forceinline void kernel_embree_filter_occluded_shadow_all_func_impl(
|
|||
}
|
||||
}
|
||||
|
||||
/* Test if we need to record this transparent intersection. */
|
||||
const numhit_t max_record_hits = min(ctx->max_hits, numhit_t(INTEGRATOR_SHADOW_ISECT_SIZE));
|
||||
if (ctx->num_recorded_hits < max_record_hits) {
|
||||
/* If maximum number of hits was reached, replace the intersection with the
|
||||
* highest distance. We want to find the N closest intersections. */
|
||||
const numhit_t num_recorded_hits = min(ctx->num_recorded_hits, max_record_hits);
|
||||
numhit_t isect_index = num_recorded_hits;
|
||||
if (num_recorded_hits + 1 >= max_record_hits) {
|
||||
float max_t = INTEGRATOR_STATE_ARRAY(ctx->isect_s, shadow_isect, 0, t);
|
||||
numhit_t max_recorded_hit = numhit_t(0);
|
||||
|
||||
for (numhit_t i = numhit_t(1); i < num_recorded_hits; ++i) {
|
||||
const float isect_t = INTEGRATOR_STATE_ARRAY(ctx->isect_s, shadow_isect, i, t);
|
||||
if (isect_t > max_t) {
|
||||
max_recorded_hit = i;
|
||||
max_t = isect_t;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_recorded_hits >= max_record_hits) {
|
||||
isect_index = max_recorded_hit;
|
||||
}
|
||||
|
||||
/* Limit the ray distance and stop counting hits beyond this. */
|
||||
ray->tfar = max(current_isect.t, max_t);
|
||||
}
|
||||
|
||||
integrator_state_write_shadow_isect(ctx->isect_s, ¤t_isect, isect_index);
|
||||
}
|
||||
numhit_t isect_index = ctx->num_recorded_hits;
|
||||
|
||||
/* Always increase the number of recorded hits, even beyond the maximum,
|
||||
* so that we can detect this and trace another ray if needed. */
|
||||
* so that we can detect this and trace another ray if needed.
|
||||
* More details about the related logic can be found in implementation of
|
||||
* "shadow_intersections_has_remaining" and "integrate_transparent_shadow"
|
||||
* functions. */
|
||||
++ctx->num_recorded_hits;
|
||||
|
||||
/* This tells Embree to continue tracing. */
|
||||
*args->valid = 0;
|
||||
|
||||
const numhit_t max_record_hits = min(ctx->max_hits, numhit_t(INTEGRATOR_SHADOW_ISECT_SIZE));
|
||||
/* If the maximum number of hits was reached, replace the furthest intersection
|
||||
* with a closer one so we get the N closest intersections. */
|
||||
if (isect_index >= max_record_hits) {
|
||||
/* When recording only N closest hits, max_t will always only decrease.
|
||||
* So let's test if we are already not meeting criteria and can skip max_t recalculation. */
|
||||
if (current_isect.t >= ctx->max_t) {
|
||||
return;
|
||||
}
|
||||
|
||||
float max_t = INTEGRATOR_STATE_ARRAY(ctx->isect_s, shadow_isect, 0, t);
|
||||
numhit_t max_recorded_hit = numhit_t(0);
|
||||
|
||||
for (numhit_t i = numhit_t(1); i < max_record_hits; ++i) {
|
||||
const float isect_t = INTEGRATOR_STATE_ARRAY(ctx->isect_s, shadow_isect, i, t);
|
||||
if (isect_t > max_t) {
|
||||
max_recorded_hit = i;
|
||||
max_t = isect_t;
|
||||
}
|
||||
}
|
||||
|
||||
isect_index = max_recorded_hit;
|
||||
|
||||
/* Limit the ray distance and avoid processing hits beyond this. */
|
||||
ctx->max_t = max_t;
|
||||
|
||||
/* If it's further away than max_t, we don't record this transparent intersection. */
|
||||
if (current_isect.t >= max_t) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
integrator_state_write_shadow_isect(ctx->isect_s, ¤t_isect, isect_index);
|
||||
}
|
||||
|
||||
ccl_device_forceinline void kernel_embree_filter_occluded_local_func_impl(
|
||||
|
|
|
@ -197,8 +197,14 @@ ccl_device_inline void object_normal_transform(KernelGlobals kg,
|
|||
}
|
||||
#endif
|
||||
|
||||
Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
|
||||
*N = normalize(transform_direction_transposed(&tfm, *N));
|
||||
if (sd->object != OBJECT_NONE) {
|
||||
Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
|
||||
*N = normalize(transform_direction_transposed(&tfm, *N));
|
||||
}
|
||||
else if (sd->type == PRIMITIVE_LAMP) {
|
||||
Transform tfm = lamp_fetch_transform(kg, sd->lamp, true);
|
||||
*N = normalize(transform_direction_transposed(&tfm, *N));
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_inline bool object_negative_scale_applied(const int object_flag)
|
||||
|
|
|
@ -155,12 +155,15 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg,
|
|||
sd->Ng = Ng;
|
||||
sd->wi = I;
|
||||
sd->shader = shader;
|
||||
if (prim != PRIM_NONE)
|
||||
sd->type = PRIMITIVE_TRIANGLE;
|
||||
else if (lamp != LAMP_NONE)
|
||||
if (lamp != LAMP_NONE) {
|
||||
sd->type = PRIMITIVE_LAMP;
|
||||
else
|
||||
}
|
||||
else if (prim != PRIM_NONE) {
|
||||
sd->type = PRIMITIVE_TRIANGLE;
|
||||
}
|
||||
else {
|
||||
sd->type = PRIMITIVE_NONE;
|
||||
}
|
||||
|
||||
/* primitive */
|
||||
sd->object = object;
|
||||
|
|
|
@ -224,7 +224,7 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg,
|
|||
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
|
||||
}
|
||||
}
|
||||
/* GGX (either single- or multiscattering) */
|
||||
/* GGX (either single- or multi-scattering). */
|
||||
else {
|
||||
if (has_reflection && has_transmission) {
|
||||
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
|
||||
|
@ -278,7 +278,7 @@ ccl_device void osl_closure_conductor_bsdf_setup(KernelGlobals kg,
|
|||
if (closure->distribution == make_string("beckmann", 14712237670914973463ull)) {
|
||||
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
|
||||
}
|
||||
/* GGX (either single- or multiscattering) */
|
||||
/* GGX (either single- or multi-scattering) */
|
||||
else {
|
||||
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
|
||||
preserve_energy = (closure->distribution == make_string("multi_ggx", 16842698693386468366ull));
|
||||
|
@ -338,7 +338,7 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
|
|||
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
|
||||
}
|
||||
}
|
||||
/* GGX (either single- or multiscattering) */
|
||||
/* GGX (either single- or multi-scattering) */
|
||||
else {
|
||||
if (has_reflection && has_transmission) {
|
||||
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
|
||||
|
@ -414,7 +414,7 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
|
|||
else if (closure->distribution == make_string("ashikhmin_shirley", 11318482998918370922ull)) {
|
||||
sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
|
||||
}
|
||||
/* GGX (either single- or multiscattering) */
|
||||
/* GGX (either single- or multi-scattering) */
|
||||
else {
|
||||
if (closure->refract == 1) {
|
||||
sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
|
||||
|
@ -523,7 +523,7 @@ ccl_device void osl_closure_microfacet_aniso_fresnel_setup(
|
|||
bsdf->ior = closure->ior;
|
||||
bsdf->T = closure->T;
|
||||
|
||||
/* Only GGX (either single- or multiscattering) supported here */
|
||||
/* Only GGX (either single- or multi-scattering) supported here */
|
||||
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
|
||||
|
||||
const bool preserve_energy = (closure->distribution ==
|
||||
|
|
|
@ -47,7 +47,9 @@ shader node_texture_coordinate(
|
|||
if (!getattribute("geom:generated", Generated)) {
|
||||
Generated = transform("object", P);
|
||||
}
|
||||
getattribute("geom:uv", UV);
|
||||
if (!getattribute("geom:uv", UV)) {
|
||||
UV = point(1.0 - u - v, u, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (use_transform) {
|
||||
|
|
|
@ -26,7 +26,7 @@ closure color principled_diffuse(normal N, float roughness) BUILTIN;
|
|||
closure color principled_sheen(normal N) BUILTIN;
|
||||
closure color principled_clearcoat(normal N, float clearcoat, float clearcoat_roughness) BUILTIN;
|
||||
|
||||
/* Needed to pass along the color for multiscattering saturation adjustment,
|
||||
/* Needed to pass along the color for multi-scattering saturation adjustment,
|
||||
* otherwise could be replaced by microfacet() */
|
||||
closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN;
|
||||
closure color microfacet_multi_ggx_aniso(normal N, vector T, float ax, float ay, color C) BUILTIN;
|
||||
|
|
|
@ -71,6 +71,11 @@ ccl_device_noinline void svm_node_attr(KernelGlobals kg,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (sd->type == PRIMITIVE_LAMP && node.y == ATTR_STD_UV) {
|
||||
stack_store_float3(stack, out_offset, make_float3(1.0f - sd->u - sd->v, sd->u, 0.0f));
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
|
||||
/* No generated attribute, fall back to object coordinates. */
|
||||
float3 f = sd->P;
|
||||
|
|
|
@ -25,7 +25,7 @@ ccl_device_noinline void svm_node_vector_transform(KernelGlobals kg,
|
|||
NodeVectorTransformConvertSpace to = (NodeVectorTransformConvertSpace)ito;
|
||||
|
||||
Transform tfm;
|
||||
bool is_object = (sd->object != OBJECT_NONE);
|
||||
bool is_object = (sd->object != OBJECT_NONE) || (sd->type == PRIMITIVE_LAMP);
|
||||
bool is_normal = (type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL);
|
||||
bool is_direction = (type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
|
|||
* \param height: The height the window.
|
||||
* \param state: The state of the window when opened.
|
||||
* \param is_dialog: Stay on top of parent window, no icon in taskbar, can't be minimized.
|
||||
* \param glSettings: Misc OpenGL options.
|
||||
* \param gpuSettings: Misc GPU options.
|
||||
* \return A handle to the new window ( == NULL if creation failed).
|
||||
*/
|
||||
extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
||||
|
@ -174,17 +174,17 @@ extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
|||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
bool is_dialog,
|
||||
GHOST_GLSettings glSettings);
|
||||
GHOST_GPUSettings gpuSettings);
|
||||
|
||||
/**
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \param systemhandle: The handle to the system.
|
||||
* \param glSettings: Misc OpenGL options.
|
||||
* \param gpuSettings: Misc GPU options.
|
||||
* \return A handle to the new context ( == NULL if creation failed).
|
||||
*/
|
||||
extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle,
|
||||
GHOST_GLSettings glSettings);
|
||||
extern GHOST_ContextHandle GHOST_CreateGPUContext(GHOST_SystemHandle systemhandle,
|
||||
GHOST_GPUSettings gpuSettings);
|
||||
|
||||
/**
|
||||
* Dispose of a context.
|
||||
|
@ -192,8 +192,8 @@ extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemha
|
|||
* \param contexthandle: Handle to the context to be disposed.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
extern GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
|
||||
GHOST_ContextHandle contexthandle);
|
||||
extern GHOST_TSuccess GHOST_DisposeGPUContext(GHOST_SystemHandle systemhandle,
|
||||
GHOST_ContextHandle contexthandle);
|
||||
|
||||
/**
|
||||
* Returns the window user data.
|
||||
|
@ -730,24 +730,24 @@ extern GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle);
|
|||
* \param contexthandle: The handle to the context.
|
||||
* \return A success indicator.
|
||||
*/
|
||||
extern GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle);
|
||||
extern GHOST_TSuccess GHOST_ActivateGPUContext(GHOST_ContextHandle contexthandle);
|
||||
|
||||
/**
|
||||
* Release the drawing context bound to this thread.
|
||||
* \param contexthandle: The handle to the context.
|
||||
* \return A success indicator.
|
||||
*/
|
||||
extern GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle);
|
||||
extern GHOST_TSuccess GHOST_ReleaseGPUContext(GHOST_ContextHandle contexthandle);
|
||||
|
||||
/**
|
||||
* Get the OpenGL frame-buffer handle that serves as a default frame-buffer.
|
||||
* Get the GPU frame-buffer handle that serves as a default frame-buffer.
|
||||
*/
|
||||
extern unsigned int GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contexthandle);
|
||||
extern unsigned int GHOST_GetContextDefaultGPUFramebuffer(GHOST_ContextHandle contexthandle);
|
||||
|
||||
/**
|
||||
* Get the OpenGL frame-buffer handle that serves as a default frame-buffer.
|
||||
* Get the GPU frame-buffer handle that serves as a default frame-buffer.
|
||||
*/
|
||||
extern unsigned int GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle);
|
||||
extern unsigned int GHOST_GetDefaultGPUFramebuffer(GHOST_WindowHandle windowhandle);
|
||||
|
||||
/**
|
||||
* Use multi-touch gestures if supported.
|
||||
|
@ -1072,7 +1072,7 @@ int GHOST_XrSessionIsRunning(const GHOST_XrContextHandle xr_context);
|
|||
|
||||
/**
|
||||
* Check if \a xr_context has a session that requires an upside-down frame-buffer (compared to
|
||||
* OpenGL). If true, the render result should be flipped vertically for correct output.
|
||||
* GPU). If true, the render result should be flipped vertically for correct output.
|
||||
* \note Only to be called after session start, may otherwise result in a false negative.
|
||||
*/
|
||||
int GHOST_XrSessionNeedsUpsideDownDrawing(const GHOST_XrContextHandle xr_context);
|
||||
|
|
|
@ -230,7 +230,7 @@ class GHOST_ISystem {
|
|||
* \param width: The width the window.
|
||||
* \param height: The height the window.
|
||||
* \param state: The state of the window when opened.
|
||||
* \param glSettings: Misc OpenGL settings.
|
||||
* \param gpuSettings: Misc GPU settings.
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
* \param is_dialog: Stay on top of parent window, no icon in taskbar, can't be minimized.
|
||||
* \param parentWindow: Parent (embedder) window
|
||||
|
@ -242,7 +242,7 @@ class GHOST_ISystem {
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool exclusive = false,
|
||||
const bool is_dialog = false,
|
||||
const GHOST_IWindow *parentWindow = NULL) = 0;
|
||||
|
@ -259,7 +259,7 @@ class GHOST_ISystem {
|
|||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0;
|
||||
virtual GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) = 0;
|
||||
|
||||
/**
|
||||
* Dispose of a context.
|
||||
|
|
|
@ -64,9 +64,9 @@ typedef struct {
|
|||
} GHOST_CursorBitmapRef;
|
||||
|
||||
typedef enum {
|
||||
GHOST_glStereoVisual = (1 << 0),
|
||||
GHOST_glDebugContext = (1 << 1),
|
||||
} GHOST_GLFlags;
|
||||
GHOST_gpuStereoVisual = (1 << 0),
|
||||
GHOST_gpuDebugContext = (1 << 1),
|
||||
} GHOST_GPUFlags;
|
||||
|
||||
typedef enum GHOST_DialogOptions {
|
||||
GHOST_DialogWarning = (1 << 0),
|
||||
|
@ -170,14 +170,15 @@ typedef enum {
|
|||
GHOST_kModifierKeyNum
|
||||
} GHOST_TModifierKey;
|
||||
|
||||
/**
|
||||
* \note these values are stored in #wmWindow::windowstate,
|
||||
* don't change, only add new values.
|
||||
*/
|
||||
typedef enum {
|
||||
GHOST_kWindowStateNormal = 0,
|
||||
GHOST_kWindowStateMaximized,
|
||||
GHOST_kWindowStateMinimized,
|
||||
GHOST_kWindowStateFullScreen,
|
||||
GHOST_kWindowStateEmbedded,
|
||||
// GHOST_kWindowStateModified,
|
||||
// GHOST_kWindowStateUnModified,
|
||||
GHOST_kWindowStateMaximized = 1,
|
||||
GHOST_kWindowStateMinimized = 2,
|
||||
GHOST_kWindowStateFullScreen = 3,
|
||||
} GHOST_TWindowState;
|
||||
|
||||
typedef enum {
|
||||
|
@ -680,7 +681,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
int flags;
|
||||
GHOST_TDrawingContextType context_type;
|
||||
} GHOST_GLSettings;
|
||||
} GHOST_GPUSettings;
|
||||
|
||||
typedef enum {
|
||||
/** Axis that cursor grab will wrap. */
|
||||
|
|
|
@ -135,16 +135,16 @@ void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
|
|||
system->getAllDisplayDimensions(*width, *height);
|
||||
}
|
||||
|
||||
GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle,
|
||||
GHOST_GLSettings glSettings)
|
||||
GHOST_ContextHandle GHOST_CreateGPUContext(GHOST_SystemHandle systemhandle,
|
||||
GHOST_GPUSettings gpuSettings)
|
||||
{
|
||||
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
|
||||
|
||||
return (GHOST_ContextHandle)system->createOffscreenContext(glSettings);
|
||||
return (GHOST_ContextHandle)system->createOffscreenContext(gpuSettings);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
|
||||
GHOST_ContextHandle contexthandle)
|
||||
GHOST_TSuccess GHOST_DisposeGPUContext(GHOST_SystemHandle systemhandle,
|
||||
GHOST_ContextHandle contexthandle)
|
||||
{
|
||||
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
|
||||
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
|
||||
|
@ -161,7 +161,7 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
|||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
bool is_dialog,
|
||||
GHOST_GLSettings glSettings)
|
||||
GHOST_GPUSettings gpuSettings)
|
||||
{
|
||||
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
|
||||
|
||||
|
@ -171,7 +171,7 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
|||
width,
|
||||
height,
|
||||
state,
|
||||
glSettings,
|
||||
gpuSettings,
|
||||
false,
|
||||
is_dialog,
|
||||
(GHOST_IWindow *)parent_windowhandle);
|
||||
|
@ -716,7 +716,7 @@ GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandl
|
|||
return window->activateDrawingContext();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle)
|
||||
GHOST_TSuccess GHOST_ActivateGPUContext(GHOST_ContextHandle contexthandle)
|
||||
{
|
||||
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
|
||||
if (context) {
|
||||
|
@ -726,21 +726,21 @@ GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle)
|
|||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle)
|
||||
GHOST_TSuccess GHOST_ReleaseGPUContext(GHOST_ContextHandle contexthandle)
|
||||
{
|
||||
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
|
||||
|
||||
return context->releaseDrawingContext();
|
||||
}
|
||||
|
||||
uint GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contexthandle)
|
||||
uint GHOST_GetContextDefaultGPUFramebuffer(GHOST_ContextHandle contexthandle)
|
||||
{
|
||||
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
|
||||
|
||||
return context->getDefaultFramebuffer();
|
||||
}
|
||||
|
||||
uint GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle)
|
||||
uint GHOST_GetDefaultGPUFramebuffer(GHOST_WindowHandle windowhandle)
|
||||
{
|
||||
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
|
||||
|
||||
|
|
|
@ -397,12 +397,12 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window,
|
|||
const GHOST_DisplaySetting &settings,
|
||||
const bool stereoVisual)
|
||||
{
|
||||
GHOST_GLSettings glSettings = {0};
|
||||
GHOST_GPUSettings gpuSettings = {0};
|
||||
|
||||
if (stereoVisual) {
|
||||
glSettings.flags |= GHOST_glStereoVisual;
|
||||
gpuSettings.flags |= GHOST_gpuStereoVisual;
|
||||
}
|
||||
glSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
|
||||
gpuSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
|
||||
/* NOTE: don't use #getCurrentDisplaySetting() because on X11 we may
|
||||
* be zoomed in and the desktop may be bigger than the viewport. */
|
||||
GHOST_ASSERT(m_displayManager,
|
||||
|
@ -414,7 +414,7 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window,
|
|||
settings.xPixels,
|
||||
settings.yPixels,
|
||||
GHOST_kWindowStateNormal,
|
||||
glSettings,
|
||||
gpuSettings,
|
||||
true /* exclusive */);
|
||||
return (*window == nullptr) ? GHOST_kFailure : GHOST_kSuccess;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ class GHOST_System : public GHOST_ISystem {
|
|||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0;
|
||||
virtual GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) = 0;
|
||||
|
||||
/**
|
||||
* Returns whether a window is valid.
|
||||
|
|
|
@ -77,7 +77,7 @@ class GHOST_SystemCocoa : public GHOST_System {
|
|||
* \param width: The width the window.
|
||||
* \param height: The height the window.
|
||||
* \param state: The state of the window when opened.
|
||||
* \param glSettings: Misc OpenGL settings.
|
||||
* \param gpuSettings: Misc GPU settings.
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
* \param parentWindow: Parent (embedder) window.
|
||||
* \return The new window (or 0 if creation failed).
|
||||
|
@ -88,7 +88,7 @@ class GHOST_SystemCocoa : public GHOST_System {
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool exclusive = false,
|
||||
const bool is_dialog = false,
|
||||
const GHOST_IWindow *parentWindow = NULL);
|
||||
|
@ -98,7 +98,7 @@ class GHOST_SystemCocoa : public GHOST_System {
|
|||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings);
|
||||
|
||||
/**
|
||||
* Dispose of a context.
|
||||
|
|
|
@ -696,7 +696,7 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool exclusive,
|
||||
const bool is_dialog,
|
||||
const GHOST_IWindow *parentWindow)
|
||||
|
@ -725,9 +725,9 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
|
|||
width,
|
||||
height,
|
||||
state,
|
||||
glSettings.context_type,
|
||||
glSettings.flags & GHOST_glStereoVisual,
|
||||
glSettings.flags & GHOST_glDebugContext,
|
||||
gpuSettings.context_type,
|
||||
gpuSettings.flags & GHOST_gpuStereoVisual,
|
||||
gpuSettings.flags & GHOST_gpuDebugContext,
|
||||
is_dialog,
|
||||
(GHOST_WindowCocoa *)parentWindow);
|
||||
|
||||
|
@ -755,11 +755,11 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
|
|||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GPUSettings gpuSettings)
|
||||
{
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
if (glSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
|
||||
if (gpuSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
|
||||
GHOST_Context *context = new GHOST_ContextVK(false, NULL, 1, 2, debug_context);
|
||||
if (!context->initializeDrawingContext()) {
|
||||
delete context;
|
||||
|
@ -769,7 +769,7 @@ GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GLSettings glSet
|
|||
}
|
||||
#endif
|
||||
|
||||
GHOST_Context *context = new GHOST_ContextCGL(false, NULL, NULL, NULL, glSettings.context_type);
|
||||
GHOST_Context *context = new GHOST_ContextCGL(false, NULL, NULL, NULL, gpuSettings.context_type);
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
|
|
|
@ -79,7 +79,7 @@ class GHOST_SystemHeadless : public GHOST_System {
|
|||
void getAllDisplayDimensions(uint32_t & /*width*/, uint32_t & /*height*/) const override
|
||||
{ /* nop */
|
||||
}
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings /*glSettings*/) override
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings /*gpuSettings*/) override
|
||||
{
|
||||
#ifdef __linux__
|
||||
GHOST_Context *context;
|
||||
|
@ -150,7 +150,7 @@ class GHOST_SystemHeadless : public GHOST_System {
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool /*exclusive*/,
|
||||
const bool /*is_dialog*/,
|
||||
const GHOST_IWindow *parentWindow) override
|
||||
|
@ -162,8 +162,8 @@ class GHOST_SystemHeadless : public GHOST_System {
|
|||
height,
|
||||
state,
|
||||
parentWindow,
|
||||
glSettings.context_type,
|
||||
((glSettings.flags & GHOST_glStereoVisual) != 0));
|
||||
gpuSettings.context_type,
|
||||
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0));
|
||||
}
|
||||
|
||||
GHOST_IWindow *getWindowUnderCursor(int32_t /*x*/, int32_t /*y*/) override
|
||||
|
|
|
@ -42,7 +42,7 @@ GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title,
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool exclusive,
|
||||
const bool /* is_dialog */,
|
||||
const GHOST_IWindow *parentWindow)
|
||||
|
@ -56,8 +56,8 @@ GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title,
|
|||
width,
|
||||
height,
|
||||
state,
|
||||
glSettings.context_type,
|
||||
((glSettings.flags & GHOST_glStereoVisual) != 0),
|
||||
gpuSettings.context_type,
|
||||
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
|
||||
exclusive,
|
||||
parentWindow);
|
||||
|
||||
|
@ -125,7 +125,7 @@ uint8_t GHOST_SystemSDL::getNumDisplays() const
|
|||
return SDL_GetNumVideoDisplays();
|
||||
}
|
||||
|
||||
GHOST_IContext *GHOST_SystemSDL::createOffscreenContext(GHOST_GLSettings /*glSettings*/)
|
||||
GHOST_IContext *GHOST_SystemSDL::createOffscreenContext(GHOST_GPUSettings /*gpuSettings*/)
|
||||
{
|
||||
GHOST_Context *context = new GHOST_ContextSDL(false,
|
||||
nullptr,
|
||||
|
|
|
@ -60,7 +60,7 @@ class GHOST_SystemSDL : public GHOST_System {
|
|||
|
||||
void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const override;
|
||||
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) override;
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) override;
|
||||
|
||||
GHOST_TSuccess disposeContext(GHOST_IContext *context) override;
|
||||
|
||||
|
@ -73,7 +73,7 @@ class GHOST_SystemSDL : public GHOST_System {
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool exclusive = false,
|
||||
const bool is_dialog = false,
|
||||
const GHOST_IWindow *parentWindow = nullptr) override;
|
||||
|
|
|
@ -6279,7 +6279,7 @@ static GHOST_Context *createOffscreenContext_impl(GHOST_SystemWayland *system,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GPUSettings gpuSettings)
|
||||
{
|
||||
#ifdef USE_EVENT_BACKGROUND_THREAD
|
||||
std::lock_guard lock_server_guard{*server_mutex};
|
||||
|
@ -6289,9 +6289,9 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings glS
|
|||
wl_surface *wl_surface = wl_compositor_create_surface(wl_compositor());
|
||||
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
|
||||
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
|
||||
|
||||
if (glSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
if (gpuSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
GHOST_Context *context = new GHOST_ContextVK(false,
|
||||
GHOST_kVulkanPlatformWayland,
|
||||
0,
|
||||
|
@ -6310,7 +6310,7 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings glS
|
|||
return context;
|
||||
}
|
||||
#else
|
||||
(void)glSettings;
|
||||
(void)gpuSettings;
|
||||
#endif
|
||||
|
||||
wl_egl_window *egl_window = wl_surface ? wl_egl_window_create(wl_surface, 1, 1) : nullptr;
|
||||
|
@ -6359,7 +6359,7 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
|
|||
const uint32_t width,
|
||||
const uint32_t height,
|
||||
const GHOST_TWindowState state,
|
||||
const GHOST_GLSettings glSettings,
|
||||
const GHOST_GPUSettings gpuSettings,
|
||||
const bool exclusive,
|
||||
const bool is_dialog,
|
||||
const GHOST_IWindow *parentWindow)
|
||||
|
@ -6374,9 +6374,9 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
|
|||
height,
|
||||
state,
|
||||
parentWindow,
|
||||
glSettings.context_type,
|
||||
gpuSettings.context_type,
|
||||
is_dialog,
|
||||
((glSettings.flags & GHOST_glStereoVisual) != 0),
|
||||
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
|
||||
exclusive);
|
||||
|
||||
if (window) {
|
||||
|
|
|
@ -157,7 +157,7 @@ class GHOST_SystemWayland : public GHOST_System {
|
|||
|
||||
void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const override;
|
||||
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) override;
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) override;
|
||||
|
||||
GHOST_TSuccess disposeContext(GHOST_IContext *context) override;
|
||||
|
||||
|
@ -167,7 +167,7 @@ class GHOST_SystemWayland : public GHOST_System {
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool exclusive,
|
||||
const bool is_dialog,
|
||||
const GHOST_IWindow *parentWindow) override;
|
||||
|
|
|
@ -224,7 +224,7 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool /*exclusive*/,
|
||||
const bool is_dialog,
|
||||
const GHOST_IWindow *parentWindow)
|
||||
|
@ -237,11 +237,11 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
|
|||
width,
|
||||
height,
|
||||
state,
|
||||
glSettings.context_type,
|
||||
((glSettings.flags & GHOST_glStereoVisual) != 0),
|
||||
gpuSettings.context_type,
|
||||
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
|
||||
false,
|
||||
(GHOST_WindowWin32 *)parentWindow,
|
||||
((glSettings.flags & GHOST_glDebugContext) != 0),
|
||||
((gpuSettings.flags & GHOST_gpuDebugContext) != 0),
|
||||
is_dialog);
|
||||
|
||||
if (window->getValid()) {
|
||||
|
@ -263,15 +263,15 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
|
|||
* Never explicitly delete the window, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GPUSettings gpuSettings)
|
||||
{
|
||||
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
|
||||
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
|
||||
|
||||
GHOST_Context *context = nullptr;
|
||||
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
/* Vulkan does not need a window. */
|
||||
if (glSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
if (gpuSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
context = new GHOST_ContextVK(false, (HWND)0, 1, 2, debug_context);
|
||||
|
||||
if (!context->initializeDrawingContext()) {
|
||||
|
|
|
@ -103,7 +103,7 @@ class GHOST_SystemWin32 : public GHOST_System {
|
|||
* \param width: The width the window.
|
||||
* \param height: The height the window.
|
||||
* \param state: The state of the window when opened.
|
||||
* \param glSettings: Misc OpenGL settings.
|
||||
* \param gpuSettings: Misc GPU settings.
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
* \param parentWindow: Parent window.
|
||||
* \return The new window (or 0 if creation failed).
|
||||
|
@ -114,7 +114,7 @@ class GHOST_SystemWin32 : public GHOST_System {
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool exclusive = false,
|
||||
const bool is_dialog = false,
|
||||
const GHOST_IWindow *parentWindow = 0);
|
||||
|
@ -124,7 +124,7 @@ class GHOST_SystemWin32 : public GHOST_System {
|
|||
* Never explicitly delete the window, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings);
|
||||
|
||||
/**
|
||||
* Dispose of a context.
|
||||
|
|
|
@ -304,7 +304,7 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool exclusive,
|
||||
const bool is_dialog,
|
||||
const GHOST_IWindow *parentWindow)
|
||||
|
@ -324,11 +324,11 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
|
|||
height,
|
||||
state,
|
||||
(GHOST_WindowX11 *)parentWindow,
|
||||
glSettings.context_type,
|
||||
gpuSettings.context_type,
|
||||
is_dialog,
|
||||
((glSettings.flags & GHOST_glStereoVisual) != 0),
|
||||
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
|
||||
exclusive,
|
||||
(glSettings.flags & GHOST_glDebugContext) != 0);
|
||||
(gpuSettings.flags & GHOST_gpuDebugContext) != 0);
|
||||
|
||||
if (window) {
|
||||
/* Both are now handle in GHOST_WindowX11.cc
|
||||
|
@ -399,7 +399,7 @@ static GHOST_Context *create_glx_context(Display *display,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GPUSettings gpuSettings)
|
||||
{
|
||||
/* During development:
|
||||
* try 4.x compatibility profile
|
||||
|
@ -411,11 +411,11 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti
|
|||
* try 3.3 core profile
|
||||
* no fall-backs. */
|
||||
|
||||
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
|
||||
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
|
||||
GHOST_Context *context = nullptr;
|
||||
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
if (glSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
if (gpuSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
context = new GHOST_ContextVK(
|
||||
false, GHOST_kVulkanPlatformX11, 0, m_display, NULL, NULL, 1, 2, debug_context);
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ class GHOST_SystemX11 : public GHOST_System {
|
|||
uint32_t width,
|
||||
uint32_t height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_GLSettings glSettings,
|
||||
GHOST_GPUSettings gpuSettings,
|
||||
const bool exclusive = false,
|
||||
const bool is_dialog = false,
|
||||
const GHOST_IWindow *parentWindow = nullptr) override;
|
||||
|
@ -134,7 +134,7 @@ class GHOST_SystemX11 : public GHOST_System {
|
|||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) override;
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) override;
|
||||
|
||||
/**
|
||||
* Dispose of a context.
|
||||
|
|
|
@ -332,9 +332,6 @@ static bool gwl_window_state_set_for_libdecor(libdecor_frame *frame,
|
|||
libdecor_frame_set_fullscreen(frame, nullptr);
|
||||
break;
|
||||
}
|
||||
case GHOST_kWindowStateEmbedded: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -377,9 +374,6 @@ static bool gwl_window_state_set_for_xdg(xdg_toplevel *toplevel,
|
|||
xdg_toplevel_set_fullscreen(toplevel, nullptr);
|
||||
break;
|
||||
}
|
||||
case GHOST_kWindowStateEmbedded: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -412,7 +412,7 @@ bool processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GHOST_GLSettings glSettings = {0};
|
||||
GHOST_GPUSettings gpuSettings = {0};
|
||||
char *title1 = "gears - main window";
|
||||
char *title2 = "gears - secondary window";
|
||||
GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL);
|
||||
|
@ -433,7 +433,7 @@ int main(int argc, char **argv)
|
|||
GHOST_kWindowStateNormal,
|
||||
false,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
glSettings);
|
||||
gpuSettings);
|
||||
if (!sMainWindow) {
|
||||
printf("could not create main window\n");
|
||||
exit(-1);
|
||||
|
@ -450,7 +450,7 @@ int main(int argc, char **argv)
|
|||
GHOST_kWindowStateNormal,
|
||||
false,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
glSettings);
|
||||
gpuSettings);
|
||||
if (!sSecondaryWindow) {
|
||||
printf("could not create secondary window\n");
|
||||
exit(-1);
|
||||
|
|
|
@ -406,13 +406,13 @@ Application::Application(GHOST_ISystem *system)
|
|||
m_exitRequested(false),
|
||||
stereo(false)
|
||||
{
|
||||
GHOST_GLSettings glSettings = {0};
|
||||
glSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
|
||||
GHOST_GPUSettings gpuSettings = {0};
|
||||
gpuSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
|
||||
fApp = this;
|
||||
|
||||
// Create the main window
|
||||
m_mainWindow = system->createWindow(
|
||||
"gears - main window", 10, 64, 320, 200, GHOST_kWindowStateNormal, glSettings);
|
||||
"gears - main window", 10, 64, 320, 200, GHOST_kWindowStateNormal, gpuSettings);
|
||||
|
||||
if (!m_mainWindow) {
|
||||
std::cout << "could not create main window\n";
|
||||
|
@ -421,7 +421,7 @@ Application::Application(GHOST_ISystem *system)
|
|||
|
||||
// Create a secondary window
|
||||
m_secondaryWindow = system->createWindow(
|
||||
"gears - secondary window", 340, 64, 320, 200, GHOST_kWindowStateNormal, glSettings);
|
||||
"gears - secondary window", 340, 64, 320, 200, GHOST_kWindowStateNormal, gpuSettings);
|
||||
if (!m_secondaryWindow) {
|
||||
std::cout << "could not create secondary window\n";
|
||||
exit(-1);
|
||||
|
|
|
@ -306,7 +306,7 @@ MainWindow *mainwindow_new(MultiTestApp *app)
|
|||
{
|
||||
GHOST_SystemHandle sys = multitestapp_get_system(app);
|
||||
GHOST_WindowHandle win;
|
||||
GHOST_GLSettings glSettings = {0};
|
||||
GHOST_GPUSettings gpuSettings = {0};
|
||||
|
||||
win = GHOST_CreateWindow(sys,
|
||||
NULL,
|
||||
|
@ -318,7 +318,7 @@ MainWindow *mainwindow_new(MultiTestApp *app)
|
|||
GHOST_kWindowStateNormal,
|
||||
false,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
glSettings);
|
||||
gpuSettings);
|
||||
|
||||
if (win) {
|
||||
MainWindow *mw = MEM_callocN(sizeof(*mw), "mainwindow_new");
|
||||
|
@ -557,7 +557,7 @@ static void loggerwindow_handle(void *priv, GHOST_EventHandle evt)
|
|||
|
||||
LoggerWindow *loggerwindow_new(MultiTestApp *app)
|
||||
{
|
||||
GHOST_GLSettings glSettings = {0};
|
||||
GHOST_GPUSettings gpuSettings = {0};
|
||||
GHOST_SystemHandle sys = multitestapp_get_system(app);
|
||||
uint32_t screensize[2];
|
||||
GHOST_WindowHandle win;
|
||||
|
@ -573,7 +573,7 @@ LoggerWindow *loggerwindow_new(MultiTestApp *app)
|
|||
GHOST_kWindowStateNormal,
|
||||
false,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
glSettings);
|
||||
gpuSettings);
|
||||
|
||||
if (win) {
|
||||
LoggerWindow *lw = MEM_callocN(sizeof(*lw), "loggerwindow_new");
|
||||
|
@ -761,7 +761,7 @@ static void extrawindow_handle(void *priv, GHOST_EventHandle evt)
|
|||
|
||||
ExtraWindow *extrawindow_new(MultiTestApp *app)
|
||||
{
|
||||
GHOST_GLSettings glSettings = {0};
|
||||
GHOST_GPUSettings gpuSettings = {0};
|
||||
GHOST_SystemHandle sys = multitestapp_get_system(app);
|
||||
GHOST_WindowHandle win;
|
||||
|
||||
|
@ -775,7 +775,7 @@ ExtraWindow *extrawindow_new(MultiTestApp *app)
|
|||
GHOST_kWindowStateNormal,
|
||||
false,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
glSettings);
|
||||
gpuSettings);
|
||||
|
||||
if (win) {
|
||||
ExtraWindow *ew = MEM_callocN(sizeof(*ew), "mainwindow_new");
|
||||
|
|
|
@ -350,7 +350,7 @@ def main():
|
|||
if name.rpartition(".")[2].isdigit():
|
||||
continue
|
||||
|
||||
if not ob_eval.data.attributes.active_color:
|
||||
if (not hasattr(ob_eval.data, 'attributes')) or not ob_eval.data.attributes.active_color:
|
||||
print("Skipping:", name, "(no vertex colors)")
|
||||
continue
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ const UserDef U_default = {
|
|||
.sounddir = "//",
|
||||
.i18ndir = "",
|
||||
.image_editor = "",
|
||||
.text_editor = "",
|
||||
.text_editor_args = "",
|
||||
.anim_player = "",
|
||||
.anim_player_preset = 0,
|
||||
.v2d_min_gridsize = 45,
|
||||
|
|
|
@ -80,7 +80,7 @@ def keyconfig_update(keyconfig_data, keyconfig_version):
|
|||
km_items.append(('ROTATE_NORMALS', {"type": 'N', "value": 'PRESS'}, None))
|
||||
break
|
||||
|
||||
if keyconfig_version <= (3, 6, 3):
|
||||
if keyconfig_version <= (4, 0, 3):
|
||||
if not has_copy:
|
||||
keyconfig_data = copy.deepcopy(keyconfig_data)
|
||||
has_copy = True
|
||||
|
|
|
@ -1836,6 +1836,10 @@ def km_graph_editor(params):
|
|||
("graph.delete", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("confirm", False)]}),
|
||||
("graph.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
|
||||
("graph.keyframe_insert", {"type": 'I', "value": 'PRESS'}, None),
|
||||
("graph.keyframe_jump", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True},
|
||||
{"properties": [("next", True)]}),
|
||||
("graph.keyframe_jump", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True},
|
||||
{"properties": [("next", False)]}),
|
||||
("graph.click_insert", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True}, None),
|
||||
("graph.click_insert", {"type": params.action_mouse, "value": 'CLICK', "shift": True, "ctrl": True},
|
||||
{"properties": [("extend", True)]}),
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import bpy
|
||||
|
||||
filepaths = bpy.context.preferences.filepaths
|
||||
|
||||
filepaths.text_editor = ""
|
||||
filepaths.text_editor_args = ""
|
|
@ -0,0 +1,12 @@
|
|||
import bpy
|
||||
import platform
|
||||
|
||||
filepaths = bpy.context.preferences.filepaths
|
||||
|
||||
filepaths.text_editor_args = "-g $filepath:$line:$column"
|
||||
|
||||
match platform.system():
|
||||
case "Windows":
|
||||
filepaths.text_editor = "code.cmd"
|
||||
case _:
|
||||
filepaths.text_editor = "code"
|
|
@ -28,6 +28,7 @@ _modules = [
|
|||
"screen_play_rendered_anim",
|
||||
"sequencer",
|
||||
"spreadsheet",
|
||||
"text",
|
||||
"userpref",
|
||||
"uvcalc_follow_active",
|
||||
"uvcalc_lightmap",
|
||||
|
|
|
@ -413,6 +413,24 @@ class AddPresetHairDynamics(AddPresetBase, Operator):
|
|||
]
|
||||
|
||||
|
||||
class AddPresetTextEditor(AddPresetBase, Operator):
|
||||
"""Add or remove a Text Editor Preset"""
|
||||
bl_idname = "text_editor.preset_add"
|
||||
bl_label = "Add Text Editor Preset"
|
||||
preset_menu = "USERPREF_PT_text_editor_presets"
|
||||
|
||||
preset_defines = [
|
||||
"filepaths = bpy.context.preferences.filepaths"
|
||||
]
|
||||
|
||||
preset_values = [
|
||||
"filepaths.text_editor",
|
||||
"filepaths.text_editor_args"
|
||||
]
|
||||
|
||||
preset_subdir = "text_editor"
|
||||
|
||||
|
||||
class AddPresetTrackingCamera(AddPresetBase, Operator):
|
||||
"""Add or remove a Tracking Camera Intrinsics Preset"""
|
||||
bl_idname = "clip.camera_preset_add"
|
||||
|
@ -692,6 +710,7 @@ classes = (
|
|||
AddPresetOperator,
|
||||
AddPresetRender,
|
||||
AddPresetCameraSafeAreas,
|
||||
AddPresetTextEditor,
|
||||
AddPresetTrackingCamera,
|
||||
AddPresetTrackingSettings,
|
||||
AddPresetTrackingTrackColor,
|
||||
|
|
|
@ -8,7 +8,6 @@ from bpy.app.translations import pgettext_tip as tip_
|
|||
|
||||
|
||||
def guess_player_path(preset):
|
||||
import os
|
||||
import sys
|
||||
|
||||
if preset == 'INTERNAL':
|
||||
|
@ -17,6 +16,7 @@ def guess_player_path(preset):
|
|||
elif preset == 'DJV':
|
||||
player_path = "djv"
|
||||
if sys.platform == "darwin":
|
||||
import os
|
||||
test_path = "/Applications/DJV2.app/Contents/Resources/bin/djv"
|
||||
if os.path.exists(test_path):
|
||||
player_path = test_path
|
||||
|
@ -141,7 +141,15 @@ class PlayRenderedAnim(Operator):
|
|||
opts = [file, "%d-%d" % (scene.frame_start, scene.frame_end)]
|
||||
cmd.extend(opts)
|
||||
elif preset == 'RV':
|
||||
opts = ["-fps", str(rd.fps), "-play", "[ %s ]" % file]
|
||||
opts = ["-fps", str(rd.fps), "-play"]
|
||||
if scene.use_preview_range:
|
||||
opts += [
|
||||
"%s" % file.replace("#", "", file.count('#') - 1),
|
||||
"%d-%d" % (frame_start, frame_end),
|
||||
]
|
||||
else:
|
||||
opts.append(file)
|
||||
|
||||
cmd.extend(opts)
|
||||
elif preset == 'MPLAYER':
|
||||
opts = []
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import bpy
|
||||
from bpy.types import Operator
|
||||
from bpy.props import (
|
||||
IntProperty,
|
||||
StringProperty,
|
||||
)
|
||||
|
||||
|
||||
class TEXT_OT_jump_to_file_at_point(Operator):
|
||||
bl_idname = "text.jump_to_file_at_point"
|
||||
bl_label = "Open Text File at point"
|
||||
bl_description = "Edit text file in external text editor"
|
||||
|
||||
filepath: StringProperty(name="filepath")
|
||||
line: IntProperty(name="line")
|
||||
column: IntProperty(name="column")
|
||||
|
||||
def execute(self, context):
|
||||
import shlex
|
||||
import subprocess
|
||||
from string import Template
|
||||
|
||||
if not self.properties.is_property_set("filepath"):
|
||||
text = getattr(getattr(context, "space_data", None), "text", None)
|
||||
if not text:
|
||||
return {'CANCELLED'}
|
||||
self.filepath = text.filepath
|
||||
self.line = text.current_line_index
|
||||
self.column = text.current_character
|
||||
|
||||
text_editor = context.preferences.filepaths.text_editor
|
||||
text_editor_args = context.preferences.filepaths.text_editor_args
|
||||
|
||||
# Use the internal text editor.
|
||||
if not text_editor:
|
||||
return bpy.ops.text.jump_to_file_at_point_internal(
|
||||
filepath=self.filepath,
|
||||
line=self.line,
|
||||
column=self.column,
|
||||
)
|
||||
|
||||
if not text_editor_args:
|
||||
self.report(
|
||||
{'ERROR_INVALID_INPUT'},
|
||||
"Provide text editor argument format in File Paths/Applications Preferences, "
|
||||
"see input field tool-tip for more information.",
|
||||
)
|
||||
return {'CANCELLED'}
|
||||
|
||||
if "$filepath" not in text_editor_args:
|
||||
self.report({'ERROR_INVALID_INPUT'}, "Text Editor Args Format must contain $filepath")
|
||||
return {'CANCELLED'}
|
||||
|
||||
args = [text_editor]
|
||||
template_vars = {
|
||||
"filepath": self.filepath,
|
||||
"line": self.line + 1,
|
||||
"column": self.column + 1,
|
||||
"line0": self.line,
|
||||
"column0": self.column,
|
||||
}
|
||||
|
||||
try:
|
||||
args.extend([Template(arg).substitute(**template_vars) for arg in shlex.split(text_editor_args)])
|
||||
except Exception as ex:
|
||||
self.report({'ERROR'}, "Exception parsing template: %r" % ex)
|
||||
return {'CANCELLED'}
|
||||
|
||||
try:
|
||||
# With `check=True` if `process.returncode != 0` an exception will be raised.
|
||||
subprocess.run(args, check=True)
|
||||
except Exception as ex:
|
||||
self.report({'ERROR'}, "Exception running external editor: %r" % ex)
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
classes = (
|
||||
TEXT_OT_jump_to_file_at_point,
|
||||
)
|
|
@ -937,7 +937,6 @@ def brush_settings_advanced(layout, context, brush, popover=False):
|
|||
|
||||
col = layout.column(heading="Auto-Masking", align=True)
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(brush, "use_automasking_topology", text="Topology")
|
||||
col.prop(brush, "use_automasking_face_sets", text="Face Sets")
|
||||
|
||||
|
|
|
@ -764,20 +764,26 @@ class NODE_PT_quality(bpy.types.Panel):
|
|||
tree = snode.node_tree
|
||||
prefs = bpy.context.preferences
|
||||
|
||||
use_realtime = False
|
||||
col = layout.column()
|
||||
if prefs.experimental.use_full_frame_compositor:
|
||||
if prefs.experimental.use_experimental_compositors:
|
||||
col.prop(tree, "execution_mode")
|
||||
use_realtime = tree.execution_mode == 'REALTIME'
|
||||
|
||||
col = layout.column()
|
||||
col.active = not use_realtime
|
||||
col.prop(tree, "render_quality", text="Render")
|
||||
col.prop(tree, "edit_quality", text="Edit")
|
||||
col.prop(tree, "chunk_size")
|
||||
|
||||
col = layout.column()
|
||||
col.active = not use_realtime
|
||||
col.prop(tree, "use_opencl")
|
||||
col.prop(tree, "use_groupnode_buffer")
|
||||
col.prop(tree, "use_two_pass")
|
||||
col.prop(tree, "use_viewer_border")
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.prop(snode, "use_auto_render")
|
||||
|
||||
|
||||
|
|
|
@ -256,7 +256,13 @@ class TEXT_MT_text(Menu):
|
|||
|
||||
if text:
|
||||
layout.separator()
|
||||
layout.operator("text.reload")
|
||||
row = layout.row()
|
||||
row.operator("text.reload")
|
||||
row.enabled = not text.is_in_memory
|
||||
|
||||
row = layout.row()
|
||||
op = row.operator("text.jump_to_file_at_point", text="Edit Externally")
|
||||
row.enabled = (not text.is_in_memory and context.preferences.filepaths.text_editor != "")
|
||||
|
||||
layout.separator()
|
||||
layout.operator("text.save", icon='FILE_TICK')
|
||||
|
|
|
@ -25,7 +25,7 @@ if "_icon_cache" in locals():
|
|||
del release
|
||||
|
||||
|
||||
# (filename -> icon_value) map
|
||||
# (icon_name -> icon_value) map
|
||||
_icon_cache = {}
|
||||
|
||||
|
||||
|
@ -236,14 +236,14 @@ class ToolSelectPanelHelper:
|
|||
icon_value = _icon_cache.get(icon_name)
|
||||
if icon_value is None:
|
||||
dirname = bpy.utils.system_resource('DATAFILES', path="icons")
|
||||
filename = os.path.join(dirname, icon_name + ".dat")
|
||||
filepath = os.path.join(dirname, icon_name + ".dat")
|
||||
try:
|
||||
icon_value = bpy.app.icons.new_triangles_from_file(filename)
|
||||
icon_value = bpy.app.icons.new_triangles_from_file(filepath)
|
||||
except Exception as ex:
|
||||
if not os.path.exists(filename):
|
||||
print("Missing icons:", filename, ex)
|
||||
if not os.path.exists(filepath):
|
||||
print("Missing icons:", filepath, ex)
|
||||
else:
|
||||
print("Corrupt icon:", filename, ex)
|
||||
print("Corrupt icon:", filepath, ex)
|
||||
# Use none as a fallback (avoids layout issues).
|
||||
if icon_name != "none":
|
||||
icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle("none")
|
||||
|
|
|
@ -3111,7 +3111,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
|
|||
*_tools_annotate,
|
||||
],
|
||||
'EDIT_GPENCIL': [
|
||||
*_tools_gpencil_select,
|
||||
*_tools_select,
|
||||
_defs_view3d_generic.cursor,
|
||||
None,
|
||||
*_tools_transform,
|
||||
|
|
|
@ -10,6 +10,7 @@ from bpy.app.translations import (
|
|||
pgettext_iface as iface_,
|
||||
pgettext_tip as tip_,
|
||||
)
|
||||
from bl_ui.utils import PresetPanel
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
@ -1399,6 +1400,13 @@ class USERPREF_PT_file_paths_render(FilePathsPanel, Panel):
|
|||
col.prop(paths, "render_cache_directory", text="Render Cache")
|
||||
|
||||
|
||||
class USERPREF_PT_text_editor_presets(PresetPanel, Panel):
|
||||
bl_label = "Text Editor Presets"
|
||||
preset_subdir = "text_editor"
|
||||
preset_operator = "script.execute_preset"
|
||||
preset_add_operator = "text_editor.preset_add"
|
||||
|
||||
|
||||
class USERPREF_PT_file_paths_applications(FilePathsPanel, Panel):
|
||||
bl_label = "Applications"
|
||||
|
||||
|
@ -1416,6 +1424,25 @@ class USERPREF_PT_file_paths_applications(FilePathsPanel, Panel):
|
|||
col.prop(paths, "animation_player", text="Player")
|
||||
|
||||
|
||||
class USERPREF_PT_text_editor(FilePathsPanel, Panel):
|
||||
bl_label = "Text Editor"
|
||||
bl_parent_id = "USERPREF_PT_file_paths_applications"
|
||||
|
||||
def draw_header_preset(self, _context):
|
||||
USERPREF_PT_text_editor_presets.draw_panel_header(self.layout)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
paths = context.preferences.filepaths
|
||||
|
||||
col = layout.column()
|
||||
col.prop(paths, "text_editor", text="Program")
|
||||
col.prop(paths, "text_editor_args", text="Arguments")
|
||||
|
||||
|
||||
class USERPREF_PT_file_paths_development(FilePathsPanel, Panel):
|
||||
bl_label = "Development"
|
||||
|
||||
|
@ -2396,7 +2423,7 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):
|
|||
({"property": "use_new_curves_tools"}, ("blender/blender/issues/68981", "#68981")),
|
||||
({"property": "use_new_point_cloud_type"}, ("blender/blender/issues/75717", "#75717")),
|
||||
({"property": "use_sculpt_texture_paint"}, ("blender/blender/issues/96225", "#96225")),
|
||||
({"property": "use_full_frame_compositor"}, ("blender/blender/issues/88150", "#88150")),
|
||||
({"property": "use_experimental_compositors"}, ("blender/blender/issues/88150", "#88150")),
|
||||
({"property": "enable_eevee_next"}, ("blender/blender/issues/93220", "#93220")),
|
||||
({"property": "enable_workbench_next"}, ("blender/blender/issues/101619", "#101619")),
|
||||
({"property": "use_grease_pencil_version3"}, ("blender/blender/projects/40", "Grease Pencil 3.0")),
|
||||
|
@ -2510,6 +2537,8 @@ classes = (
|
|||
USERPREF_PT_file_paths_script_directories,
|
||||
USERPREF_PT_file_paths_render,
|
||||
USERPREF_PT_file_paths_applications,
|
||||
USERPREF_PT_text_editor,
|
||||
USERPREF_PT_text_editor_presets,
|
||||
USERPREF_PT_file_paths_development,
|
||||
USERPREF_PT_file_paths_asset_libraries,
|
||||
|
||||
|
|
|
@ -945,11 +945,11 @@ class VIEW3D_MT_editor_menus(Menu):
|
|||
tool_settings.use_gpencil_select_mask_stroke or
|
||||
tool_settings.use_gpencil_select_mask_segment)
|
||||
):
|
||||
layout.menu("VIEW3D_MT_select_gpencil")
|
||||
layout.menu("VIEW3D_MT_select_edit_gpencil")
|
||||
elif mode_string == 'EDIT_GPENCIL':
|
||||
layout.menu("VIEW3D_MT_select_gpencil")
|
||||
layout.menu("VIEW3D_MT_select_edit_gpencil")
|
||||
elif mode_string == 'VERTEX_GPENCIL':
|
||||
layout.menu("VIEW3D_MT_select_gpencil")
|
||||
layout.menu("VIEW3D_MT_select_edit_gpencil")
|
||||
elif mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}:
|
||||
mesh = obj.data
|
||||
if mesh.use_paint_mask:
|
||||
|
@ -2028,7 +2028,7 @@ class VIEW3D_MT_select_edit_gpencil(Menu):
|
|||
layout.operator("grease_pencil.select_all", text="None").action = 'DESELECT'
|
||||
layout.operator("grease_pencil.select_all", text="Invert").action = 'INVERT'
|
||||
|
||||
layout.separator()
|
||||
layout.separator()
|
||||
|
||||
|
||||
class VIEW3D_MT_select_paint_mask(Menu):
|
||||
|
@ -7067,72 +7067,70 @@ class VIEW3D_PT_snapping(Panel):
|
|||
|
||||
def draw(self, context):
|
||||
tool_settings = context.tool_settings
|
||||
snap_elements = tool_settings.snap_elements
|
||||
obj = context.active_object
|
||||
object_mode = 'OBJECT' if obj is None else obj.mode
|
||||
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
|
||||
col.label(text="Snap With")
|
||||
row = col.row(align=True)
|
||||
row.prop(tool_settings, "snap_target", expand=True)
|
||||
|
||||
col.label(text="Snap To")
|
||||
col.prop(tool_settings, "snap_elements", expand=True)
|
||||
col.prop(tool_settings, "snap_elements_base", expand=True)
|
||||
|
||||
col.label(text="Snap Individual Elements To")
|
||||
col.prop(tool_settings, "snap_elements_individual", expand=True)
|
||||
|
||||
col.separator()
|
||||
if 'INCREMENT' in snap_elements:
|
||||
|
||||
if 'INCREMENT' in tool_settings.snap_elements:
|
||||
col.prop(tool_settings, "use_snap_grid_absolute")
|
||||
|
||||
if snap_elements != {'INCREMENT'}:
|
||||
if snap_elements != {'FACE_NEAREST'}:
|
||||
col.label(text="Snap With")
|
||||
row = col.row(align=True)
|
||||
row.prop(tool_settings, "snap_target", expand=True)
|
||||
if 'VOLUME' in tool_settings.snap_elements:
|
||||
col.prop(tool_settings, "use_snap_peel_object")
|
||||
|
||||
if obj:
|
||||
col.label(text="Target Selection")
|
||||
col_targetsel = col.column(align=True)
|
||||
if object_mode == 'EDIT' and obj.type not in {'LATTICE', 'META', 'FONT'}:
|
||||
col_targetsel.prop(
|
||||
tool_settings,
|
||||
"use_snap_self",
|
||||
text="Include Active",
|
||||
icon='EDITMODE_HLT',
|
||||
)
|
||||
col_targetsel.prop(
|
||||
tool_settings,
|
||||
"use_snap_edit",
|
||||
text="Include Edited",
|
||||
icon='OUTLINER_DATA_MESH',
|
||||
)
|
||||
col_targetsel.prop(
|
||||
tool_settings,
|
||||
"use_snap_nonedit",
|
||||
text="Include Non-Edited",
|
||||
icon='OUTLINER_OB_MESH',
|
||||
)
|
||||
if 'FACE_NEAREST' in tool_settings.snap_elements:
|
||||
col.prop(tool_settings, "use_snap_to_same_target")
|
||||
if object_mode == 'EDIT':
|
||||
col.prop(tool_settings, "snap_face_nearest_steps")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.prop(tool_settings, "use_snap_align_rotation")
|
||||
col.prop(tool_settings, "use_snap_backface_culling")
|
||||
|
||||
col.separator()
|
||||
|
||||
if obj:
|
||||
col.label(text="Target Selection")
|
||||
col_targetsel = col.column(align=True)
|
||||
if object_mode == 'EDIT' and obj.type not in {'LATTICE', 'META', 'FONT'}:
|
||||
col_targetsel.prop(
|
||||
tool_settings,
|
||||
"use_snap_selectable",
|
||||
text="Exclude Non-Selectable",
|
||||
icon='RESTRICT_SELECT_OFF',
|
||||
"use_snap_self",
|
||||
text="Include Active",
|
||||
icon='EDITMODE_HLT',
|
||||
)
|
||||
|
||||
if object_mode in {'OBJECT', 'POSE', 'EDIT', 'WEIGHT_PAINT'}:
|
||||
col.prop(tool_settings, "use_snap_align_rotation")
|
||||
|
||||
col.prop(tool_settings, "use_snap_backface_culling")
|
||||
|
||||
is_face_nearest_enabled = 'FACE_NEAREST' in snap_elements
|
||||
if is_face_nearest_enabled or 'FACE' in snap_elements:
|
||||
sub = col.column()
|
||||
sub.active = not is_face_nearest_enabled
|
||||
sub.prop(tool_settings, "use_snap_project")
|
||||
|
||||
if is_face_nearest_enabled:
|
||||
col.prop(tool_settings, "use_snap_to_same_target")
|
||||
if object_mode == 'EDIT':
|
||||
col.prop(tool_settings, "snap_face_nearest_steps")
|
||||
|
||||
if 'VOLUME' in snap_elements:
|
||||
col.prop(tool_settings, "use_snap_peel_object")
|
||||
col_targetsel.prop(
|
||||
tool_settings,
|
||||
"use_snap_edit",
|
||||
text="Include Edited",
|
||||
icon='OUTLINER_DATA_MESH',
|
||||
)
|
||||
col_targetsel.prop(
|
||||
tool_settings,
|
||||
"use_snap_nonedit",
|
||||
text="Include Non-Edited",
|
||||
icon='OUTLINER_OB_MESH',
|
||||
)
|
||||
col_targetsel.prop(
|
||||
tool_settings,
|
||||
"use_snap_selectable",
|
||||
text="Exclude Non-Selectable",
|
||||
icon='RESTRICT_SELECT_OFF',
|
||||
)
|
||||
|
||||
col.label(text="Affect")
|
||||
row = col.row(align=True)
|
||||
|
|
|
@ -335,6 +335,7 @@ compositor_node_categories = [
|
|||
NodeItem("CompositorNodeSunBeams"),
|
||||
NodeItem("CompositorNodeDenoise"),
|
||||
NodeItem("CompositorNodeAntiAliasing"),
|
||||
NodeItem("CompositorNodeKuwahara"),
|
||||
]),
|
||||
CompositorNodeCategory("CMP_OP_VECTOR", "Vector", items=[
|
||||
NodeItem("CompositorNodeNormal"),
|
||||
|
|
|
@ -124,6 +124,7 @@ class AssetLibrary {
|
|||
*/
|
||||
AssetRepresentation &add_external_asset(StringRef relative_asset_path,
|
||||
StringRef name,
|
||||
int id_type,
|
||||
std::unique_ptr<AssetMetaData> metadata);
|
||||
/** See #AssetLibrary::add_external_asset(). */
|
||||
AssetRepresentation &add_local_id_asset(StringRef relative_asset_path, ID &id);
|
||||
|
|
|
@ -22,6 +22,7 @@ typedef struct AssetRepresentation AssetRepresentation;
|
|||
|
||||
const char *AS_asset_representation_name_get(const AssetRepresentation *asset)
|
||||
ATTR_WARN_UNUSED_RESULT;
|
||||
int AS_asset_representation_id_type_get(const AssetRepresentation *asset) ATTR_WARN_UNUSED_RESULT;
|
||||
AssetMetaData *AS_asset_representation_metadata_get(const AssetRepresentation *asset)
|
||||
ATTR_WARN_UNUSED_RESULT;
|
||||
struct ID *AS_asset_representation_local_id_get(const AssetRepresentation *asset)
|
||||
|
|
|
@ -42,6 +42,7 @@ class AssetRepresentation {
|
|||
|
||||
struct ExternalAsset {
|
||||
std::string name;
|
||||
int id_type = 0;
|
||||
std::unique_ptr<AssetMetaData> metadata_ = nullptr;
|
||||
};
|
||||
union {
|
||||
|
@ -55,6 +56,7 @@ class AssetRepresentation {
|
|||
/** Constructs an asset representation for an external ID. The asset will not be editable. */
|
||||
AssetRepresentation(AssetIdentifier &&identifier,
|
||||
StringRef name,
|
||||
int id_type,
|
||||
std::unique_ptr<AssetMetaData> metadata,
|
||||
const AssetLibrary &owner_asset_library);
|
||||
/**
|
||||
|
@ -85,6 +87,7 @@ class AssetRepresentation {
|
|||
std::unique_ptr<AssetWeakReference> make_weak_reference() const;
|
||||
|
||||
StringRefNull get_name() const;
|
||||
int get_id_type() const;
|
||||
AssetMetaData &get_metadata() const;
|
||||
/**
|
||||
* Get the import method to use for this asset. A different one may be used if
|
||||
|
@ -114,6 +117,9 @@ class AssetRepresentation {
|
|||
/* C-Handle */
|
||||
struct AssetRepresentation;
|
||||
|
||||
const blender::StringRefNull AS_asset_representation_library_relative_identifier_get(
|
||||
const AssetRepresentation *asset_handle);
|
||||
|
||||
std::string AS_asset_representation_full_path_get(const ::AssetRepresentation *asset);
|
||||
/**
|
||||
* Get the absolute path to the .blend file containing the given asset. String will be empty if
|
||||
|
|
|
@ -230,11 +230,12 @@ void AssetLibrary::refresh()
|
|||
|
||||
AssetRepresentation &AssetLibrary::add_external_asset(StringRef relative_asset_path,
|
||||
StringRef name,
|
||||
const int id_type,
|
||||
std::unique_ptr<AssetMetaData> metadata)
|
||||
{
|
||||
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
||||
return asset_storage_->add_external_asset(
|
||||
std::move(identifier), name, std::move(metadata), *this);
|
||||
std::move(identifier), name, id_type, std::move(metadata), *this);
|
||||
}
|
||||
|
||||
AssetRepresentation &AssetLibrary::add_local_id_asset(StringRef relative_asset_path, ID &id)
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace blender::asset_system {
|
|||
|
||||
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
|
||||
StringRef name,
|
||||
const int id_type,
|
||||
std::unique_ptr<AssetMetaData> metadata,
|
||||
const AssetLibrary &owner_asset_library)
|
||||
: identifier_(identifier),
|
||||
|
@ -29,6 +30,7 @@ AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
|
|||
external_asset_()
|
||||
{
|
||||
external_asset_.name = name;
|
||||
external_asset_.id_type = id_type;
|
||||
external_asset_.metadata_ = std::move(metadata);
|
||||
}
|
||||
|
||||
|
@ -87,6 +89,15 @@ StringRefNull AssetRepresentation::get_name() const
|
|||
return external_asset_.name;
|
||||
}
|
||||
|
||||
int AssetRepresentation::get_id_type() const
|
||||
{
|
||||
if (is_local_id_) {
|
||||
return GS(local_asset_id_->name);
|
||||
}
|
||||
|
||||
return external_asset_.id_type;
|
||||
}
|
||||
|
||||
AssetMetaData &AssetRepresentation::get_metadata() const
|
||||
{
|
||||
return is_local_id_ ? *local_asset_id_->asset_data : *external_asset_.metadata_;
|
||||
|
@ -135,6 +146,15 @@ const AssetLibrary &AssetRepresentation::owner_asset_library() const
|
|||
|
||||
using namespace blender;
|
||||
|
||||
const StringRefNull AS_asset_representation_library_relative_identifier_get(
|
||||
const AssetRepresentation *asset_handle)
|
||||
{
|
||||
const asset_system::AssetRepresentation *asset =
|
||||
reinterpret_cast<const asset_system::AssetRepresentation *>(asset_handle);
|
||||
const asset_system::AssetIdentifier &identifier = asset->get_identifier();
|
||||
return identifier.library_relative_identifier();
|
||||
}
|
||||
|
||||
std::string AS_asset_representation_full_path_get(const AssetRepresentation *asset_handle)
|
||||
{
|
||||
const asset_system::AssetRepresentation *asset =
|
||||
|
@ -183,6 +203,13 @@ const char *AS_asset_representation_name_get(const AssetRepresentation *asset_ha
|
|||
return asset->get_name().c_str();
|
||||
}
|
||||
|
||||
int AS_asset_representation_id_type_get(const AssetRepresentation *asset_handle)
|
||||
{
|
||||
const asset_system::AssetRepresentation *asset =
|
||||
reinterpret_cast<const asset_system::AssetRepresentation *>(asset_handle);
|
||||
return asset->get_id_type();
|
||||
}
|
||||
|
||||
AssetMetaData *AS_asset_representation_metadata_get(const AssetRepresentation *asset_handle)
|
||||
{
|
||||
const asset_system::AssetRepresentation *asset =
|
||||
|
|
|
@ -27,11 +27,12 @@ AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifi
|
|||
|
||||
AssetRepresentation &AssetStorage::add_external_asset(AssetIdentifier &&identifier,
|
||||
StringRef name,
|
||||
const int id_type,
|
||||
std::unique_ptr<AssetMetaData> metadata,
|
||||
const AssetLibrary &owner_asset_library)
|
||||
{
|
||||
return *external_assets_.lookup_key_or_add(std::make_unique<AssetRepresentation>(
|
||||
std::move(identifier), name, std::move(metadata), owner_asset_library));
|
||||
std::move(identifier), name, id_type, std::move(metadata), owner_asset_library));
|
||||
}
|
||||
|
||||
bool AssetStorage::remove_asset(AssetRepresentation &asset)
|
||||
|
|
|
@ -37,6 +37,7 @@ class AssetStorage {
|
|||
/** See #AssetLibrary::add_external_asset(). */
|
||||
AssetRepresentation &add_external_asset(AssetIdentifier &&identifier,
|
||||
StringRef name,
|
||||
int id_type,
|
||||
std::unique_ptr<AssetMetaData> metadata,
|
||||
const AssetLibrary &owner_asset_library);
|
||||
/** See #AssetLibrary::add_external_asset(). */
|
||||
|
|
|
@ -32,7 +32,8 @@ class AssetRepresentationTest : public AssetLibraryTestBase {
|
|||
AssetRepresentation &add_dummy_asset(AssetLibrary &library, StringRef relative_path)
|
||||
{
|
||||
std::unique_ptr<AssetMetaData> dummy_metadata = std::make_unique<AssetMetaData>();
|
||||
return library.add_external_asset(relative_path, "Some asset name", std::move(dummy_metadata));
|
||||
return library.add_external_asset(
|
||||
relative_path, "Some asset name", 0, std::move(dummy_metadata));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -38,6 +38,13 @@ typedef struct AssetTypeInfo {
|
|||
struct AssetMetaData *BKE_asset_metadata_create(void);
|
||||
void BKE_asset_metadata_free(struct AssetMetaData **asset_data);
|
||||
|
||||
/**
|
||||
* Create a copy of the #AssetMetaData so that it can be assigned to another asset.
|
||||
*
|
||||
* The caller becomes the owner of the returned pointer.
|
||||
*/
|
||||
struct AssetMetaData *BKE_asset_metadata_copy(const struct AssetMetaData *source);
|
||||
|
||||
struct AssetTagEnsureResult {
|
||||
struct AssetTag *tag;
|
||||
/* Set to false if a tag of this name was already present. */
|
||||
|
|
|
@ -27,7 +27,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 4
|
||||
#define BLENDER_FILE_SUBVERSION 5
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
|
|
|
@ -65,7 +65,7 @@ void BKE_blendfile_read_setup_readfile(struct bContext *C,
|
|||
const char *startup_app_template);
|
||||
|
||||
/**
|
||||
* Simpler version of #BKE_blendfile_read_setup_readfile used when reading undoe steps from
|
||||
* Simpler version of #BKE_blendfile_read_setup_readfile used when reading undo steps from
|
||||
* memfile. */
|
||||
void BKE_blendfile_read_setup_undo(struct bContext *C,
|
||||
struct BlendFileData *bfd,
|
||||
|
|
|
@ -51,5 +51,8 @@ struct GeometryDeformation {
|
|||
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig);
|
||||
GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
||||
const Object &ob_orig);
|
||||
GeometryDeformation get_evaluated_grease_pencil_drawing_deformation(const Object *ob_eval,
|
||||
const Object &ob_orig,
|
||||
int drawing_index);
|
||||
|
||||
} // namespace blender::bke::crazyspace
|
||||
|
|
|
@ -1061,6 +1061,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
|
|||
#define CMP_NODE_INPAINT 272
|
||||
#define CMP_NODE_DESPECKLE 273
|
||||
#define CMP_NODE_ANTIALIASING 274
|
||||
#define CMP_NODE_KUWAHARA 275
|
||||
|
||||
#define CMP_NODE_GLARE 301
|
||||
#define CMP_NODE_TONEMAP 302
|
||||
|
|
|
@ -75,15 +75,13 @@ bool BKE_texture_dependsOnTime(const struct Tex *texture);
|
|||
*/
|
||||
bool BKE_texture_is_image_user(const struct Tex *tex);
|
||||
|
||||
void BKE_texture_get_value_ex(const struct Scene *scene,
|
||||
struct Tex *texture,
|
||||
void BKE_texture_get_value_ex(struct Tex *texture,
|
||||
const float *tex_co,
|
||||
struct TexResult *texres,
|
||||
struct ImagePool *pool,
|
||||
bool use_color_management);
|
||||
|
||||
void BKE_texture_get_value(const struct Scene *scene,
|
||||
struct Tex *texture,
|
||||
void BKE_texture_get_value(struct Tex *texture,
|
||||
const float *tex_co,
|
||||
struct TexResult *texres,
|
||||
bool use_color_management);
|
||||
|
|
|
@ -21,6 +21,7 @@ struct MovieClipUser;
|
|||
struct MovieDistortion;
|
||||
struct MovieReconstructContext;
|
||||
struct MovieTracking;
|
||||
struct MovieTrackingCamera;
|
||||
struct MovieTrackingMarker;
|
||||
struct MovieTrackingObject;
|
||||
struct MovieTrackingPlaneMarker;
|
||||
|
@ -464,6 +465,16 @@ void BKE_tracking_camera_principal_point_pixel_get(struct MovieClip *clip,
|
|||
void BKE_tracking_camera_principal_point_pixel_set(struct MovieClip *clip,
|
||||
const float principal_point_pixel[2]);
|
||||
|
||||
/* Compares distortion related parameters of camera. Ideally, this implementation will be
|
||||
* abstracted away in the future, but for now, one needs to be careful about it and handle any
|
||||
* extra parameters of distortions models. */
|
||||
bool BKE_tracking_camera_distortion_equal(const struct MovieTrackingCamera *a,
|
||||
const struct MovieTrackingCamera *b);
|
||||
/* Hashes distortion related parameters of camera. Ideally, this implementation will be
|
||||
* abstracted away in the future, but for now, one needs to be careful about it and handle any
|
||||
* extra parameters of distortions models. */
|
||||
uint64_t BKE_tracking_camera_distortion_hash(const struct MovieTrackingCamera *camera);
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* (Un)distortion.
|
||||
*/
|
||||
|
|
|
@ -1852,7 +1852,7 @@ void BKE_pose_blend_write(BlendWriter *writer, bPose *pose, bArmature *arm)
|
|||
|
||||
animviz_motionpath_blend_write(writer, chan->mpath);
|
||||
|
||||
/* Prevent crashes with autosave,
|
||||
/* Prevent crashes with auto-save,
|
||||
* when a bone duplicated in edit-mode has not yet been assigned to its pose-channel.
|
||||
* Also needed with memundo, in some cases we can store a step before pose has been
|
||||
* properly rebuilt from previous undo step. */
|
||||
|
|
|
@ -114,10 +114,10 @@ AnimData *BKE_animdata_ensure_id(ID *id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Action / Tmpact Setter shared code -------------------------
|
||||
/* Action / `tmpact` Setter shared code -------------------------
|
||||
*
|
||||
* Both the action and tmpact setter functions have essentially
|
||||
* identical semantics, because tmpact is just a place to temporarily
|
||||
* Both the action and `tmpact` setter functions have essentially
|
||||
* identical semantics, because `tmpact` is just a place to temporarily
|
||||
* store the main action during tweaking. This function contains the
|
||||
* shared code between those two setter functions, setting the action
|
||||
* of the passed `act_slot` to `act`.
|
||||
|
|
|
@ -65,7 +65,7 @@ static void pchan_deform_accumulate(const DualQuat *deform_dq,
|
|||
BLI_assert(!co_accum);
|
||||
|
||||
if (deform_dq->scale_weight) {
|
||||
/* FIX https://projects.blender.org/blender/blender/issues/32022 */
|
||||
/* FIX #32022. */
|
||||
DualQuat mdq = *deform_dq;
|
||||
float dst[3];
|
||||
mul_v3_m4v3(dst, mdq.scale, co_in);
|
||||
|
|
|
@ -39,6 +39,38 @@ void BKE_asset_metadata_free(AssetMetaData **asset_data)
|
|||
*asset_data = nullptr;
|
||||
}
|
||||
|
||||
AssetMetaData *BKE_asset_metadata_copy(const AssetMetaData *source)
|
||||
{
|
||||
AssetMetaData *copy = BKE_asset_metadata_create();
|
||||
|
||||
copy->local_type_info = source->local_type_info;
|
||||
|
||||
if (source->properties) {
|
||||
copy->properties = IDP_CopyProperty(source->properties);
|
||||
}
|
||||
|
||||
BKE_asset_metadata_catalog_id_set(copy, source->catalog_id, source->catalog_simple_name);
|
||||
|
||||
if (source->author) {
|
||||
copy->author = BLI_strdup(source->author);
|
||||
}
|
||||
if (source->description) {
|
||||
copy->description = BLI_strdup(source->description);
|
||||
}
|
||||
if (source->copyright) {
|
||||
copy->copyright = BLI_strdup(source->copyright);
|
||||
}
|
||||
if (source->license) {
|
||||
copy->license = BLI_strdup(source->license);
|
||||
}
|
||||
|
||||
BLI_duplicatelist(©->tags, &source->tags);
|
||||
copy->active_tag = source->active_tag;
|
||||
copy->tot_tags = source->tot_tags;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
AssetMetaData::~AssetMetaData()
|
||||
{
|
||||
if (properties) {
|
||||
|
|
|
@ -208,14 +208,13 @@ static void setup_app_userdef(BlendFileData *bfd)
|
|||
BKE_blender_userdef_data_set_and_free(bfd->user);
|
||||
bfd->user = nullptr;
|
||||
|
||||
/* Security issue: any blend file could include a USER block.
|
||||
/* Security issue: any blend file could include a #BLO_CODE_USER block.
|
||||
*
|
||||
* Currently we load prefs from BLENDER_STARTUP_FILE and later on load BLENDER_USERPREF_FILE,
|
||||
* to load the preferences defined in the users home dir.
|
||||
* Preferences are loaded from #BLENDER_STARTUP_FILE and later on load #BLENDER_USERPREF_FILE,
|
||||
* to load the preferences defined in the users home directory.
|
||||
*
|
||||
* This means we will never accidentally (or maliciously)
|
||||
* enable scripts auto-execution by loading a '.blend' file.
|
||||
*/
|
||||
* enable scripts auto-execution by loading a `.blend` file. */
|
||||
U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE;
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +250,7 @@ typedef struct ReuseOldBMainData {
|
|||
* NOTE: The case where the `old_bmain` would be a library in the newly read one is not handled
|
||||
* here, as it does not create explicit issues. The local data from `old_bmain` is either
|
||||
* discarded, or added to the `new_bmain` as local data as well. Worst case, there will be a
|
||||
* doublon of a linked data as a local one, without any known relationships between them. In
|
||||
* double of a linked data as a local one, without any known relationships between them. In
|
||||
* practice, this latter case is not expected to commonly happen.
|
||||
*/
|
||||
static IDRemapper *reuse_bmain_data_remapper_ensure(ReuseOldBMainData *reuse_data)
|
||||
|
@ -747,7 +746,7 @@ static void setup_app_data(bContext *C,
|
|||
wmWindow *win = nullptr;
|
||||
bScreen *curscreen = nullptr;
|
||||
|
||||
/* Ensure that there is a valid scene and viewlayer. */
|
||||
/* Ensure that there is a valid scene and view-layer. */
|
||||
if (curscene == nullptr) {
|
||||
curscene = static_cast<Scene *>(bfd->main->scenes.first);
|
||||
}
|
||||
|
@ -904,7 +903,7 @@ static void setup_app_data(bContext *C,
|
|||
bmain->filepath[0] = '\0';
|
||||
}
|
||||
else if (recover) {
|
||||
/* In case of autosave or quit.blend, use original filepath instead. */
|
||||
/* In case of auto-save or quit.blend, use original filepath instead. */
|
||||
bmain->recovered = true;
|
||||
STRNCPY(bmain->filepath, bfd->filepath);
|
||||
}
|
||||
|
|
|
@ -368,6 +368,10 @@ void clothModifier_do(ClothModifierData *clmd,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Since implicit sharing is introduced, mesh data can be moved to other places.
|
||||
* Therefore some fields in simulation data need to be updated accordingly */
|
||||
clmd->clothObject->edges = reinterpret_cast<const vec2i *>(mesh->edges().data());
|
||||
|
||||
/* try to read from cache */
|
||||
bool can_simulate = (framenr == clmd->clothObject->last_frame + 1) &&
|
||||
!(cache->flag & PTCACHE_BAKED);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "BKE_curves.hh"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_wrapper.h"
|
||||
|
@ -662,4 +663,37 @@ GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
|||
return get_evaluated_curves_deformation(ob_eval, ob_orig);
|
||||
}
|
||||
|
||||
GeometryDeformation get_evaluated_grease_pencil_drawing_deformation(const Object *ob_eval,
|
||||
const Object &ob_orig,
|
||||
const int drawing_index)
|
||||
{
|
||||
BLI_assert(ob_orig.type == OB_GREASE_PENCIL);
|
||||
const GreasePencil &grease_pencil_orig = *static_cast<const GreasePencil *>(ob_orig.data);
|
||||
|
||||
GreasePencilDrawingBase *drawing_base = grease_pencil_orig.drawings()[drawing_index];
|
||||
|
||||
GeometryDeformation deformation;
|
||||
if (drawing_base->type == GP_DRAWING) {
|
||||
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
|
||||
/* Use the undeformed positions by default. */
|
||||
deformation.positions = drawing->geometry.wrap().positions();
|
||||
}
|
||||
else if (drawing_base->type == GP_DRAWING_REFERENCE) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
if (ob_eval == nullptr) {
|
||||
return deformation;
|
||||
}
|
||||
const GeometrySet *geometry_eval = ob_eval->runtime.geometry_set_eval;
|
||||
if (geometry_eval == nullptr) {
|
||||
return deformation;
|
||||
}
|
||||
|
||||
/* TODO: Read `GeometryComponentEditData` from `geometry_eval` and populate deformation with it.
|
||||
*/
|
||||
|
||||
return deformation;
|
||||
}
|
||||
|
||||
} // namespace blender::bke::crazyspace
|
||||
|
|
|
@ -1931,7 +1931,7 @@ static void sample_mesh(FluidFlowSettings *ffs,
|
|||
tex_co[1] = tex_co[1] * 2.0f - 1.0f;
|
||||
tex_co[2] = ffs->texture_offset;
|
||||
}
|
||||
BKE_texture_get_value(nullptr, ffs->noise_texture, tex_co, &texres, false);
|
||||
BKE_texture_get_value(ffs->noise_texture, tex_co, &texres, false);
|
||||
emission_strength *= texres.tin;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
#include "attribute_access_intern.hh"
|
||||
|
||||
using blender::GVArray;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Geometry Component Implementation
|
||||
* \{ */
|
||||
|
@ -292,47 +290,43 @@ std::optional<eAttrDomain> CurveLengthFieldInput::preferred_domain(
|
|||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Attribute Access Helper Functions
|
||||
* \{ */
|
||||
|
||||
static void tag_component_topology_changed(void *owner)
|
||||
{
|
||||
blender::bke::CurvesGeometry &curves = *static_cast<blender::bke::CurvesGeometry *>(owner);
|
||||
CurvesGeometry &curves = *static_cast<CurvesGeometry *>(owner);
|
||||
curves.tag_topology_changed();
|
||||
}
|
||||
|
||||
static void tag_component_curve_types_changed(void *owner)
|
||||
{
|
||||
blender::bke::CurvesGeometry &curves = *static_cast<blender::bke::CurvesGeometry *>(owner);
|
||||
CurvesGeometry &curves = *static_cast<CurvesGeometry *>(owner);
|
||||
curves.update_curve_types();
|
||||
curves.tag_topology_changed();
|
||||
}
|
||||
|
||||
static void tag_component_positions_changed(void *owner)
|
||||
{
|
||||
blender::bke::CurvesGeometry &curves = *static_cast<blender::bke::CurvesGeometry *>(owner);
|
||||
CurvesGeometry &curves = *static_cast<CurvesGeometry *>(owner);
|
||||
curves.tag_positions_changed();
|
||||
}
|
||||
|
||||
static void tag_component_radii_changed(void *owner)
|
||||
{
|
||||
blender::bke::CurvesGeometry &curves = *static_cast<blender::bke::CurvesGeometry *>(owner);
|
||||
CurvesGeometry &curves = *static_cast<CurvesGeometry *>(owner);
|
||||
curves.tag_radii_changed();
|
||||
}
|
||||
|
||||
static void tag_component_normals_changed(void *owner)
|
||||
{
|
||||
blender::bke::CurvesGeometry &curves = *static_cast<blender::bke::CurvesGeometry *>(owner);
|
||||
CurvesGeometry &curves = *static_cast<CurvesGeometry *>(owner);
|
||||
curves.tag_normals_changed();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Attribute Provider Declaration
|
||||
* \{ */
|
||||
|
@ -590,7 +584,7 @@ static AttributeAccessorFunctions get_curves_accessor_functions()
|
|||
return ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE);
|
||||
};
|
||||
fn.adapt_domain = [](const void *owner,
|
||||
const blender::GVArray &varray,
|
||||
const GVArray &varray,
|
||||
const eAttrDomain from_domain,
|
||||
const eAttrDomain to_domain) -> GVArray {
|
||||
if (owner == nullptr) {
|
||||
|
|
|
@ -24,17 +24,6 @@
|
|||
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
|
||||
using blender::float4x4;
|
||||
using blender::GSpan;
|
||||
using blender::IndexMask;
|
||||
using blender::Map;
|
||||
using blender::MutableSpan;
|
||||
using blender::Set;
|
||||
using blender::Span;
|
||||
using blender::VectorSet;
|
||||
using blender::bke::InstanceReference;
|
||||
using blender::bke::Instances;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Geometry Component Implementation
|
||||
* \{ */
|
||||
|
@ -50,7 +39,7 @@ GeometryComponent *InstancesComponent::copy() const
|
|||
{
|
||||
InstancesComponent *new_component = new InstancesComponent();
|
||||
if (instances_ != nullptr) {
|
||||
new_component->instances_ = new Instances(*instances_);
|
||||
new_component->instances_ = new blender::bke::Instances(*instances_);
|
||||
new_component->ownership_ = GeometryOwnershipType::Owned;
|
||||
}
|
||||
return new_component;
|
||||
|
@ -99,13 +88,14 @@ blender::bke::Instances *InstancesComponent::get_for_write()
|
|||
{
|
||||
BLI_assert(this->is_mutable());
|
||||
if (ownership_ == GeometryOwnershipType::ReadOnly) {
|
||||
instances_ = new Instances(*instances_);
|
||||
instances_ = new blender::bke::Instances(*instances_);
|
||||
ownership_ = GeometryOwnershipType::Owned;
|
||||
}
|
||||
return instances_;
|
||||
}
|
||||
|
||||
void InstancesComponent::replace(Instances *instances, GeometryOwnershipType ownership)
|
||||
void InstancesComponent::replace(blender::bke::Instances *instances,
|
||||
GeometryOwnershipType ownership)
|
||||
{
|
||||
BLI_assert(this->is_mutable());
|
||||
this->clear();
|
||||
|
@ -233,13 +223,13 @@ static AttributeAccessorFunctions get_instances_accessor_functions()
|
|||
return domain == ATTR_DOMAIN_INSTANCE;
|
||||
};
|
||||
fn.adapt_domain = [](const void * /*owner*/,
|
||||
const blender::GVArray &varray,
|
||||
const GVArray &varray,
|
||||
const eAttrDomain from_domain,
|
||||
const eAttrDomain to_domain) {
|
||||
if (from_domain == to_domain && from_domain == ATTR_DOMAIN_INSTANCE) {
|
||||
return varray;
|
||||
}
|
||||
return blender::GVArray{};
|
||||
return GVArray{};
|
||||
};
|
||||
return fn;
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
|
||||
#include "attribute_access_intern.hh"
|
||||
|
||||
extern "C" MDeformVert *BKE_object_defgroup_data_create(ID *id);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Geometry Component Implementation
|
||||
* \{ */
|
||||
|
@ -158,16 +156,12 @@ VArray<float3> mesh_normals_varray(const Mesh &mesh,
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Attribute Access
|
||||
* \{ */
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
template<typename T>
|
||||
static void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
|
||||
const VArray<T> &old_values,
|
||||
|
@ -740,8 +734,6 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v
|
|||
return new_varray;
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
static bool can_simple_adapt_for_single(const Mesh &mesh,
|
||||
const eAttrDomain from_domain,
|
||||
const eAttrDomain to_domain)
|
||||
|
@ -780,10 +772,10 @@ static bool can_simple_adapt_for_single(const Mesh &mesh,
|
|||
}
|
||||
}
|
||||
|
||||
static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
|
||||
const blender::GVArray &varray,
|
||||
const eAttrDomain from_domain,
|
||||
const eAttrDomain to_domain)
|
||||
static GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
|
||||
const GVArray &varray,
|
||||
const eAttrDomain from_domain,
|
||||
const eAttrDomain to_domain)
|
||||
{
|
||||
if (!varray) {
|
||||
return {};
|
||||
|
@ -798,8 +790,7 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
|
|||
if (can_simple_adapt_for_single(mesh, from_domain, to_domain)) {
|
||||
BUFFER_FOR_CPP_TYPE_VALUE(varray.type(), value);
|
||||
varray.get_internal_single(value);
|
||||
return blender::GVArray::ForSingle(
|
||||
varray.type(), mesh.attributes().domain_size(to_domain), value);
|
||||
return GVArray::ForSingle(varray.type(), mesh.attributes().domain_size(to_domain), value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -807,11 +798,11 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
|
|||
case ATTR_DOMAIN_CORNER: {
|
||||
switch (to_domain) {
|
||||
case ATTR_DOMAIN_POINT:
|
||||
return blender::bke::adapt_mesh_domain_corner_to_point(mesh, varray);
|
||||
return adapt_mesh_domain_corner_to_point(mesh, varray);
|
||||
case ATTR_DOMAIN_FACE:
|
||||
return blender::bke::adapt_mesh_domain_corner_to_face(mesh, varray);
|
||||
return adapt_mesh_domain_corner_to_face(mesh, varray);
|
||||
case ATTR_DOMAIN_EDGE:
|
||||
return blender::bke::adapt_mesh_domain_corner_to_edge(mesh, varray);
|
||||
return adapt_mesh_domain_corner_to_edge(mesh, varray);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -820,11 +811,11 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
|
|||
case ATTR_DOMAIN_POINT: {
|
||||
switch (to_domain) {
|
||||
case ATTR_DOMAIN_CORNER:
|
||||
return blender::bke::adapt_mesh_domain_point_to_corner(mesh, varray);
|
||||
return adapt_mesh_domain_point_to_corner(mesh, varray);
|
||||
case ATTR_DOMAIN_FACE:
|
||||
return blender::bke::adapt_mesh_domain_point_to_face(mesh, varray);
|
||||
return adapt_mesh_domain_point_to_face(mesh, varray);
|
||||
case ATTR_DOMAIN_EDGE:
|
||||
return blender::bke::adapt_mesh_domain_point_to_edge(mesh, varray);
|
||||
return adapt_mesh_domain_point_to_edge(mesh, varray);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -833,11 +824,11 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
|
|||
case ATTR_DOMAIN_FACE: {
|
||||
switch (to_domain) {
|
||||
case ATTR_DOMAIN_POINT:
|
||||
return blender::bke::adapt_mesh_domain_face_to_point(mesh, varray);
|
||||
return adapt_mesh_domain_face_to_point(mesh, varray);
|
||||
case ATTR_DOMAIN_CORNER:
|
||||
return blender::bke::adapt_mesh_domain_face_to_corner(mesh, varray);
|
||||
return adapt_mesh_domain_face_to_corner(mesh, varray);
|
||||
case ATTR_DOMAIN_EDGE:
|
||||
return blender::bke::adapt_mesh_domain_face_to_edge(mesh, varray);
|
||||
return adapt_mesh_domain_face_to_edge(mesh, varray);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -846,11 +837,11 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
|
|||
case ATTR_DOMAIN_EDGE: {
|
||||
switch (to_domain) {
|
||||
case ATTR_DOMAIN_CORNER:
|
||||
return blender::bke::adapt_mesh_domain_edge_to_corner(mesh, varray);
|
||||
return adapt_mesh_domain_edge_to_corner(mesh, varray);
|
||||
case ATTR_DOMAIN_POINT:
|
||||
return blender::bke::adapt_mesh_domain_edge_to_point(mesh, varray);
|
||||
return adapt_mesh_domain_edge_to_point(mesh, varray);
|
||||
case ATTR_DOMAIN_FACE:
|
||||
return blender::bke::adapt_mesh_domain_edge_to_face(mesh, varray);
|
||||
return adapt_mesh_domain_edge_to_face(mesh, varray);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -863,8 +854,6 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
|
|||
return {};
|
||||
}
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
static void tag_component_positions_changed(void *owner)
|
||||
{
|
||||
Mesh *mesh = static_cast<Mesh *>(owner);
|
||||
|
@ -1269,9 +1258,9 @@ static AttributeAccessorFunctions get_mesh_accessor_functions()
|
|||
return ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_FACE, ATTR_DOMAIN_CORNER);
|
||||
};
|
||||
fn.adapt_domain = [](const void *owner,
|
||||
const blender::GVArray &varray,
|
||||
const GVArray &varray,
|
||||
const eAttrDomain from_domain,
|
||||
const eAttrDomain to_domain) -> blender::GVArray {
|
||||
const eAttrDomain to_domain) -> GVArray {
|
||||
if (owner == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -1061,7 +1061,7 @@ enum ForeachDrawingMode {
|
|||
static void foreach_drawing_ex(GreasePencil &grease_pencil,
|
||||
int frame,
|
||||
ForeachDrawingMode mode,
|
||||
blender::FunctionRef<void(GreasePencilDrawing &)> function)
|
||||
blender::FunctionRef<void(int, GreasePencilDrawing &)> function)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
|
||||
|
@ -1089,7 +1089,7 @@ static void foreach_drawing_ex(GreasePencil &grease_pencil,
|
|||
GreasePencilDrawingBase *drawing_base = drawings[index];
|
||||
if (drawing_base->type == GP_DRAWING) {
|
||||
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
|
||||
function(*drawing);
|
||||
function(index, *drawing);
|
||||
}
|
||||
else if (drawing_base->type == GP_DRAWING_REFERENCE) {
|
||||
/* TODO */
|
||||
|
@ -1098,13 +1098,13 @@ static void foreach_drawing_ex(GreasePencil &grease_pencil,
|
|||
}
|
||||
|
||||
void GreasePencil::foreach_visible_drawing(
|
||||
int frame, blender::FunctionRef<void(GreasePencilDrawing &)> function)
|
||||
int frame, blender::FunctionRef<void(int, GreasePencilDrawing &)> function)
|
||||
{
|
||||
foreach_drawing_ex(*this, frame, VISIBLE, function);
|
||||
}
|
||||
|
||||
void GreasePencil::foreach_editable_drawing(
|
||||
int frame, blender::FunctionRef<void(GreasePencilDrawing &)> function)
|
||||
int frame, blender::FunctionRef<void(int, GreasePencilDrawing &)> function)
|
||||
{
|
||||
foreach_drawing_ex(*this, frame, EDITABLE, function);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* Usage:
|
||||
*
|
||||
* ```
|
||||
* \code{.cc}
|
||||
* Image *image = ...;
|
||||
* ImBuf *image_buffer = ...;
|
||||
*
|
||||
|
@ -44,8 +44,7 @@
|
|||
*
|
||||
* // Free partial_update_user.
|
||||
* BKE_image_partial_update_free(partial_update_user);
|
||||
*
|
||||
* ```
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#include <optional>
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_array_utils.hh"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_task.hh"
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_attribute_math.hh"
|
||||
#include "BKE_bvhutils.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_editmesh.h"
|
||||
|
@ -35,6 +36,7 @@
|
|||
#include "BKE_mesh_mapping.h"
|
||||
#include "BKE_mesh_remesh_voxel.h" /* own include */
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_mesh_sample.hh"
|
||||
|
||||
#include "bmesh_tools.h"
|
||||
|
||||
|
@ -360,116 +362,104 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
|
|||
|
||||
void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
|
||||
{
|
||||
BVHTreeFromMesh bvhtree = {nullptr};
|
||||
BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2);
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const AttributeAccessor src_attributes = source->attributes();
|
||||
MutableAttributeAccessor dst_attributes = target->attributes_for_write();
|
||||
|
||||
int i = 0;
|
||||
const CustomDataLayer *layer;
|
||||
Vector<AttributeIDRef> point_ids;
|
||||
Vector<AttributeIDRef> corner_ids;
|
||||
source->attributes().for_all([&](const AttributeIDRef &id, const AttributeMetaData &meta_data) {
|
||||
if (CD_TYPE_AS_MASK(meta_data.data_type) & CD_MASK_COLOR_ALL) {
|
||||
if (meta_data.domain == ATTR_DOMAIN_POINT) {
|
||||
point_ids.append(id);
|
||||
}
|
||||
else if (meta_data.domain == ATTR_DOMAIN_CORNER) {
|
||||
corner_ids.append(id);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (point_ids.is_empty() && corner_ids.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Array<int> source_vert_to_loop_offsets;
|
||||
Array<int> source_vert_to_loop_indices;
|
||||
blender::GroupedSpan<int> source_lmap;
|
||||
|
||||
GroupedSpan<int> source_lmap;
|
||||
Array<int> target_vert_to_loop_offsets;
|
||||
Array<int> target_vert_to_loop_indices;
|
||||
blender::GroupedSpan<int> target_lmap;
|
||||
GroupedSpan<int> target_lmap;
|
||||
BVHTreeFromMesh bvhtree = {nullptr};
|
||||
threading::parallel_invoke(
|
||||
[&]() { BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2); },
|
||||
[&]() {
|
||||
source_lmap = mesh::build_vert_to_loop_map(source->corner_verts(),
|
||||
source->totvert,
|
||||
source_vert_to_loop_offsets,
|
||||
source_vert_to_loop_indices);
|
||||
},
|
||||
[&]() {
|
||||
target_lmap = mesh::build_vert_to_loop_map(target->corner_verts(),
|
||||
target->totvert,
|
||||
target_vert_to_loop_offsets,
|
||||
target_vert_to_loop_indices);
|
||||
});
|
||||
|
||||
while ((layer = BKE_id_attribute_from_index(
|
||||
const_cast<ID *>(&source->id), i++, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL)))
|
||||
{
|
||||
eAttrDomain domain = BKE_id_attribute_domain(&source->id, layer);
|
||||
const eCustomDataType type = eCustomDataType(layer->type);
|
||||
|
||||
CustomData *target_cdata = domain == ATTR_DOMAIN_POINT ? &target->vdata : &target->ldata;
|
||||
const CustomData *source_cdata = domain == ATTR_DOMAIN_POINT ? &source->vdata : &source->ldata;
|
||||
|
||||
/* Check attribute exists in target. */
|
||||
int layer_i = CustomData_get_named_layer_index(target_cdata, type, layer->name);
|
||||
if (layer_i == -1) {
|
||||
int elem_num = domain == ATTR_DOMAIN_POINT ? target->totvert : target->totloop;
|
||||
|
||||
CustomData_add_layer_named(target_cdata, type, CD_SET_DEFAULT, elem_num, layer->name);
|
||||
layer_i = CustomData_get_named_layer_index(target_cdata, type, layer->name);
|
||||
const Span<float3> target_positions = target->vert_positions();
|
||||
Array<int> nearest_src_verts(target_positions.size());
|
||||
threading::parallel_for(target_positions.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
BVHTreeNearest nearest;
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = FLT_MAX;
|
||||
BLI_bvhtree_find_nearest(
|
||||
bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree);
|
||||
nearest_src_verts[i] = nearest.index;
|
||||
}
|
||||
});
|
||||
|
||||
size_t data_size = CustomData_sizeof(type);
|
||||
void *target_data = target_cdata->layers[layer_i].data;
|
||||
void *source_data = layer->data;
|
||||
const Span<float3> target_positions = target->vert_positions();
|
||||
for (const AttributeIDRef &id : point_ids) {
|
||||
const GVArraySpan src = *src_attributes.lookup(id, ATTR_DOMAIN_POINT);
|
||||
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
id, ATTR_DOMAIN_POINT, cpp_type_to_custom_data_type(src.type()));
|
||||
attribute_math::gather(src, nearest_src_verts, dst.span);
|
||||
dst.finish();
|
||||
}
|
||||
|
||||
if (domain == ATTR_DOMAIN_POINT) {
|
||||
blender::threading::parallel_for(
|
||||
IndexRange(target->totvert), 4096, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
BVHTreeNearest nearest;
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = FLT_MAX;
|
||||
BLI_bvhtree_find_nearest(
|
||||
bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree);
|
||||
if (nearest.index != -1) {
|
||||
memcpy(POINTER_OFFSET(target_data, size_t(i) * data_size),
|
||||
POINTER_OFFSET(source_data, size_t(nearest.index) * data_size),
|
||||
data_size);
|
||||
if (!corner_ids.is_empty()) {
|
||||
for (const AttributeIDRef &id : corner_ids) {
|
||||
const GVArraySpan src = *src_attributes.lookup(id, ATTR_DOMAIN_CORNER);
|
||||
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
id, ATTR_DOMAIN_CORNER, cpp_type_to_custom_data_type(src.type()));
|
||||
|
||||
threading::parallel_for(target_positions.index_range(), 1024, [&](const IndexRange range) {
|
||||
src.type().to_static_type_tag<ColorGeometry4b, ColorGeometry4f>([&](auto type_tag) {
|
||||
using T = typename decltype(type_tag)::type;
|
||||
if constexpr (std::is_void_v<T>) {
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
else {
|
||||
const Span<T> src_typed = src.typed<T>();
|
||||
MutableSpan<T> dst_typed = dst.span.typed<T>();
|
||||
for (const int dst_vert : range) {
|
||||
/* Find the average value at the corners of the closest vertex on the
|
||||
* source mesh. */
|
||||
const int src_vert = nearest_src_verts[dst_vert];
|
||||
T value;
|
||||
typename blender::bke::attribute_math::DefaultMixer<T> mixer({&value, 1});
|
||||
for (const int corner : source_lmap[src_vert]) {
|
||||
mixer.mix_in(0, src_typed[corner]);
|
||||
}
|
||||
|
||||
dst_typed.fill_indices(target_lmap[dst_vert], value);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
/* Lazily init vertex -> loop maps. */
|
||||
if (source_lmap.is_empty()) {
|
||||
source_lmap = blender::bke::mesh::build_vert_to_loop_map(source->corner_verts(),
|
||||
source->totvert,
|
||||
source_vert_to_loop_offsets,
|
||||
source_vert_to_loop_indices);
|
||||
target_lmap = blender::bke::mesh::build_vert_to_loop_map(target->corner_verts(),
|
||||
target->totvert,
|
||||
target_vert_to_loop_offsets,
|
||||
target_vert_to_loop_indices);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
blender::threading::parallel_for(
|
||||
IndexRange(target->totvert), 2048, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
BVHTreeNearest nearest;
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = FLT_MAX;
|
||||
BLI_bvhtree_find_nearest(
|
||||
bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree);
|
||||
|
||||
if (nearest.index == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Span<int> source_loops = source_lmap[nearest.index];
|
||||
const Span<int> target_loops = target_lmap[i];
|
||||
|
||||
if (target_loops.size() == 0 || source_loops.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Average color data for loops around the source vertex into
|
||||
* the first target loop around the target vertex
|
||||
*/
|
||||
|
||||
CustomData_interp(source_cdata,
|
||||
target_cdata,
|
||||
source_loops.data(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
source_loops.size(),
|
||||
target_loops[0]);
|
||||
|
||||
void *elem = POINTER_OFFSET(target_data, size_t(target_loops[0]) * data_size);
|
||||
|
||||
/* Copy to rest of target loops. */
|
||||
for (int j = 1; j < target_loops.size(); j++) {
|
||||
memcpy(POINTER_OFFSET(target_data, size_t(target_loops[j]) * data_size),
|
||||
elem,
|
||||
data_size);
|
||||
}
|
||||
}
|
||||
});
|
||||
dst.finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -331,7 +331,6 @@ static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket
|
|||
case SOCK_BOOLEAN:
|
||||
case SOCK_INT:
|
||||
case SOCK_STRING:
|
||||
case __SOCK_MESH:
|
||||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
|
@ -479,7 +478,6 @@ static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *so
|
|||
case SOCK_CUSTOM:
|
||||
/* Custom node sockets where default_value is defined uses custom properties for storage. */
|
||||
break;
|
||||
case __SOCK_MESH:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
BLI_assert_unreachable();
|
||||
|
@ -923,7 +921,6 @@ static void lib_link_node_socket(BlendLibReader *reader, ID *self_id, bNodeSocke
|
|||
case SOCK_BOOLEAN:
|
||||
case SOCK_INT:
|
||||
case SOCK_STRING:
|
||||
case __SOCK_MESH:
|
||||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
|
@ -1016,7 +1013,6 @@ static void expand_node_socket(BlendExpander *expander, bNodeSocket *sock)
|
|||
case SOCK_BOOLEAN:
|
||||
case SOCK_INT:
|
||||
case SOCK_STRING:
|
||||
case __SOCK_MESH:
|
||||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
|
@ -1705,7 +1701,6 @@ static void socket_id_user_increment(bNodeSocket *sock)
|
|||
case SOCK_BOOLEAN:
|
||||
case SOCK_INT:
|
||||
case SOCK_STRING:
|
||||
case __SOCK_MESH:
|
||||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
|
@ -1751,7 +1746,6 @@ static bool socket_id_user_decrement(bNodeSocket *sock)
|
|||
case SOCK_BOOLEAN:
|
||||
case SOCK_INT:
|
||||
case SOCK_STRING:
|
||||
case __SOCK_MESH:
|
||||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
|
@ -1804,7 +1798,6 @@ void nodeModifySocketType(bNodeTree *ntree,
|
|||
case SOCK_SHADER:
|
||||
case SOCK_BOOLEAN:
|
||||
case SOCK_CUSTOM:
|
||||
case __SOCK_MESH:
|
||||
case SOCK_OBJECT:
|
||||
case SOCK_IMAGE:
|
||||
case SOCK_GEOMETRY:
|
||||
|
@ -1943,7 +1936,7 @@ const char *nodeStaticSocketType(const int type, const int subtype)
|
|||
return "NodeSocketTexture";
|
||||
case SOCK_MATERIAL:
|
||||
return "NodeSocketMaterial";
|
||||
default:
|
||||
case SOCK_CUSTOM:
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -2022,7 +2015,7 @@ const char *nodeStaticSocketInterfaceType(const int type, const int subtype)
|
|||
return "NodeSocketInterfaceTexture";
|
||||
case SOCK_MATERIAL:
|
||||
return "NodeSocketInterfaceMaterial";
|
||||
default:
|
||||
case SOCK_CUSTOM:
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -2057,7 +2050,7 @@ const char *nodeStaticSocketLabel(const int type, const int /*subtype*/)
|
|||
return "Texture";
|
||||
case SOCK_MATERIAL:
|
||||
return "Material";
|
||||
default:
|
||||
case SOCK_CUSTOM:
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -2579,7 +2572,6 @@ static void *socket_value_storage(bNodeSocket &socket)
|
|||
case SOCK_STRING:
|
||||
/* We don't want do this now! */
|
||||
return nullptr;
|
||||
case __SOCK_MESH:
|
||||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
|
|
|
@ -3489,12 +3489,14 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
|
|||
}
|
||||
}
|
||||
|
||||
hair_create_input_mesh(sim, totpoint, totedge, &psys->hair_in_mesh);
|
||||
|
||||
/* Free hair_out_mesh before modifying hair_in_mesh in hair_create_input_mesh() to avoid copying
|
||||
* on write since they share some data */
|
||||
if (psys->hair_out_mesh) {
|
||||
BKE_id_free(NULL, psys->hair_out_mesh);
|
||||
}
|
||||
|
||||
hair_create_input_mesh(sim, totpoint, totedge, &psys->hair_in_mesh);
|
||||
|
||||
psys->clmd->point_cache = psys->pointcache;
|
||||
/* for hair sim we replace the internal cloth effector weights temporarily
|
||||
* to use the particle settings
|
||||
|
|
|
@ -705,22 +705,15 @@ bool BKE_texture_dependsOnTime(const Tex *texture)
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void BKE_texture_get_value_ex(const Scene *scene,
|
||||
Tex *texture,
|
||||
void BKE_texture_get_value_ex(Tex *texture,
|
||||
const float *tex_co,
|
||||
TexResult *texres,
|
||||
ImagePool *pool,
|
||||
bool use_color_management)
|
||||
{
|
||||
int result_type;
|
||||
bool do_color_manage = false;
|
||||
|
||||
if (scene && use_color_management) {
|
||||
do_color_manage = BKE_scene_check_color_management_enabled(scene);
|
||||
}
|
||||
|
||||
/* no node textures for now */
|
||||
result_type = multitex_ext_safe(texture, tex_co, texres, pool, do_color_manage, false);
|
||||
const int result_type = multitex_ext_safe(
|
||||
texture, tex_co, texres, pool, use_color_management, false);
|
||||
|
||||
/* if the texture gave an RGB value, we assume it didn't give a valid
|
||||
* intensity, since this is in the context of modifiers don't use perceptual color conversion.
|
||||
|
@ -734,13 +727,12 @@ void BKE_texture_get_value_ex(const Scene *scene,
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_texture_get_value(const Scene *scene,
|
||||
Tex *texture,
|
||||
void BKE_texture_get_value(Tex *texture,
|
||||
const float *tex_co,
|
||||
TexResult *texres,
|
||||
bool use_color_management)
|
||||
{
|
||||
BKE_texture_get_value_ex(scene, texture, tex_co, texres, nullptr, use_color_management);
|
||||
BKE_texture_get_value_ex(texture, tex_co, texres, nullptr, use_color_management);
|
||||
}
|
||||
|
||||
static void texture_nodes_fetch_images_for_pool(Tex *texture, bNodeTree *ntree, ImagePool *pool)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
|
@ -23,9 +24,12 @@
|
|||
|
||||
#include "BLI_bitmap_draw_2d.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_hash.hh"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utils.h"
|
||||
#include "BLI_threads.h"
|
||||
|
@ -2197,6 +2201,66 @@ void BKE_tracking_camera_principal_point_pixel_set(MovieClip *clip,
|
|||
principal_point_pixel, frame_width, frame_height, camera->principal_point);
|
||||
}
|
||||
|
||||
bool BKE_tracking_camera_distortion_equal(const MovieTrackingCamera *a,
|
||||
const MovieTrackingCamera *b)
|
||||
{
|
||||
if (a->pixel_aspect != b->pixel_aspect || a->focal != b->focal ||
|
||||
!equals_v2v2(a->principal_point, b->principal_point))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a->distortion_model != b->distortion_model) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (a->distortion_model) {
|
||||
case TRACKING_DISTORTION_MODEL_POLYNOMIAL:
|
||||
return a->k1 == b->k1 && a->k2 == b->k2 && a->k3 == b->k3;
|
||||
case TRACKING_DISTORTION_MODEL_DIVISION:
|
||||
return a->division_k1 == b->division_k1 && a->division_k2 == b->division_k2;
|
||||
case TRACKING_DISTORTION_MODEL_NUKE:
|
||||
return a->nuke_k1 == b->nuke_k1 && a->nuke_k2 == b->nuke_k2;
|
||||
case TRACKING_DISTORTION_MODEL_BROWN:
|
||||
return a->brown_k1 == b->brown_k1 && a->brown_k2 == b->brown_k2 &&
|
||||
a->brown_k3 == b->brown_k3 && a->brown_k4 == b->brown_k4 &&
|
||||
a->brown_p1 == b->brown_p1 && a->brown_p2 == b->brown_p2;
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t BKE_tracking_camera_distortion_hash(const MovieTrackingCamera *camera)
|
||||
{
|
||||
using namespace blender;
|
||||
switch (camera->distortion_model) {
|
||||
case TRACKING_DISTORTION_MODEL_POLYNOMIAL:
|
||||
return get_default_hash_4(camera->distortion_model,
|
||||
float2(camera->pixel_aspect, camera->focal),
|
||||
float2(camera->principal_point),
|
||||
float3(camera->k1, camera->k2, camera->k3));
|
||||
case TRACKING_DISTORTION_MODEL_DIVISION:
|
||||
return get_default_hash_4(camera->distortion_model,
|
||||
float2(camera->pixel_aspect, camera->focal),
|
||||
float2(camera->principal_point),
|
||||
float2(camera->division_k1, camera->division_k2));
|
||||
case TRACKING_DISTORTION_MODEL_NUKE:
|
||||
return get_default_hash_4(camera->distortion_model,
|
||||
float2(camera->pixel_aspect, camera->focal),
|
||||
float2(camera->principal_point),
|
||||
float2(camera->nuke_k1, camera->nuke_k2));
|
||||
case TRACKING_DISTORTION_MODEL_BROWN:
|
||||
return get_default_hash_4(
|
||||
float2(camera->pixel_aspect, camera->focal),
|
||||
float2(camera->principal_point),
|
||||
float4(camera->brown_k1, camera->brown_k2, camera->brown_k3, camera->brown_k4),
|
||||
float2(camera->brown_p1, camera->brown_p2));
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
return 0;
|
||||
}
|
||||
/* --------------------------------------------------------------------
|
||||
* (Un)distortion.
|
||||
*/
|
||||
|
|
|
@ -179,94 +179,98 @@ static void libmv_frame_to_normalized_relative(const float frame_coord[2],
|
|||
/** \name Conversion of markers between Blender's DNA and Libmv.
|
||||
* \{ */
|
||||
|
||||
static void dna_marker_to_libmv_marker(/*const*/ MovieTrackingTrack *track,
|
||||
const MovieTrackingMarker *marker,
|
||||
int clip,
|
||||
int track_index,
|
||||
int frame_width,
|
||||
int frame_height,
|
||||
bool backwards,
|
||||
libmv_Marker *libmv_marker)
|
||||
static libmv_Marker dna_marker_to_libmv_marker(/*const*/ MovieTrackingTrack &track,
|
||||
const MovieTrackingMarker &marker,
|
||||
const int clip,
|
||||
const int track_index,
|
||||
const int frame_width,
|
||||
const int frame_height,
|
||||
const bool backwards)
|
||||
{
|
||||
const int frame_dimensions[2] = {frame_width, frame_height};
|
||||
libmv_marker->clip = clip;
|
||||
libmv_marker->frame = marker->framenr;
|
||||
libmv_marker->track = track_index;
|
||||
libmv_Marker libmv_marker{};
|
||||
|
||||
normalized_to_libmv_frame(marker->pos, frame_dimensions, libmv_marker->center);
|
||||
const int frame_dimensions[2] = {frame_width, frame_height};
|
||||
libmv_marker.clip = clip;
|
||||
libmv_marker.frame = marker.framenr;
|
||||
libmv_marker.track = track_index;
|
||||
|
||||
normalized_to_libmv_frame(marker.pos, frame_dimensions, libmv_marker.center);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
normalized_relative_to_libmv_frame(
|
||||
marker->pattern_corners[i], marker->pos, frame_dimensions, libmv_marker->patch[i]);
|
||||
marker.pattern_corners[i], marker.pos, frame_dimensions, libmv_marker.patch[i]);
|
||||
}
|
||||
|
||||
normalized_relative_to_libmv_frame(
|
||||
marker->search_min, marker->pos, frame_dimensions, libmv_marker->search_region_min);
|
||||
marker.search_min, marker.pos, frame_dimensions, libmv_marker.search_region_min);
|
||||
|
||||
normalized_relative_to_libmv_frame(
|
||||
marker->search_max, marker->pos, frame_dimensions, libmv_marker->search_region_max);
|
||||
marker.search_max, marker.pos, frame_dimensions, libmv_marker.search_region_max);
|
||||
|
||||
/* NOTE: All the markers does have 1.0 weight.
|
||||
* Might support in the future, but will require more elaborated process which will involve
|
||||
* F-Curve evaluation. */
|
||||
libmv_marker->weight = 1.0f;
|
||||
libmv_marker.weight = 1.0f;
|
||||
|
||||
if (marker->flag & MARKER_TRACKED) {
|
||||
libmv_marker->source = LIBMV_MARKER_SOURCE_TRACKED;
|
||||
if (marker.flag & MARKER_TRACKED) {
|
||||
libmv_marker.source = LIBMV_MARKER_SOURCE_TRACKED;
|
||||
}
|
||||
else {
|
||||
libmv_marker->source = LIBMV_MARKER_SOURCE_MANUAL;
|
||||
libmv_marker.source = LIBMV_MARKER_SOURCE_MANUAL;
|
||||
}
|
||||
libmv_marker->status = LIBMV_MARKER_STATUS_UNKNOWN;
|
||||
libmv_marker->model_type = LIBMV_MARKER_MODEL_TYPE_POINT;
|
||||
libmv_marker->model_id = 0;
|
||||
libmv_marker.status = LIBMV_MARKER_STATUS_UNKNOWN;
|
||||
libmv_marker.model_type = LIBMV_MARKER_MODEL_TYPE_POINT;
|
||||
libmv_marker.model_id = 0;
|
||||
|
||||
/* NOTE: We currently don't support reference marker from different clip. */
|
||||
libmv_marker->reference_clip = clip;
|
||||
libmv_marker.reference_clip = clip;
|
||||
|
||||
if (track->pattern_match == TRACK_MATCH_KEYFRAME) {
|
||||
if (track.pattern_match == TRACK_MATCH_KEYFRAME) {
|
||||
const MovieTrackingMarker *keyframe_marker = tracking_get_keyframed_marker(
|
||||
track, marker->framenr, backwards);
|
||||
libmv_marker->reference_frame = keyframe_marker->framenr;
|
||||
&track, marker.framenr, backwards);
|
||||
libmv_marker.reference_frame = keyframe_marker->framenr;
|
||||
}
|
||||
else {
|
||||
libmv_marker->reference_frame = backwards ? marker->framenr - 1 : marker->framenr;
|
||||
libmv_marker.reference_frame = backwards ? marker.framenr - 1 : marker.framenr;
|
||||
}
|
||||
|
||||
libmv_marker->disabled_channels =
|
||||
((track->flag & TRACK_DISABLE_RED) ? LIBMV_MARKER_CHANNEL_R : 0) |
|
||||
((track->flag & TRACK_DISABLE_GREEN) ? LIBMV_MARKER_CHANNEL_G : 0) |
|
||||
((track->flag & TRACK_DISABLE_BLUE) ? LIBMV_MARKER_CHANNEL_B : 0);
|
||||
libmv_marker.disabled_channels =
|
||||
((track.flag & TRACK_DISABLE_RED) ? LIBMV_MARKER_CHANNEL_R : 0) |
|
||||
((track.flag & TRACK_DISABLE_GREEN) ? LIBMV_MARKER_CHANNEL_G : 0) |
|
||||
((track.flag & TRACK_DISABLE_BLUE) ? LIBMV_MARKER_CHANNEL_B : 0);
|
||||
|
||||
return libmv_marker;
|
||||
}
|
||||
|
||||
static void libmv_marker_to_dna_marker(libmv_Marker *libmv_marker,
|
||||
int frame_width,
|
||||
int frame_height,
|
||||
MovieTrackingMarker *marker)
|
||||
static MovieTrackingMarker libmv_marker_to_dna_marker(const libmv_Marker &libmv_marker,
|
||||
const int frame_width,
|
||||
const int frame_height)
|
||||
{
|
||||
const int frame_dimensions[2] = {frame_width, frame_height};
|
||||
marker->framenr = libmv_marker->frame;
|
||||
MovieTrackingMarker marker{};
|
||||
|
||||
libmv_frame_to_normalized(libmv_marker->center, frame_dimensions, marker->pos);
|
||||
const int frame_dimensions[2] = {frame_width, frame_height};
|
||||
marker.framenr = libmv_marker.frame;
|
||||
|
||||
libmv_frame_to_normalized(libmv_marker.center, frame_dimensions, marker.pos);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
libmv_frame_to_normalized_relative(libmv_marker->patch[i],
|
||||
libmv_marker->center,
|
||||
frame_dimensions,
|
||||
marker->pattern_corners[i]);
|
||||
libmv_frame_to_normalized_relative(
|
||||
libmv_marker.patch[i], libmv_marker.center, frame_dimensions, marker.pattern_corners[i]);
|
||||
}
|
||||
|
||||
libmv_frame_to_normalized_relative(
|
||||
libmv_marker->search_region_min, libmv_marker->center, frame_dimensions, marker->search_min);
|
||||
libmv_marker.search_region_min, libmv_marker.center, frame_dimensions, marker.search_min);
|
||||
|
||||
libmv_frame_to_normalized_relative(
|
||||
libmv_marker->search_region_max, libmv_marker->center, frame_dimensions, marker->search_max);
|
||||
libmv_marker.search_region_max, libmv_marker.center, frame_dimensions, marker.search_max);
|
||||
|
||||
marker->flag = 0;
|
||||
if (libmv_marker->source == LIBMV_MARKER_SOURCE_TRACKED) {
|
||||
marker->flag |= MARKER_TRACKED;
|
||||
marker.flag = 0;
|
||||
if (libmv_marker.source == LIBMV_MARKER_SOURCE_TRACKED) {
|
||||
marker.flag |= MARKER_TRACKED;
|
||||
}
|
||||
else {
|
||||
marker->flag &= ~MARKER_TRACKED;
|
||||
marker.flag &= ~MARKER_TRACKED;
|
||||
}
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -279,29 +283,28 @@ static void libmv_marker_to_dna_marker(libmv_Marker *libmv_marker,
|
|||
* \{ */
|
||||
|
||||
/* Returns false if marker crossed margin area from frame bounds. */
|
||||
static bool tracking_check_marker_margin(const libmv_Marker *libmv_marker,
|
||||
int margin,
|
||||
int frame_width,
|
||||
int frame_height)
|
||||
static bool tracking_check_marker_margin(const libmv_Marker &libmv_marker,
|
||||
const int margin,
|
||||
const int frame_width,
|
||||
const int frame_height)
|
||||
{
|
||||
float patch_min[2], patch_max[2];
|
||||
float margin_left, margin_top, margin_right, margin_bottom;
|
||||
|
||||
INIT_MINMAX2(patch_min, patch_max);
|
||||
minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[0]);
|
||||
minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[1]);
|
||||
minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[2]);
|
||||
minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[3]);
|
||||
minmax_v2v2_v2(patch_min, patch_max, libmv_marker.patch[0]);
|
||||
minmax_v2v2_v2(patch_min, patch_max, libmv_marker.patch[1]);
|
||||
minmax_v2v2_v2(patch_min, patch_max, libmv_marker.patch[2]);
|
||||
minmax_v2v2_v2(patch_min, patch_max, libmv_marker.patch[3]);
|
||||
|
||||
margin_left = max_ff(libmv_marker->center[0] - patch_min[0], margin);
|
||||
margin_top = max_ff(patch_max[1] - libmv_marker->center[1], margin);
|
||||
margin_right = max_ff(patch_max[0] - libmv_marker->center[0], margin);
|
||||
margin_bottom = max_ff(libmv_marker->center[1] - patch_min[1], margin);
|
||||
margin_left = max_ff(libmv_marker.center[0] - patch_min[0], margin);
|
||||
margin_top = max_ff(patch_max[1] - libmv_marker.center[1], margin);
|
||||
margin_right = max_ff(patch_max[0] - libmv_marker.center[0], margin);
|
||||
margin_bottom = max_ff(libmv_marker.center[1] - patch_min[1], margin);
|
||||
|
||||
if (libmv_marker->center[0] < margin_left ||
|
||||
libmv_marker->center[0] > frame_width - margin_right ||
|
||||
libmv_marker->center[1] < margin_bottom ||
|
||||
libmv_marker->center[1] > frame_height - margin_top)
|
||||
if (libmv_marker.center[0] < margin_left ||
|
||||
libmv_marker.center[0] > frame_width - margin_right ||
|
||||
libmv_marker.center[1] < margin_bottom || libmv_marker.center[1] > frame_height - margin_top)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -315,9 +318,9 @@ static bool tracking_check_marker_margin(const libmv_Marker *libmv_marker,
|
|||
/** \name Auto-Track Context Initialization
|
||||
* \{ */
|
||||
|
||||
static bool autotrack_is_marker_usable(const MovieTrackingMarker *marker)
|
||||
static bool autotrack_is_marker_usable(const MovieTrackingMarker &marker)
|
||||
{
|
||||
if (marker->flag & MARKER_DISABLED) {
|
||||
if (marker.flag & MARKER_DISABLED) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -334,7 +337,7 @@ static bool autotrack_is_track_trackable(const AutoTrackContext *context,
|
|||
clip, context->start_scene_frame);
|
||||
|
||||
const MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame_number);
|
||||
return autotrack_is_marker_usable(marker);
|
||||
return autotrack_is_marker_usable(*marker);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -430,7 +433,7 @@ static size_t autotrack_count_all_usable_markers(AutoTrackContext *context)
|
|||
for (int track_index = 0; track_index < context->num_all_tracks; ++track_index) {
|
||||
const MovieTrackingTrack *track = context->all_autotrack_tracks[track_index].track;
|
||||
for (int marker_index = 0; marker_index < track->markersnr; ++marker_index) {
|
||||
const MovieTrackingMarker *marker = &track->markers[marker_index];
|
||||
const MovieTrackingMarker &marker = track->markers[marker_index];
|
||||
if (!autotrack_is_marker_usable(marker)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -475,21 +478,21 @@ static void autotrack_context_init_autotrack(AutoTrackContext *context)
|
|||
int num_filled_libmv_markers = 0;
|
||||
for (int track_index = 0; track_index < context->num_all_tracks; ++track_index) {
|
||||
const AutoTrackTrack *autotrack_track = &context->all_autotrack_tracks[track_index];
|
||||
/*const*/ MovieTrackingTrack *track = autotrack_track->track;
|
||||
for (int marker_index = 0; marker_index < track->markersnr; ++marker_index) {
|
||||
/*const*/ MovieTrackingMarker *marker = &track->markers[marker_index];
|
||||
/*const*/ MovieTrackingTrack &track = *autotrack_track->track;
|
||||
for (int marker_index = 0; marker_index < track.markersnr; ++marker_index) {
|
||||
/*const*/ MovieTrackingMarker &marker = track.markers[marker_index];
|
||||
if (!autotrack_is_marker_usable(marker)) {
|
||||
continue;
|
||||
}
|
||||
const AutoTrackClip *autotrack_clip = &context->autotrack_clips[autotrack_track->clip_index];
|
||||
dna_marker_to_libmv_marker(track,
|
||||
marker,
|
||||
autotrack_track->clip_index,
|
||||
track_index,
|
||||
autotrack_clip->width,
|
||||
autotrack_clip->height,
|
||||
context->is_backwards,
|
||||
&libmv_markers[num_filled_libmv_markers++]);
|
||||
libmv_markers[num_filled_libmv_markers++] = dna_marker_to_libmv_marker(
|
||||
track,
|
||||
marker,
|
||||
autotrack_track->clip_index,
|
||||
track_index,
|
||||
autotrack_clip->width,
|
||||
autotrack_clip->height,
|
||||
context->is_backwards);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -525,18 +528,17 @@ static void autotrack_context_init_markers(AutoTrackContext *context)
|
|||
const int clip_frame_number = BKE_movieclip_remap_scene_to_clip_frame(
|
||||
clip, context->start_scene_frame);
|
||||
|
||||
/*const*/ MovieTrackingTrack *track = context->all_autotrack_tracks[track_index].track;
|
||||
const MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame_number);
|
||||
/*const*/ MovieTrackingTrack &track = *context->all_autotrack_tracks[track_index].track;
|
||||
const MovieTrackingMarker &marker = *BKE_tracking_marker_get(&track, clip_frame_number);
|
||||
|
||||
AutoTrackMarker *autotrack_marker = &context->autotrack_markers[autotrack_marker_index++];
|
||||
dna_marker_to_libmv_marker(track,
|
||||
marker,
|
||||
autotrack_track->clip_index,
|
||||
track_index,
|
||||
autotrack_clip->width,
|
||||
autotrack_clip->height,
|
||||
context->is_backwards,
|
||||
&autotrack_marker->libmv_marker);
|
||||
autotrack_marker->libmv_marker = dna_marker_to_libmv_marker(track,
|
||||
marker,
|
||||
autotrack_track->clip_index,
|
||||
track_index,
|
||||
autotrack_clip->width,
|
||||
autotrack_clip->height,
|
||||
context->is_backwards);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,35 +635,35 @@ static void autotrack_context_step_cb(void *__restrict userdata,
|
|||
AutoTrackContext *context = static_cast<AutoTrackContext *>(userdata);
|
||||
AutoTrackTLS *autotrack_tls = (AutoTrackTLS *)tls->userdata_chunk;
|
||||
|
||||
const AutoTrackMarker *autotrack_marker = &context->autotrack_markers[marker_index];
|
||||
const libmv_Marker *libmv_current_marker = &autotrack_marker->libmv_marker;
|
||||
const AutoTrackMarker &autotrack_marker = context->autotrack_markers[marker_index];
|
||||
const libmv_Marker &libmv_current_marker = autotrack_marker.libmv_marker;
|
||||
|
||||
const int frame_delta = context->is_backwards ? -1 : 1;
|
||||
const int clip_index = libmv_current_marker->clip;
|
||||
const int track_index = libmv_current_marker->track;
|
||||
const int clip_index = libmv_current_marker.clip;
|
||||
const int track_index = libmv_current_marker.track;
|
||||
|
||||
const AutoTrackClip *autotrack_clip = &context->autotrack_clips[clip_index];
|
||||
const AutoTrackTrack *autotrack_track = &context->all_autotrack_tracks[track_index];
|
||||
const MovieTrackingTrack *track = autotrack_track->track;
|
||||
const AutoTrackClip &autotrack_clip = context->autotrack_clips[clip_index];
|
||||
const AutoTrackTrack &autotrack_track = context->all_autotrack_tracks[track_index];
|
||||
const MovieTrackingTrack &track = *autotrack_track.track;
|
||||
|
||||
/* Check whether marker is going outside of allowed frame margin. */
|
||||
if (!tracking_check_marker_margin(
|
||||
libmv_current_marker, track->margin, autotrack_clip->width, autotrack_clip->height))
|
||||
libmv_current_marker, track.margin, autotrack_clip.width, autotrack_clip.height))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int new_marker_frame = libmv_current_marker->frame + frame_delta;
|
||||
const int new_marker_frame = libmv_current_marker.frame + frame_delta;
|
||||
|
||||
AutoTrackTrackingResult *autotrack_result = MEM_cnew<AutoTrackTrackingResult>(
|
||||
"autotrack result");
|
||||
autotrack_result->libmv_marker = *libmv_current_marker;
|
||||
autotrack_result->libmv_marker = libmv_current_marker;
|
||||
autotrack_result->libmv_marker.frame = new_marker_frame;
|
||||
|
||||
/* Update reference frame. */
|
||||
libmv_Marker libmv_reference_marker;
|
||||
if (track->pattern_match == TRACK_MATCH_KEYFRAME) {
|
||||
autotrack_result->libmv_marker.reference_frame = libmv_current_marker->reference_frame;
|
||||
if (track.pattern_match == TRACK_MATCH_KEYFRAME) {
|
||||
autotrack_result->libmv_marker.reference_frame = libmv_current_marker.reference_frame;
|
||||
libmv_autoTrackGetMarker(context->autotrack,
|
||||
clip_index,
|
||||
autotrack_result->libmv_marker.reference_frame,
|
||||
|
@ -669,14 +671,14 @@ static void autotrack_context_step_cb(void *__restrict userdata,
|
|||
&libmv_reference_marker);
|
||||
}
|
||||
else {
|
||||
BLI_assert(track->pattern_match == TRACK_MATCH_PREVIOS_FRAME);
|
||||
autotrack_result->libmv_marker.reference_frame = libmv_current_marker->frame;
|
||||
libmv_reference_marker = *libmv_current_marker;
|
||||
BLI_assert(track.pattern_match == TRACK_MATCH_PREVIOUS_FRAME);
|
||||
autotrack_result->libmv_marker.reference_frame = libmv_current_marker.frame;
|
||||
libmv_reference_marker = libmv_current_marker;
|
||||
}
|
||||
|
||||
/* Perform actual tracking. */
|
||||
autotrack_result->success = libmv_autoTrackMarker(context->autotrack,
|
||||
&autotrack_track->track_region_options,
|
||||
&autotrack_track.track_region_options,
|
||||
&autotrack_result->libmv_marker,
|
||||
&autotrack_result->libmv_result);
|
||||
|
||||
|
@ -684,7 +686,7 @@ static void autotrack_context_step_cb(void *__restrict userdata,
|
|||
* This is how Blender side is currently expecting failed track to be handled. Without this the
|
||||
* marker is left in an arbitrary position which did not provide good correlation. */
|
||||
if (!autotrack_result->success) {
|
||||
autotrack_result->libmv_marker = *libmv_current_marker;
|
||||
autotrack_result->libmv_marker = libmv_current_marker;
|
||||
autotrack_result->libmv_marker.frame = new_marker_frame;
|
||||
}
|
||||
|
||||
|
@ -768,22 +770,21 @@ void BKE_autotrack_context_sync(AutoTrackContext *context)
|
|||
BLI_spin_unlock(&context->spin_lock);
|
||||
|
||||
LISTBASE_FOREACH_MUTABLE (AutoTrackTrackingResult *, autotrack_result, &results_to_sync) {
|
||||
const libmv_Marker *libmv_marker = &autotrack_result->libmv_marker;
|
||||
const int clip_index = libmv_marker->clip;
|
||||
const int track_index = libmv_marker->track;
|
||||
const AutoTrackClip *autotrack_clip = &context->autotrack_clips[clip_index];
|
||||
const MovieClip *clip = autotrack_clip->clip;
|
||||
const AutoTrackTrack *autotrack_track = &context->all_autotrack_tracks[track_index];
|
||||
MovieTrackingTrack *track = autotrack_track->track;
|
||||
const libmv_Marker &libmv_marker = autotrack_result->libmv_marker;
|
||||
const int clip_index = libmv_marker.clip;
|
||||
const int track_index = libmv_marker.track;
|
||||
const AutoTrackClip &autotrack_clip = context->autotrack_clips[clip_index];
|
||||
const MovieClip *clip = autotrack_clip.clip;
|
||||
const AutoTrackTrack &autotrack_track = context->all_autotrack_tracks[track_index];
|
||||
MovieTrackingTrack *track = autotrack_track.track;
|
||||
|
||||
const int start_clip_frame = BKE_movieclip_remap_scene_to_clip_frame(
|
||||
clip, context->start_scene_frame);
|
||||
const int first_result_frame = start_clip_frame + frame_delta;
|
||||
|
||||
/* Insert marker which corresponds to the tracking result. */
|
||||
MovieTrackingMarker marker;
|
||||
libmv_marker_to_dna_marker(
|
||||
&autotrack_result->libmv_marker, autotrack_clip->width, autotrack_clip->height, &marker);
|
||||
MovieTrackingMarker marker = libmv_marker_to_dna_marker(
|
||||
autotrack_result->libmv_marker, autotrack_clip.width, autotrack_clip.height);
|
||||
if (!autotrack_result->success) {
|
||||
marker.flag |= MARKER_DISABLED;
|
||||
}
|
||||
|
|
|
@ -205,8 +205,8 @@ eFileAttributes BLI_file_attributes(const char *path);
|
|||
* Usage of this function is strongly discouraged as it is not thread safe. It will likely cause
|
||||
* issues if there is an operation on another thread that does not expect the current working
|
||||
* directory to change. This has been added to support USDZ export, which has a problematic
|
||||
* "feature" described in this issue https://projects.blender.org/blender/blender/issues/99807. It
|
||||
* will be removed if it is possible to resolve that issue upstream in the USD library.
|
||||
* "feature" described in this issue #99807. It will be removed if it is possible to resolve
|
||||
* that issue upstream in the USD library.
|
||||
*
|
||||
* \return true on success, false otherwise.
|
||||
*/
|
||||
|
|
|
@ -91,6 +91,11 @@ template<typename T> inline T floor(const T &a)
|
|||
return std::floor(a);
|
||||
}
|
||||
|
||||
template<typename T> inline T round(const T &a)
|
||||
{
|
||||
return std::round(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats the saw-tooth pattern even on negative numbers.
|
||||
* ex: `mod_periodic(-3, 4) = 1`, `mod(-3, 4)= -3`
|
||||
|
@ -127,6 +132,20 @@ template<typename T> inline T sqrt(const T &a)
|
|||
return std::sqrt(a);
|
||||
}
|
||||
|
||||
/* Inverse value.
|
||||
* If the input is zero the output is NaN. */
|
||||
template<typename T> inline T rcp(const T &a)
|
||||
{
|
||||
return T(1) / a;
|
||||
}
|
||||
|
||||
/* Inverse value.
|
||||
* If the input is zero the output is zero. */
|
||||
template<typename T> inline T safe_rcp(const T &a)
|
||||
{
|
||||
return a ? T(1) / a : T(0);
|
||||
}
|
||||
|
||||
template<typename T> inline T cos(const T &a)
|
||||
{
|
||||
return std::cos(a);
|
||||
|
|
|
@ -111,7 +111,7 @@ template<typename T, int Size>
|
|||
{
|
||||
VecBase<T, Size> result = a;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = std::clamp(result[i], min[i], max[i]);
|
||||
result[i] = math::clamp(result[i], min[i], max[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ template<typename T, int Size>
|
|||
{
|
||||
VecBase<T, Size> result = a;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = std::clamp(result[i], min, max);
|
||||
result[i] = math::clamp(result[i], min, max);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ template<typename T, int Size>
|
|||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
BLI_assert(b[i] != 0);
|
||||
result[i] = std::fmod(a[i], b[i]);
|
||||
result[i] = math::mod(a[i], b[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ template<typename T, int Size>
|
|||
BLI_assert(b != 0);
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = std::fmod(a[i], b);
|
||||
result[i] = math::mod(a[i], b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ template<typename T, int Size>
|
|||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = (b[i] != 0) ? std::fmod(a[i], b[i]) : 0;
|
||||
result[i] = (b[i] != 0) ? math::mod(a[i], b[i]) : 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ template<typename T, int Size>
|
|||
}
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = std::fmod(a[i], b);
|
||||
result[i] = math::mod(a[i], b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ template<typename T, int Size>
|
|||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = std::pow(x[i], y);
|
||||
result[i] = math::pow(x[i], y);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ template<typename T, int Size>
|
|||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = std::pow(x[i], y[i]);
|
||||
result[i] = math::pow(x[i], y[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ template<typename T, int Size>
|
|||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = std::floor(a[i]);
|
||||
result[i] = math::floor(a[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ template<typename T, int Size>
|
|||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = std::round(a[i]);
|
||||
result[i] = math::round(a[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -296,7 +296,62 @@ template<typename T, int Size>
|
|||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = std::ceil(a[i]);
|
||||
result[i] = math::ceil(a[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Per-element square root.
|
||||
* Negative elements are evaluated to NaN.
|
||||
*/
|
||||
template<typename T, int Size>
|
||||
[[nodiscard]] inline VecBase<T, Size> sqrt(const VecBase<T, Size> &a)
|
||||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = math::sqrt(a[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Per-element square root.
|
||||
* Negative elements are evaluated to zero.
|
||||
*/
|
||||
template<typename T, int Size>
|
||||
[[nodiscard]] inline VecBase<T, Size> safe_sqrt(const VecBase<T, Size> &a)
|
||||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = a[i] >= T(0) ? math ::sqrt(a[i]) : T(0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Per-element inverse.
|
||||
* Zero elements are evaluated to NaN.
|
||||
*/
|
||||
template<typename T, int Size> [[nodiscard]] inline VecBase<T, Size> rcp(const VecBase<T, Size> &a)
|
||||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = math::rcp(a[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Per-element inverse.
|
||||
* Zero elements are evaluated to zero.
|
||||
*/
|
||||
template<typename T, int Size>
|
||||
[[nodiscard]] inline VecBase<T, Size> safe_rcp(const VecBase<T, Size> &a)
|
||||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = math::safe_rcp(a[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -306,7 +361,7 @@ template<typename T, int Size>
|
|||
{
|
||||
VecBase<T, Size> result;
|
||||
for (int i = 0; i < Size; i++) {
|
||||
result[i] = a[i] - std::floor(a[i]);
|
||||
result[i] = math::fract(a[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -332,9 +387,9 @@ template<typename T, int Size>
|
|||
*/
|
||||
template<typename T, int Size> [[nodiscard]] inline T length_manhattan(const VecBase<T, Size> &a)
|
||||
{
|
||||
T result = std::abs(a[0]);
|
||||
T result = math::abs(a[0]);
|
||||
for (int i = 1; i < Size; i++) {
|
||||
result += std::abs(a[i]);
|
||||
result += math::abs(a[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -346,7 +401,7 @@ template<typename T, int Size> [[nodiscard]] inline T length_squared(const VecBa
|
|||
|
||||
template<typename T, int Size> [[nodiscard]] inline T length(const VecBase<T, Size> &a)
|
||||
{
|
||||
return std::sqrt(length_squared(a));
|
||||
return math::sqrt(length_squared(a));
|
||||
}
|
||||
|
||||
/** Return true if each individual column is unit scaled. Mainly for assert usage. */
|
||||
|
@ -356,8 +411,8 @@ template<typename T, int Size> [[nodiscard]] inline bool is_unit_scale(const Vec
|
|||
* normalized and in the case we don't want NAN to be raising asserts since there
|
||||
* is nothing to be done in that case. */
|
||||
const T test_unit = math::length_squared(v);
|
||||
return (!(std::abs(test_unit - T(1)) >= AssertUnitEpsilon<T>::value) ||
|
||||
!(std::abs(test_unit) >= AssertUnitEpsilon<T>::value));
|
||||
return (!(math::abs(test_unit - T(1)) >= AssertUnitEpsilon<T>::value) ||
|
||||
!(math::abs(test_unit) >= AssertUnitEpsilon<T>::value));
|
||||
}
|
||||
|
||||
template<typename T, int Size>
|
||||
|
@ -593,7 +648,7 @@ template<typename T, int Size>
|
|||
const T epsilon = T(0))
|
||||
{
|
||||
for (int i = 0; i < Size; i++) {
|
||||
if (std::abs(a[i] - b[i]) > epsilon) {
|
||||
if (math::abs(a[i] - b[i]) > epsilon) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ static float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], int
|
|||
i_prev = i;
|
||||
}
|
||||
|
||||
return (area_best != FLT_MAX) ? atan2f(dvec_best[0], dvec_best[1]) : 0.0f;
|
||||
return (area_best != FLT_MAX) ? (float)atan2(dvec_best[0], dvec_best[1]) : 0.0f;
|
||||
}
|
||||
|
||||
float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], int n)
|
||||
|
|
|
@ -136,4 +136,40 @@ TEST(math_vector, Sign)
|
|||
EXPECT_FLOAT_EQ(result.z, 0);
|
||||
}
|
||||
|
||||
TEST(math_vector, sqrt)
|
||||
{
|
||||
const float3 a(1.0f, 4.0f, 9.0f);
|
||||
const float3 result = math::sqrt(a);
|
||||
EXPECT_NEAR(result.x, 1.0f, 1e-6f);
|
||||
EXPECT_NEAR(result.y, 2.0f, 1e-6f);
|
||||
EXPECT_NEAR(result.z, 3.0f, 1e-6f);
|
||||
}
|
||||
|
||||
TEST(math_vector, safe_sqrt)
|
||||
{
|
||||
const float3 a(1.0f, -4.0f, 9.0f);
|
||||
const float3 result = math::safe_sqrt(a);
|
||||
EXPECT_NEAR(result.x, 1.0f, 1e-6f);
|
||||
EXPECT_NEAR(result.y, 0.0f, 1e-6f);
|
||||
EXPECT_NEAR(result.z, 3.0f, 1e-6f);
|
||||
}
|
||||
|
||||
TEST(math_vector, rcp)
|
||||
{
|
||||
const float3 a(1.0f, 2.0f, 4.0f);
|
||||
const float3 result = math::rcp(a);
|
||||
EXPECT_NEAR(result.x, 1.0f, 1e-6f);
|
||||
EXPECT_NEAR(result.y, 0.5f, 1e-6f);
|
||||
EXPECT_NEAR(result.z, 0.25f, 1e-6f);
|
||||
}
|
||||
|
||||
TEST(math_vector, safe_rcp)
|
||||
{
|
||||
const float3 a(1.0f, 0.0f, 4.0f);
|
||||
const float3 result = math::safe_rcp(a);
|
||||
EXPECT_NEAR(result.x, 1.0f, 1e-6f);
|
||||
EXPECT_NEAR(result.y, 0.0f, 1e-6f);
|
||||
EXPECT_NEAR(result.z, 0.25f, 1e-6f);
|
||||
}
|
||||
|
||||
} // namespace blender::tests
|
||||
|
|
|
@ -47,8 +47,8 @@ typedef struct WorkspaceConfigFileData {
|
|||
|
||||
typedef enum eBlenFileType {
|
||||
BLENFILETYPE_BLEND = 1,
|
||||
/* BLENFILETYPE_PUB = 2, */ /* UNUSED */
|
||||
/* BLENFILETYPE_RUNTIME = 3, */ /* UNUSED */
|
||||
// BLENFILETYPE_PUB = 2, /* UNUSED */
|
||||
// BLENFILETYPE_RUNTIME = 3, /* UNUSED */
|
||||
} eBlenFileType;
|
||||
|
||||
typedef struct BlendFileData {
|
||||
|
@ -59,17 +59,24 @@ typedef struct BlendFileData {
|
|||
int globalf;
|
||||
char filepath[1024]; /* 1024 = FILE_MAX */
|
||||
|
||||
struct bScreen *curscreen; /* TODO: think this isn't needed anymore? */
|
||||
/** TODO: think this isn't needed anymore? */
|
||||
struct bScreen *curscreen;
|
||||
struct Scene *curscene;
|
||||
struct ViewLayer *cur_view_layer; /* layer to activate in workspaces when reading without UI */
|
||||
/** Layer to activate in workspaces when reading without UI. */
|
||||
struct ViewLayer *cur_view_layer;
|
||||
|
||||
eBlenFileType type;
|
||||
} BlendFileData;
|
||||
|
||||
/** Data used by WM readfile code and BKE's setup_app_data to handle the complex preservation logic
|
||||
* of WindowManager and other UI data-blocks across blendfile reading prcess. */
|
||||
/**
|
||||
* Data used by WM readfile code and BKE's setup_app_data to handle the complex preservation logic
|
||||
* of WindowManager and other UI data-blocks across blend-file reading process.
|
||||
*/
|
||||
typedef struct BlendFileReadWMSetupData {
|
||||
struct wmWindowManager *old_wm; /** The existing WM when filereading process is started. */
|
||||
/** The existing WM when filereading process is started. */
|
||||
struct wmWindowManager *old_wm;
|
||||
|
||||
bool is_read_homefile;
|
||||
} BlendFileReadWMSetupData;
|
||||
|
||||
struct BlendFileReadParams {
|
||||
|
@ -81,10 +88,10 @@ struct BlendFileReadParams {
|
|||
};
|
||||
|
||||
typedef struct BlendFileReadReport {
|
||||
/* General reports handling. */
|
||||
/** General reports handling. */
|
||||
struct ReportList *reports;
|
||||
|
||||
/* Timing information. */
|
||||
/** Timing information. */
|
||||
struct {
|
||||
double whole;
|
||||
double libraries;
|
||||
|
@ -93,38 +100,44 @@ typedef struct BlendFileReadReport {
|
|||
double lib_overrides_recursive_resync;
|
||||
} duration;
|
||||
|
||||
/* Count information. */
|
||||
/** Count information. */
|
||||
struct {
|
||||
/* Some numbers of IDs that ended up in a specific state, or required some specific process
|
||||
* during this file read. */
|
||||
/**
|
||||
* Some numbers of IDs that ended up in a specific state, or required some specific process
|
||||
* during this file read.
|
||||
*/
|
||||
int missing_libraries;
|
||||
int missing_linked_id;
|
||||
/* Some sub-categories of the above `missing_linked_id` counter. */
|
||||
/** Some sub-categories of the above `missing_linked_id` counter. */
|
||||
int missing_obdata;
|
||||
int missing_obproxies;
|
||||
|
||||
/* Number of root override IDs that were resynced. */
|
||||
/** Number of root override IDs that were resynced. */
|
||||
int resynced_lib_overrides;
|
||||
|
||||
/* Number of proxies converted to library overrides. */
|
||||
/** Number of proxies converted to library overrides. */
|
||||
int proxies_to_lib_overrides_success;
|
||||
/* Number of proxies that failed to convert to library overrides. */
|
||||
/** Number of proxies that failed to convert to library overrides. */
|
||||
int proxies_to_lib_overrides_failures;
|
||||
/* Number of sequencer strips that were not read because were in non-supported channels. */
|
||||
/** Number of sequencer strips that were not read because were in non-supported channels. */
|
||||
int sequence_strips_skipped;
|
||||
} count;
|
||||
|
||||
/* Number of libraries which had overrides that needed to be resynced, and a single linked list
|
||||
* of those. */
|
||||
/**
|
||||
* Number of libraries which had overrides that needed to be resynced,
|
||||
* and a single linked list of those.
|
||||
*/
|
||||
int resynced_lib_overrides_libraries_count;
|
||||
bool do_resynced_lib_overrides_libraries_list;
|
||||
struct LinkNode *resynced_lib_overrides_libraries;
|
||||
} BlendFileReadReport;
|
||||
|
||||
/* skip reading some data-block types (may want to skip screen data too). */
|
||||
/** Skip reading some data-block types (may want to skip screen data too). */
|
||||
typedef enum eBLOReadSkip {
|
||||
BLO_READ_SKIP_NONE = 0,
|
||||
/** Skip #BLO_CODE_USER blocks. */
|
||||
BLO_READ_SKIP_USERDEF = (1 << 0),
|
||||
/** Only read #BLO_CODE_USER (and associated data). */
|
||||
BLO_READ_SKIP_DATA = (1 << 1),
|
||||
/** Do not attempt to re-use IDs from old bmain for unchanged ones in case of undo. */
|
||||
BLO_READ_SKIP_UNDO_OLD_MAIN = (1 << 2),
|
||||
|
@ -133,7 +146,7 @@ ENUM_OPERATORS(eBLOReadSkip, BLO_READ_SKIP_UNDO_OLD_MAIN)
|
|||
#define BLO_READ_SKIP_ALL (BLO_READ_SKIP_USERDEF | BLO_READ_SKIP_DATA)
|
||||
|
||||
/**
|
||||
* Open a blender file from a pathname. The function returns NULL
|
||||
* Open a blender file from a `filepath`. The function returns NULL
|
||||
* and sets a report in the list if it cannot open the file.
|
||||
*
|
||||
* \param filepath: The path of the file to open.
|
||||
|
@ -189,10 +202,12 @@ typedef struct BLODataBlockInfo {
|
|||
char name[64]; /* MAX_NAME */
|
||||
struct AssetMetaData *asset_data;
|
||||
bool free_asset_data;
|
||||
/* Optimization: Tag data-blocks for which we know there is no preview.
|
||||
/**
|
||||
* Optimization: Tag data-blocks for which we know there is no preview.
|
||||
* Knowing this can be used to skip the (potentially expensive) preview loading process. If this
|
||||
* is set to true it means we looked for a preview and couldn't find one. False may mean that
|
||||
* either no preview was found, or that it wasn't looked for in the first place. */
|
||||
* either no preview was found, or that it wasn't looked for in the first place.
|
||||
*/
|
||||
bool no_preview_found;
|
||||
} BLODataBlockInfo;
|
||||
|
||||
|
@ -336,9 +351,11 @@ typedef enum eBLOLibLinkFlags {
|
|||
BLO_LIBLINK_FORCE_INDIRECT = 1 << 17,
|
||||
/** Set fake user on appended IDs. */
|
||||
BLO_LIBLINK_APPEND_SET_FAKEUSER = 1 << 19,
|
||||
/** Append (make local) also indirect dependencies of appended IDs coming from other libraries.
|
||||
/**
|
||||
* Append (make local) also indirect dependencies of appended IDs coming from other libraries.
|
||||
* NOTE: All IDs (including indirectly linked ones) coming from the same initial library are
|
||||
* always made local. */
|
||||
* always made local.
|
||||
*/
|
||||
BLO_LIBLINK_APPEND_RECURSIVE = 1 << 20,
|
||||
/** Try to re-use previously appended matching ID on new append. */
|
||||
BLO_LIBLINK_APPEND_LOCAL_ID_REUSE = 1 << 21,
|
||||
|
@ -437,7 +454,7 @@ typedef struct TempLibraryContext {
|
|||
struct LibraryLink_Params liblink_params;
|
||||
struct Library *lib;
|
||||
|
||||
/* The ID datablock that was loaded. Is NULL if loading failed. */
|
||||
/** The ID datablock that was loaded. Is NULL if loading failed. */
|
||||
struct ID *temp_id;
|
||||
} TempLibraryContext;
|
||||
|
||||
|
@ -485,7 +502,7 @@ void BLO_expand_main(void *fdhandle, struct Main *mainvar);
|
|||
void BLO_update_defaults_startup_blend(struct Main *bmain, const char *app_template);
|
||||
void BLO_update_defaults_workspace(struct WorkSpace *workspace, const char *app_template);
|
||||
|
||||
/* Disable unwanted experimental feature settings on startup. */
|
||||
/** Disable unwanted experimental feature settings on startup. */
|
||||
void BLO_sanitize_experimental_features_userpref_blend(struct UserDef *userdef);
|
||||
|
||||
/**
|
||||
|
@ -498,8 +515,9 @@ void BLO_sanitize_experimental_features_userpref_blend(struct UserDef *userdef);
|
|||
*/
|
||||
struct BlendThumbnail *BLO_thumbnail_from_file(const char *filepath);
|
||||
|
||||
/* datafiles (generated theme) */
|
||||
/** Default theme, see: `release/datafiles/userdef/userdef_default_theme.c`. */
|
||||
extern const struct bTheme U_theme_default;
|
||||
/** Default preferences, defined by: `release/datafiles/userdef/userdef_default.c`. */
|
||||
extern const struct UserDef U_default;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
* - read associated 'direct data'
|
||||
* - link direct data (internal and to LibBlock)
|
||||
* - read #FileGlobal
|
||||
* - read #USER data, only when indicated (file is `~/.config/blender/X.XX/config/userpref.blend`)
|
||||
* - read #USER data, only when indicated (file is `~/.config/blender/X.X/config/userpref.blend`)
|
||||
* - free file
|
||||
* - per Library (per #Main)
|
||||
* - read file
|
||||
|
|
|
@ -206,7 +206,7 @@ bool BLO_memfile_write_file(MemFile *memfile, const char *filepath)
|
|||
MemFileChunk *chunk;
|
||||
int file, oflags;
|
||||
|
||||
/* NOTE: This is currently used for autosave and 'quit.blend',
|
||||
/* NOTE: This is currently used for auto-save and `quit.blend`,
|
||||
* where _not_ following symlinks is OK,
|
||||
* however if this is ever executed explicitly by the user,
|
||||
* we may want to allow writing to symlinks.
|
||||
|
|
|
@ -2184,46 +2184,6 @@ static void versioning_replace_legacy_mix_rgb_node(bNodeTree *ntree)
|
|||
}
|
||||
}
|
||||
|
||||
static void versioning_replace_legacy_glossy_node(bNodeTree *ntree)
|
||||
{
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
if (node->type == SH_NODE_BSDF_GLOSSY_LEGACY) {
|
||||
strcpy(node->idname, "ShaderNodeBsdfAnisotropic");
|
||||
node->type = SH_NODE_BSDF_GLOSSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void versioning_remove_microfacet_sharp_distribution(bNodeTree *ntree)
|
||||
{
|
||||
/* Find all glossy, glass and refraction BSDF nodes that have their distribution
|
||||
* set to SHARP and set them to GGX, disconnect any link to the Roughness input
|
||||
* and set its value to zero. */
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
if (!ELEM(node->type, SH_NODE_BSDF_GLOSSY, SH_NODE_BSDF_GLASS, SH_NODE_BSDF_REFRACTION)) {
|
||||
continue;
|
||||
}
|
||||
if (node->custom1 != SHD_GLOSSY_SHARP_DEPRECATED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
node->custom1 = SHD_GLOSSY_GGX;
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
|
||||
if (!STREQ(socket->identifier, "Roughness")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (socket->link != nullptr) {
|
||||
nodeRemLink(ntree, socket->link);
|
||||
}
|
||||
bNodeSocketValueFloat *socket_value = (bNodeSocketValueFloat *)socket->default_value;
|
||||
socket_value->value = 0.0f;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void version_fix_image_format_copy(Main *bmain, ImageFormatData *format)
|
||||
{
|
||||
/* Fix bug where curves in image format were not properly copied to file output
|
||||
|
@ -4461,26 +4421,8 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
* \note Be sure to check when bumping the version:
|
||||
* - "versioning_userdef.c", #blo_do_versions_userdef
|
||||
* - "versioning_userdef.c", #do_versions_theme
|
||||
*
|
||||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
|
||||
/* Convert anisotropic BSDF node to glossy BSDF. */
|
||||
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
||||
versioning_replace_legacy_glossy_node(ntree);
|
||||
versioning_remove_microfacet_sharp_distribution(ntree);
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
|
||||
BKE_animdata_main_cb(bmain, version_liboverride_nla_frame_start_end, nullptr);
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 306, 11)) {
|
||||
BKE_animdata_main_cb(bmain, version_liboverride_nla_frame_start_end, NULL);
|
||||
|
||||
/* Store simulation bake directory in geometry nodes modifier. */
|
||||
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
||||
|
@ -4519,4 +4461,18 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
* \note Be sure to check when bumping the version:
|
||||
* - #do_versions_after_linking_300 in this file.
|
||||
* - "versioning_userdef.c", #blo_do_versions_userdef
|
||||
* - "versioning_userdef.c", #do_versions_theme
|
||||
*
|
||||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,9 +29,23 @@
|
|||
|
||||
// static CLG_LogRef LOG = {"blo.readfile.doversion"};
|
||||
|
||||
void do_versions_after_linking_400(FileData * /*fd*/, Main *bmain)
|
||||
void do_versions_after_linking_400(FileData * /*fd*/, Main * /*bmain*/)
|
||||
{
|
||||
UNUSED_VARS(bmain);
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
* \note Be sure to check when bumping the version:
|
||||
* - #blo_do_versions_400 in this file.
|
||||
* - "versioning_cycles.cc", #blo_do_versions_cycles
|
||||
* - "versioning_cycles.cc", #do_versions_after_linking_cycles
|
||||
* - "versioning_userdef.c", #blo_do_versions_userdef
|
||||
* - "versioning_userdef.c", #do_versions_theme
|
||||
*
|
||||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
}
|
||||
}
|
||||
|
||||
static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh)
|
||||
|
@ -101,6 +115,46 @@ static void version_geometry_nodes_add_realize_instance_nodes(bNodeTree *ntree)
|
|||
}
|
||||
}
|
||||
|
||||
static void versioning_replace_legacy_glossy_node(bNodeTree *ntree)
|
||||
{
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
if (node->type == SH_NODE_BSDF_GLOSSY_LEGACY) {
|
||||
strcpy(node->idname, "ShaderNodeBsdfAnisotropic");
|
||||
node->type = SH_NODE_BSDF_GLOSSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void versioning_remove_microfacet_sharp_distribution(bNodeTree *ntree)
|
||||
{
|
||||
/* Find all glossy, glass and refraction BSDF nodes that have their distribution
|
||||
* set to SHARP and set them to GGX, disconnect any link to the Roughness input
|
||||
* and set its value to zero. */
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
if (!ELEM(node->type, SH_NODE_BSDF_GLOSSY, SH_NODE_BSDF_GLASS, SH_NODE_BSDF_REFRACTION)) {
|
||||
continue;
|
||||
}
|
||||
if (node->custom1 != SHD_GLOSSY_SHARP_DEPRECATED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
node->custom1 = SHD_GLOSSY_GGX;
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
|
||||
if (!STREQ(socket->identifier, "Roughness")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (socket->link != nullptr) {
|
||||
nodeRemLink(ntree, socket->link);
|
||||
}
|
||||
bNodeSocketValueFloat *socket_value = (bNodeSocketValueFloat *)socket->default_value;
|
||||
socket_value->value = 0.0f;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
|
||||
{
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 400, 1)) {
|
||||
|
@ -124,16 +178,38 @@ void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
/* 400 4 did not require any do_version here. */
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 400, 5)) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
#define SCE_SNAP_PROJECT (1 << 3)
|
||||
if (scene->toolsettings->snap_flag & SCE_SNAP_PROJECT) {
|
||||
scene->toolsettings->snap_mode |= SCE_SNAP_MODE_FACE_RAYCAST;
|
||||
}
|
||||
#undef SCE_SNAP_PROJECT
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
* \note Be sure to check when bumping the version:
|
||||
* - #do_versions_after_linking_400 in this file.
|
||||
* - "versioning_cycles.cc", #blo_do_versions_cycles
|
||||
* - "versioning_cycles.cc", #do_versions_after_linking_cycles
|
||||
* - "versioning_userdef.c", #blo_do_versions_userdef
|
||||
* - "versioning_userdef.c", #do_versions_theme
|
||||
*
|
||||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
/* Convert anisotropic BSDF node to glossy BSDF. */
|
||||
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
||||
versioning_replace_legacy_glossy_node(ntree);
|
||||
versioning_remove_microfacet_sharp_distribution(ntree);
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
|
||||
/* Keep this block, even when empty. */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,10 +50,12 @@
|
|||
* - write library block
|
||||
* - per LibBlock
|
||||
* - write the ID of LibBlock
|
||||
* - write #TEST (#RenderInfo struct. 128x128 blend file preview is optional).
|
||||
* - write #GLOB (#FileGlobal struct) (some global vars).
|
||||
* - write #DNA1 (#SDNA struct)
|
||||
* - write #USER (#UserDef struct) if filename is `~/.config/blender/X.XX/config/startup.blend`.
|
||||
* - write #BLO_CODE_GLOB (#RenderInfo struct. 128x128 blend file preview is optional).
|
||||
* - write #BLO_CODE_GLOB (#FileGlobal struct) (some global vars).
|
||||
* - write #BLO_CODE_DNA1 (#SDNA struct)
|
||||
* - write #BLO_CODE_USER (#UserDef struct) for file paths:
|
||||
- #BLENDER_STARTUP_FILE (on UNIX `~/.config/blender/X.X/config/startup.blend`).
|
||||
- #BLENDER_USERPREF_FILE (on UNIX `~/.config/blender/X.X/config/userpref.blend`).
|
||||
*/
|
||||
|
||||
#include <cerrno>
|
||||
|
@ -971,10 +973,10 @@ static void write_libraries(WriteData *wd, Main *main)
|
|||
}
|
||||
}
|
||||
|
||||
/* To be able to restore 'quit.blend' and temp saves,
|
||||
/* To be able to restore `quit.blend` and temp saves,
|
||||
* the packed blend has to be in undo buffers... */
|
||||
/* XXX needs rethink, just like save UI in undo files now -
|
||||
* would be nice to append things only for the 'quit.blend' and temp saves. */
|
||||
* would be nice to append things only for the `quit.blend` and temp saves. */
|
||||
if (found_one) {
|
||||
/* Not overridable. */
|
||||
|
||||
|
|
|
@ -66,8 +66,7 @@ const char *BLT_pgettext(const char *msgctxt, const char *msgid)
|
|||
bool BLT_translate(void)
|
||||
{
|
||||
#ifdef WITH_INTERNATIONAL
|
||||
return true;
|
||||
/* return BLI_thread_is_main(); */
|
||||
return BLI_thread_is_main();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
|
|
@ -322,6 +322,8 @@ if(WITH_COMPOSITOR_CPU)
|
|||
nodes/COM_FilterNode.h
|
||||
nodes/COM_InpaintNode.cc
|
||||
nodes/COM_InpaintNode.h
|
||||
nodes/COM_KuwaharaNode.h
|
||||
nodes/COM_KuwaharaNode.cc
|
||||
nodes/COM_PosterizeNode.cc
|
||||
nodes/COM_PosterizeNode.h
|
||||
|
||||
|
@ -349,6 +351,10 @@ if(WITH_COMPOSITOR_CPU)
|
|||
operations/COM_GaussianXBlurOperation.h
|
||||
operations/COM_GaussianYBlurOperation.cc
|
||||
operations/COM_GaussianYBlurOperation.h
|
||||
operations/COM_KuwaharaClassicOperation.h
|
||||
operations/COM_KuwaharaClassicOperation.cc
|
||||
operations/COM_KuwaharaAnisotropicOperation.h
|
||||
operations/COM_KuwaharaAnisotropicOperation.cc
|
||||
operations/COM_MovieClipAttributeOperation.cc
|
||||
operations/COM_MovieClipAttributeOperation.h
|
||||
operations/COM_MovieDistortionOperation.cc
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Render;
|
||||
|
||||
/* Keep ascii art. */
|
||||
/* clang-format off */
|
||||
|
||||
|
@ -294,6 +296,9 @@ extern "C" {
|
|||
* It can be executed during editing (blenkernel/node.cc) or rendering
|
||||
* (renderer/pipeline.c)
|
||||
*
|
||||
* \param render: [struct Render]
|
||||
* Render instance for GPU context.
|
||||
*
|
||||
* \param render_data: [struct RenderData]
|
||||
* Render data for this composite, this won't always belong to a scene.
|
||||
*
|
||||
|
@ -305,10 +310,10 @@ extern "C" {
|
|||
* (true) or editing (false).
|
||||
* based on this setting the system will work differently:
|
||||
* - during rendering only Composite & the File output node will be calculated
|
||||
* \see NodeOperation.is_output_program(int rendering) of the specific operations
|
||||
* \see NodeOperation.is_output_program(bool rendering) of the specific operations
|
||||
*
|
||||
* - during editing all output nodes will be calculated
|
||||
* \see NodeOperation.is_output_program(int rendering) of the specific operations
|
||||
* \see NodeOperation.is_output_program(bool rendering) of the specific operations
|
||||
*
|
||||
* - another quality setting can be used bNodeTree.
|
||||
* The quality is determined by the bNodeTree fields.
|
||||
|
@ -326,10 +331,11 @@ extern "C" {
|
|||
*/
|
||||
/* clang-format off */
|
||||
|
||||
void COM_execute(RenderData *render_data,
|
||||
void COM_execute(Render *render,
|
||||
RenderData *render_data,
|
||||
Scene *scene,
|
||||
bNodeTree *node_tree,
|
||||
int rendering,
|
||||
bool rendering,
|
||||
const char *view_name);
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "COM_InvertNode.h"
|
||||
#include "COM_KeyingNode.h"
|
||||
#include "COM_KeyingScreenNode.h"
|
||||
#include "COM_KuwaharaNode.h"
|
||||
#include "COM_LensDistortionNode.h"
|
||||
#include "COM_LuminanceMatteNode.h"
|
||||
#include "COM_MapRangeNode.h"
|
||||
|
@ -436,6 +437,9 @@ Node *COM_convert_bnode(bNode *b_node)
|
|||
case CMP_NODE_COMBINE_XYZ:
|
||||
node = new CombineXYZNode(b_node);
|
||||
break;
|
||||
case CMP_NODE_KUWAHARA:
|
||||
node = new KuwaharaNode(b_node);
|
||||
break;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue