Geometry Node: Multi-input socket tooltip #104468
|
@ -1399,13 +1399,12 @@ endif()
|
||||||
|
|
||||||
# Test SIMD support, before platform includes to determine if sse2neon is needed.
|
# Test SIMD support, before platform includes to determine if sse2neon is needed.
|
||||||
if(WITH_CPU_SIMD)
|
if(WITH_CPU_SIMD)
|
||||||
set(COMPILER_SSE_FLAG)
|
set(COMPILER_SSE42_FLAG)
|
||||||
set(COMPILER_SSE2_FLAG)
|
|
||||||
|
|
||||||
# Test Neon first since macOS Arm can compile and run x86-64 SSE binaries.
|
# Test Neon first since macOS Arm can compile and run x86-64 SSE binaries.
|
||||||
test_neon_support()
|
test_neon_support()
|
||||||
if(NOT SUPPORT_NEON_BUILD)
|
if(NOT SUPPORT_NEON_BUILD)
|
||||||
test_sse_support(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
|
test_sse_support(COMPILER_SSE42_FLAG)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -1445,8 +1444,6 @@ endif()
|
||||||
|
|
||||||
# Enable SIMD support if detected by `test_sse_support()` or `test_neon_support()`.
|
# Enable SIMD support if detected by `test_sse_support()` or `test_neon_support()`.
|
||||||
#
|
#
|
||||||
# This is done globally, so that all modules can use it if available, and
|
|
||||||
# because these are used in headers used by many modules.
|
|
||||||
if(WITH_CPU_SIMD)
|
if(WITH_CPU_SIMD)
|
||||||
if(SUPPORT_NEON_BUILD)
|
if(SUPPORT_NEON_BUILD)
|
||||||
# Neon
|
# Neon
|
||||||
|
@ -1456,15 +1453,20 @@ if(WITH_CPU_SIMD)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
# SSE
|
# SSE
|
||||||
if(SUPPORT_SSE_BUILD)
|
if(SUPPORT_SSE42_BUILD)
|
||||||
string(PREPEND PLATFORM_CFLAGS "${COMPILER_SSE_FLAG} ")
|
string(APPEND CMAKE_CXX_FLAGS " ${COMPILER_SSE42_FLAG}")
|
||||||
add_definitions(-D__SSE__ -D__MMX__)
|
string(APPEND CMAKE_C_FLAGS " ${COMPILER_SSE42_FLAG}")
|
||||||
endif()
|
# MSVC doesn't define any of these and only does the AVX and higher flags.
|
||||||
if(SUPPORT_SSE2_BUILD)
|
# For consistency we define these flags for MSVC.
|
||||||
string(APPEND PLATFORM_CFLAGS " ${COMPILER_SSE2_FLAG}")
|
if(WIN32)
|
||||||
add_definitions(-D__SSE2__)
|
add_compile_definitions(
|
||||||
if(NOT SUPPORT_SSE_BUILD) # don't double up
|
__MMX__
|
||||||
add_definitions(-D__MMX__)
|
__SSE__
|
||||||
|
__SSE2__
|
||||||
|
__SSE3__
|
||||||
|
__SSE4_1__
|
||||||
|
__SSE4_2__
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -1479,10 +1481,8 @@ if(FIRST_RUN)
|
||||||
else()
|
else()
|
||||||
message(STATUS "Neon SIMD instructions detected but unused, requires sse2neon")
|
message(STATUS "Neon SIMD instructions detected but unused, requires sse2neon")
|
||||||
endif()
|
endif()
|
||||||
elseif(SUPPORT_SSE2_BUILD)
|
elseif(SUPPORT_SSE42_BUILD)
|
||||||
message(STATUS "SSE2 SIMD instructions enabled")
|
message(STATUS "SSE42 SIMD instructions enabled")
|
||||||
elseif(SUPPORT_SSE_BUILD)
|
|
||||||
message(STATUS "SSE SIMD instructions enabled")
|
|
||||||
else()
|
else()
|
||||||
message(STATUS "No SIMD instructions detected")
|
message(STATUS "No SIMD instructions detected")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -540,49 +540,37 @@ function(setup_platform_linker_libs
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
macro(TEST_SSE_SUPPORT
|
macro(TEST_SSE_SUPPORT
|
||||||
_sse_flags
|
_sse42_flags)
|
||||||
_sse2_flags)
|
|
||||||
|
|
||||||
include(CheckCSourceRuns)
|
include(CheckCSourceRuns)
|
||||||
|
|
||||||
# message(STATUS "Detecting SSE support")
|
# message(STATUS "Detecting SSE support")
|
||||||
if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
|
if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
|
||||||
set(${_sse_flags} "-msse")
|
set(${_sse42_flags} "-march=x86-64-v2")
|
||||||
set(${_sse2_flags} "-msse2")
|
|
||||||
elseif(MSVC)
|
elseif(MSVC)
|
||||||
# x86_64 has this auto enabled
|
# msvc has no specific build flags for SSE42, but when using intrinsics it will
|
||||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
# generate the right instructions.
|
||||||
set(${_sse_flags} "")
|
set(${_sse42_flags} "")
|
||||||
set(${_sse2_flags} "")
|
|
||||||
else()
|
|
||||||
set(${_sse_flags} "/arch:SSE")
|
|
||||||
set(${_sse2_flags} "/arch:SSE2")
|
|
||||||
endif()
|
|
||||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel")
|
elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel")
|
||||||
set(${_sse_flags} "") # icc defaults to -msse
|
if(WIN32)
|
||||||
set(${_sse2_flags} "") # icc defaults to -msse2
|
set(${_sse42_flags} "/QxSSE4.2")
|
||||||
|
else()
|
||||||
|
set(${_sse42_flags} "-xsse4.2")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
message(WARNING "SSE flags for this compiler: '${CMAKE_C_COMPILER_ID}' not known")
|
message(WARNING "SSE flags for this compiler: '${CMAKE_C_COMPILER_ID}' not known")
|
||||||
set(${_sse_flags})
|
set(${_sse42_flags})
|
||||||
set(${_sse2_flags})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "${${_sse_flags}} ${${_sse2_flags}}")
|
set(CMAKE_REQUIRED_FLAGS "${${_sse42_flags}}")
|
||||||
|
|
||||||
if(NOT DEFINED SUPPORT_SSE_BUILD)
|
if(NOT DEFINED SUPPORT_SSE42_BUILD)
|
||||||
# result cached
|
|
||||||
check_c_source_runs("
|
|
||||||
#include <xmmintrin.h>
|
|
||||||
int main(void) { __m128 v = _mm_setzero_ps(); return 0; }"
|
|
||||||
SUPPORT_SSE_BUILD)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT DEFINED SUPPORT_SSE2_BUILD)
|
|
||||||
# result cached
|
# result cached
|
||||||
check_c_source_runs("
|
check_c_source_runs("
|
||||||
|
#include <nmmintrin.h>
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
int main(void) { __m128d v = _mm_setzero_pd(); return 0; }"
|
int main(void) { __m128i v = _mm_setzero_si128(); v = _mm_cmpgt_epi64(v,v); return 0; }"
|
||||||
SUPPORT_SSE2_BUILD)
|
SUPPORT_SSE42_BUILD)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
unset(CMAKE_REQUIRED_FLAGS)
|
unset(CMAKE_REQUIRED_FLAGS)
|
||||||
|
|
|
@ -21,4 +21,4 @@ if "Cube" in bpy.data.meshes:
|
||||||
import os
|
import os
|
||||||
with open(os.path.splitext(bpy.data.filepath)[0] + ".txt", 'w') as fs:
|
with open(os.path.splitext(bpy.data.filepath)[0] + ".txt", 'w') as fs:
|
||||||
for image in bpy.data.images:
|
for image in bpy.data.images:
|
||||||
fs.write("%s %d x %d\n" % (image.filepath, image.size[0], image.size[1]))
|
fs.write("{:s} {:d} x {:d}\n".format(image.filepath, image.size[0], image.size[1]))
|
||||||
|
|
|
@ -21,8 +21,9 @@ class OBJECT_OT_property_example(bpy.types.Operator):
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.report(
|
self.report(
|
||||||
{'INFO'}, 'F: %.2f B: %s S: %r' %
|
{'INFO'}, "F: {:.2f} B: {:s} S: {!r}".format(
|
||||||
(self.my_float, self.my_bool, self.my_string)
|
self.my_float, self.my_bool, self.my_string,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
print('My float:', self.my_float)
|
print('My float:', self.my_float)
|
||||||
print('My bool:', self.my_bool)
|
print('My bool:', self.my_bool)
|
||||||
|
|
|
@ -53,9 +53,9 @@ class OBJECT_OT_addon_prefs_example(Operator):
|
||||||
preferences = context.preferences
|
preferences = context.preferences
|
||||||
addon_prefs = preferences.addons[__name__].preferences
|
addon_prefs = preferences.addons[__name__].preferences
|
||||||
|
|
||||||
info = ("Path: %s, Number: %d, Boolean %r" %
|
info = "Path: {:s}, Number: {:d}, Boolean {!r}".format(
|
||||||
(addon_prefs.filepath, addon_prefs.number, addon_prefs.boolean))
|
addon_prefs.filepath, addon_prefs.number, addon_prefs.boolean,
|
||||||
|
)
|
||||||
self.report({'INFO'}, info)
|
self.report({'INFO'}, info)
|
||||||
print(info)
|
print(info)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ import bpy
|
||||||
|
|
||||||
def dump(obj, text):
|
def dump(obj, text):
|
||||||
for attr in dir(obj):
|
for attr in dir(obj):
|
||||||
print("%r.%s = %s" % (obj, attr, getattr(obj, attr)))
|
print("{!r}.{:s} = {:s}".format(obj, attr, getattr(obj, attr)))
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_button_context_test(bpy.types.Operator):
|
class WM_OT_button_context_test(bpy.types.Operator):
|
||||||
|
|
|
@ -31,10 +31,10 @@ me = bpy.context.object.data
|
||||||
uv_layer = me.uv_layers.active.data
|
uv_layer = me.uv_layers.active.data
|
||||||
|
|
||||||
for poly in me.polygons:
|
for poly in me.polygons:
|
||||||
print("Polygon index: %d, length: %d" % (poly.index, poly.loop_total))
|
print("Polygon index: {:d}, length: {:d}".format(poly.index, poly.loop_total))
|
||||||
|
|
||||||
# range is used here to show how the polygons reference loops,
|
# range is used here to show how the polygons reference loops,
|
||||||
# for convenience 'poly.loop_indices' can be used instead.
|
# for convenience 'poly.loop_indices' can be used instead.
|
||||||
for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
|
for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
|
||||||
print(" Vertex: %d" % me.loops[loop_index].vertex_index)
|
print(" Vertex: {:d}".format(me.loops[loop_index].vertex_index))
|
||||||
print(" UV: %r" % uv_layer[loop_index].uv)
|
print(" UV: {!r}".format(uv_layer[loop_index].uv))
|
||||||
|
|
|
@ -34,7 +34,7 @@ class SimpleMouseOperator(bpy.types.Operator):
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
# rather than printing, use the report function,
|
# rather than printing, use the report function,
|
||||||
# this way the message appears in the header,
|
# this way the message appears in the header,
|
||||||
self.report({'INFO'}, "Mouse coords are %d %d" % (self.x, self.y))
|
self.report({'INFO'}, "Mouse coords are {:d} {:d}".format(self.x, self.y))
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
|
|
|
@ -16,9 +16,8 @@ class DialogOperator(bpy.types.Operator):
|
||||||
my_string: bpy.props.StringProperty(name="String Value")
|
my_string: bpy.props.StringProperty(name="String Value")
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
message = (
|
message = "Popup Values: {:f}, {:d}, '{:s}'".format(
|
||||||
"Popup Values: %f, %d, '%s'" %
|
self.my_float, self.my_bool, self.my_string,
|
||||||
(self.my_float, self.my_bool, self.my_string)
|
|
||||||
)
|
)
|
||||||
self.report({'INFO'}, message)
|
self.report({'INFO'}, message)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
|
@ -10,21 +10,21 @@ col.s *= 0.5
|
||||||
print("Color R:", col.r)
|
print("Color R:", col.r)
|
||||||
print("Color G:", col[1])
|
print("Color G:", col[1])
|
||||||
print("Color B:", col[-1])
|
print("Color B:", col[-1])
|
||||||
print("Color HSV: %.2f, %.2f, %.2f", col[:])
|
print("Color HSV: {:.2f}, {:.2f}, {:.2f}".format(*col))
|
||||||
|
|
||||||
|
|
||||||
# components of an existing color can be set
|
# components of an existing color can be set
|
||||||
col[:] = 0.0, 0.5, 1.0
|
col[:] = 0.0, 0.5, 1.0
|
||||||
|
|
||||||
# components of an existing color can use slice notation to get a tuple
|
# components of an existing color can use slice notation to get a tuple
|
||||||
print("Values: %f, %f, %f" % col[:])
|
print("Values: {:f}, {:f}, {:f}".format(*col))
|
||||||
|
|
||||||
# colors can be added and subtracted
|
# colors can be added and subtracted
|
||||||
col += mathutils.Color((0.25, 0.0, 0.0))
|
col += mathutils.Color((0.25, 0.0, 0.0))
|
||||||
|
|
||||||
# Color can be multiplied, in this example color is scaled to 0-255
|
# Color can be multiplied, in this example color is scaled to 0-255
|
||||||
# can printed as integers
|
# can printed as integers
|
||||||
print("Color: %d, %d, %d" % (col * 255.0)[:])
|
print("Color: {:d}, {:d}, {:d}".format(*(int(c) for c in (col * 255.0))))
|
||||||
|
|
||||||
# This example prints the color as hexadecimal
|
# This example prints the color as hexadecimal
|
||||||
print("Hexadecimal: %.2x%.2x%.2x" % (int(col.r * 255), int(col.g * 255), int(col.b * 255)))
|
print("Hexadecimal: {:02x}{:02x}{:02x}".format(int(col.r * 255), int(col.g * 255), int(col.b * 255)))
|
||||||
|
|
|
@ -16,7 +16,7 @@ print("Euler Z", eul[-1])
|
||||||
eul[:] = 1.0, 2.0, 3.0
|
eul[:] = 1.0, 2.0, 3.0
|
||||||
|
|
||||||
# components of an existing euler can use slice notation to get a tuple
|
# components of an existing euler can use slice notation to get a tuple
|
||||||
print("Values: %f, %f, %f" % eul[:])
|
print("Values: {:f}, {:f}, {:f}".format(*eul))
|
||||||
|
|
||||||
# the order can be set at any time too
|
# the order can be set at any time too
|
||||||
eul.order = 'ZYX'
|
eul.order = 'ZYX'
|
||||||
|
|
|
@ -18,9 +18,8 @@ quat_out = quat_a @ quat_b
|
||||||
# print the quat, euler degrees for mere mortals and (axis, angle)
|
# print the quat, euler degrees for mere mortals and (axis, angle)
|
||||||
print("Final Rotation:")
|
print("Final Rotation:")
|
||||||
print(quat_out)
|
print(quat_out)
|
||||||
print("%.2f, %.2f, %.2f" % tuple(math.degrees(a) for a in quat_out.to_euler()))
|
print("{:.2f}, {:.2f}, {:.2f}".format(*(math.degrees(a) for a in quat_out.to_euler())))
|
||||||
print("(%.2f, %.2f, %.2f), %.2f" % (quat_out.axis[:] +
|
print("({:.2f}, {:.2f}, {:.2f}), {:.2f}".format(*quat_out.axis, math.degrees(quat_out.angle)))
|
||||||
(math.degrees(quat_out.angle), )))
|
|
||||||
|
|
||||||
# multiple rotations can be interpolated using the exponential map
|
# multiple rotations can be interpolated using the exponential map
|
||||||
quat_c = mathutils.Quaternion((1.0, 0.0, 0.0), math.radians(15.0))
|
quat_c = mathutils.Quaternion((1.0, 0.0, 0.0), math.radians(15.0))
|
||||||
|
|
|
@ -21,7 +21,7 @@ class CyclesPresetPanel(PresetPanel, Panel):
|
||||||
preset_operator = "script.execute_preset"
|
preset_operator = "script.execute_preset"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def post_cb(context):
|
def post_cb(context, _filepath):
|
||||||
# Modify an arbitrary built-in scene property to force a depsgraph
|
# Modify an arbitrary built-in scene property to force a depsgraph
|
||||||
# update, because add-on properties don't. (see #62325)
|
# update, because add-on properties don't. (see #62325)
|
||||||
render = context.scene.render
|
render = context.scene.render
|
||||||
|
|
|
@ -332,7 +332,7 @@ class InfoPropertyRNA:
|
||||||
self.default_str = "\"%s\"" % self.default
|
self.default_str = "\"%s\"" % self.default
|
||||||
elif self.type == "enum":
|
elif self.type == "enum":
|
||||||
if self.is_enum_flag:
|
if self.is_enum_flag:
|
||||||
# self.default_str = "%r" % self.default # repr or set()
|
# self.default_str = repr(self.default) # repr or set()
|
||||||
self.default_str = "{%s}" % repr(list(sorted(self.default)))[1:-1]
|
self.default_str = "{%s}" % repr(list(sorted(self.default)))[1:-1]
|
||||||
else:
|
else:
|
||||||
self.default_str = "'%s'" % self.default
|
self.default_str = "'%s'" % self.default
|
||||||
|
|
|
@ -818,7 +818,7 @@ class TransformsToDeltasAnim(Operator):
|
||||||
if fcu.array_index in existingFCurves[dpath]:
|
if fcu.array_index in existingFCurves[dpath]:
|
||||||
# conflict
|
# conflict
|
||||||
self.report({'ERROR'},
|
self.report({'ERROR'},
|
||||||
rpt_("Object '%r' already has '%r' F-Curve(s). "
|
rpt_("Object %r already has %r F-Curve(s). "
|
||||||
"Remove these before trying again") %
|
"Remove these before trying again") %
|
||||||
(obj.name, dpath))
|
(obj.name, dpath))
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
|
@ -30,6 +30,25 @@ WindowManager.preset_name = StringProperty(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _call_preset_cb(fn, context, filepath):
|
||||||
|
# Allow "None" so the caller doesn't have to assign a variable and check it.
|
||||||
|
if fn is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Support a `filepath` argument, optional for backwards compatibility.
|
||||||
|
fn_arg_count = getattr(getattr(fn, "__code__", None), "co_argcount", None)
|
||||||
|
if fn_arg_count == 2:
|
||||||
|
args = (context, filepath)
|
||||||
|
else:
|
||||||
|
print("Deprecated since Blender 4.2, a filepath argument should be included in:", fn)
|
||||||
|
args = (context, )
|
||||||
|
|
||||||
|
try:
|
||||||
|
fn(*args)
|
||||||
|
except BaseException as ex:
|
||||||
|
print("Internal error running", fn, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class AddPresetBase:
|
class AddPresetBase:
|
||||||
"""Base preset class, only for subclassing
|
"""Base preset class, only for subclassing
|
||||||
subclasses must define
|
subclasses must define
|
||||||
|
@ -241,8 +260,7 @@ class ExecutePreset(Operator):
|
||||||
self.report({'ERROR'}, rpt_("Unknown file type: %r") % ext)
|
self.report({'ERROR'}, rpt_("Unknown file type: %r") % ext)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
if hasattr(preset_class, "reset_cb"):
|
_call_preset_cb(getattr(preset_class, "reset_cb", None), context, filepath)
|
||||||
preset_class.reset_cb(context)
|
|
||||||
|
|
||||||
if ext == ".py":
|
if ext == ".py":
|
||||||
try:
|
try:
|
||||||
|
@ -254,8 +272,7 @@ class ExecutePreset(Operator):
|
||||||
import rna_xml
|
import rna_xml
|
||||||
rna_xml.xml_file_run(context, filepath, preset_class.preset_xml_map)
|
rna_xml.xml_file_run(context, filepath, preset_class.preset_xml_map)
|
||||||
|
|
||||||
if hasattr(preset_class, "post_cb"):
|
_call_preset_cb(getattr(preset_class, "post_cb", None), context, filepath)
|
||||||
preset_class.post_cb(context)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
@ -637,6 +654,8 @@ class SavePresetInterfaceTheme(AddPresetBase, Operator):
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
context.preferences.themes[0].filepath = filepath
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
|
|
|
@ -166,7 +166,7 @@ class PlayRenderedAnim(Operator):
|
||||||
opts = ["-fps", str(rd.fps), "-play"]
|
opts = ["-fps", str(rd.fps), "-play"]
|
||||||
if scene.use_preview_range:
|
if scene.use_preview_range:
|
||||||
opts += [
|
opts += [
|
||||||
"%s" % file.replace("#", "", file.count('#') - 1),
|
file.replace("#", "", file.count('#') - 1),
|
||||||
"%d-%d" % (frame_start, frame_end),
|
"%d-%d" % (frame_start, frame_end),
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -66,7 +66,7 @@ class OUTLINER_HT_header(Header):
|
||||||
layout.operator("outliner.collection_new", text="", icon='COLLECTION_NEW').nested = True
|
layout.operator("outliner.collection_new", text="", icon='COLLECTION_NEW').nested = True
|
||||||
|
|
||||||
elif display_mode == 'ORPHAN_DATA':
|
elif display_mode == 'ORPHAN_DATA':
|
||||||
layout.operator("outliner.orphans_purge", text="Purge").do_recursive = True
|
layout.operator("outliner.orphans_purge", text="Purge")
|
||||||
|
|
||||||
elif space.display_mode == 'DATA_API':
|
elif space.display_mode == 'DATA_API':
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
|
@ -860,21 +860,37 @@ class USERPREF_MT_interface_theme_presets(Menu):
|
||||||
draw = Menu.draw_preset
|
draw = Menu.draw_preset
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def reset_cb(context):
|
def reset_cb(_context, _filepath):
|
||||||
bpy.ops.preferences.reset_default_theme()
|
bpy.ops.preferences.reset_default_theme()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def post_cb(context, filepath):
|
||||||
|
context.preferences.themes[0].filepath = filepath
|
||||||
|
|
||||||
|
|
||||||
class USERPREF_PT_theme(ThemePanel, Panel):
|
class USERPREF_PT_theme(ThemePanel, Panel):
|
||||||
bl_label = "Themes"
|
bl_label = "Themes"
|
||||||
bl_options = {'HIDE_HEADER'}
|
bl_options = {'HIDE_HEADER'}
|
||||||
|
|
||||||
def draw(self, _context):
|
def draw(self, context):
|
||||||
|
import os
|
||||||
|
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
split = layout.split(factor=0.6)
|
split = layout.split(factor=0.6)
|
||||||
|
|
||||||
row = split.row(align=True)
|
row = split.row(align=True)
|
||||||
row.menu("USERPREF_MT_interface_theme_presets", text=USERPREF_MT_interface_theme_presets.bl_label)
|
|
||||||
|
# Unlike most presets (which use the classes bl_label),
|
||||||
|
# themes store the path, use this when set.
|
||||||
|
if filepath := context.preferences.themes[0].filepath:
|
||||||
|
preset_label = bpy.path.display_name(os.path.basename(filepath))
|
||||||
|
else:
|
||||||
|
preset_label = USERPREF_MT_interface_theme_presets.bl_label
|
||||||
|
|
||||||
|
row.menu("USERPREF_MT_interface_theme_presets", text=preset_label)
|
||||||
|
del filepath, preset_label
|
||||||
|
|
||||||
row.operator("wm.interface_theme_preset_add", text="", icon='ADD')
|
row.operator("wm.interface_theme_preset_add", text="", icon='ADD')
|
||||||
row.operator("wm.interface_theme_preset_remove", text="", icon='REMOVE')
|
row.operator("wm.interface_theme_preset_remove", text="", icon='REMOVE')
|
||||||
row.operator("wm.interface_theme_preset_save", text="", icon='FILE_TICK')
|
row.operator("wm.interface_theme_preset_save", text="", icon='FILE_TICK')
|
||||||
|
|
|
@ -108,7 +108,7 @@ class MyCustomShapeWidget(Gizmo):
|
||||||
delta /= 10.0
|
delta /= 10.0
|
||||||
value = self.init_value - delta
|
value = self.init_value - delta
|
||||||
self.target_set_value("offset", value)
|
self.target_set_value("offset", value)
|
||||||
context.area.header_text_set("My Gizmo: %.4f" % value)
|
context.area.header_text_set("My Gizmo: {:.4f}".format(value))
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import bpy
|
||||||
def write_some_data(context, filepath, use_some_setting):
|
def write_some_data(context, filepath, use_some_setting):
|
||||||
print("running write_some_data...")
|
print("running write_some_data...")
|
||||||
f = open(filepath, 'w', encoding='utf-8')
|
f = open(filepath, 'w', encoding='utf-8')
|
||||||
f.write("Hello World %s" % use_some_setting)
|
f.write("Hello World {:s}".format(use_some_setting))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
|
@ -26,7 +26,7 @@ class ViewOperator(bpy.types.Operator):
|
||||||
if event.type == 'MOUSEMOVE':
|
if event.type == 'MOUSEMOVE':
|
||||||
self.offset = (self._initial_mouse - Vector((event.mouse_x, event.mouse_y, 0.0))) * 0.02
|
self.offset = (self._initial_mouse - Vector((event.mouse_x, event.mouse_y, 0.0))) * 0.02
|
||||||
self.execute(context)
|
self.execute(context)
|
||||||
context.area.header_text_set("Offset %.4f %.4f %.4f" % tuple(self.offset))
|
context.area.header_text_set("Offset {:.4f} {:.4f} {:.4f}".format(*self.offset))
|
||||||
|
|
||||||
elif event.type == 'LEFTMOUSE':
|
elif event.type == 'LEFTMOUSE':
|
||||||
context.area.header_text_set(None)
|
context.area.header_text_set(None)
|
||||||
|
|
|
@ -39,7 +39,7 @@ def enum_previews_from_directory_items(self, context):
|
||||||
if directory == pcoll.my_previews_dir:
|
if directory == pcoll.my_previews_dir:
|
||||||
return pcoll.my_previews
|
return pcoll.my_previews
|
||||||
|
|
||||||
print("Scanning directory: %s" % directory)
|
print("Scanning directory:", directory)
|
||||||
|
|
||||||
if directory and os.path.exists(directory):
|
if directory and os.path.exists(directory):
|
||||||
# Scan the directory for `*.png` files
|
# Scan the directory for `*.png` files
|
||||||
|
|
|
@ -181,3 +181,7 @@ endif()
|
||||||
if(WITH_FREESTYLE)
|
if(WITH_FREESTYLE)
|
||||||
add_subdirectory(freestyle)
|
add_subdirectory(freestyle)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_CPU_CHECK)
|
||||||
|
add_subdirectory(cpucheck)
|
||||||
|
endif()
|
||||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
||||||
|
|
||||||
/* Blender file format version. */
|
/* Blender file format version. */
|
||||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||||
#define BLENDER_FILE_SUBVERSION 15
|
#define BLENDER_FILE_SUBVERSION 16
|
||||||
|
|
||||||
/* Minimum Blender version that supports reading file written with the current
|
/* Minimum Blender version that supports reading file written with the current
|
||||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||||
|
|
|
@ -575,14 +575,6 @@ struct SculptSession {
|
||||||
blender::float3 cursor_sampled_normal;
|
blender::float3 cursor_sampled_normal;
|
||||||
blender::float3 cursor_view_normal;
|
blender::float3 cursor_view_normal;
|
||||||
|
|
||||||
/* For Sculpt trimming gesture tools, initial ray-cast data from the position of the mouse
|
|
||||||
* when
|
|
||||||
* the gesture starts (intersection with the surface and if they ray hit the surface or not).
|
|
||||||
*/
|
|
||||||
blender::float3 gesture_initial_location;
|
|
||||||
blender::float3 gesture_initial_normal;
|
|
||||||
bool gesture_initial_hit;
|
|
||||||
|
|
||||||
/* TODO(jbakker): Replace rv3d and v3d with ViewContext */
|
/* TODO(jbakker): Replace rv3d and v3d with ViewContext */
|
||||||
RegionView3D *rv3d;
|
RegionView3D *rv3d;
|
||||||
View3D *v3d;
|
View3D *v3d;
|
||||||
|
|
|
@ -67,7 +67,7 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
|
||||||
#define FROM_DEFAULT_V4_UCHAR(member) copy_v4_v4_uchar(btheme->member, U_theme_default.member)
|
#define FROM_DEFAULT_V4_UCHAR(member) copy_v4_v4_uchar(btheme->member, U_theme_default.member)
|
||||||
|
|
||||||
if (!USER_VERSION_ATLEAST(300, 41)) {
|
if (!USER_VERSION_ATLEAST(300, 41)) {
|
||||||
memcpy(btheme, &U_theme_default, sizeof(*btheme));
|
MEMCPY_STRUCT_AFTER(btheme, &U_theme_default, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Again reset the theme, but only if stored with an early 3.1 alpha version. Some changes were
|
/* Again reset the theme, but only if stored with an early 3.1 alpha version. Some changes were
|
||||||
|
@ -76,7 +76,7 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
|
||||||
* don't want to reset theme changes stored in the eventual 3.0 release once opened in a 3.1
|
* don't want to reset theme changes stored in the eventual 3.0 release once opened in a 3.1
|
||||||
* build. */
|
* build. */
|
||||||
if (userdef->versionfile > 300 && !USER_VERSION_ATLEAST(301, 1)) {
|
if (userdef->versionfile > 300 && !USER_VERSION_ATLEAST(301, 1)) {
|
||||||
memcpy(btheme, &U_theme_default, sizeof(*btheme));
|
MEMCPY_STRUCT_AFTER(btheme, &U_theme_default, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!USER_VERSION_ATLEAST(301, 2)) {
|
if (!USER_VERSION_ATLEAST(301, 2)) {
|
||||||
|
@ -145,7 +145,7 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
|
||||||
FROM_DEFAULT_V4_UCHAR(space_console.console_cursor);
|
FROM_DEFAULT_V4_UCHAR(space_console.console_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!USER_VERSION_ATLEAST(402, 14)) {
|
if (!USER_VERSION_ATLEAST(402, 16)) {
|
||||||
BLI_uniquename(
|
BLI_uniquename(
|
||||||
&userdef->themes, btheme, "Theme", '.', offsetof(bTheme, name), sizeof(btheme->name));
|
&userdef->themes, btheme, "Theme", '.', offsetof(bTheme, name), sizeof(btheme->name));
|
||||||
}
|
}
|
||||||
|
@ -515,7 +515,7 @@ void blo_do_versions_userdef(UserDef *userdef)
|
||||||
|
|
||||||
/* Reset theme, old themes will not be compatible with minor version updates from now on. */
|
/* Reset theme, old themes will not be compatible with minor version updates from now on. */
|
||||||
LISTBASE_FOREACH (bTheme *, btheme, &userdef->themes) {
|
LISTBASE_FOREACH (bTheme *, btheme, &userdef->themes) {
|
||||||
memcpy(btheme, &U_theme_default, sizeof(*btheme));
|
MEMCPY_STRUCT_AFTER(btheme, &U_theme_default, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Annotations - new layer color
|
/* Annotations - new layer color
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
# SPDX-FileCopyrightText: 2024 Blender Authors
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
# The cpu check module cannot build with sse42 since it will be executed
|
||||||
|
# by cpus that may not support these instructions
|
||||||
|
|
||||||
|
if(COMPILER_SSE42_FLAG)
|
||||||
|
remove_cc_flag("${COMPILER_SSE42_FLAG}")
|
||||||
|
endif()
|
||||||
|
add_library(blender_cpu_check SHARED cpu_check.cc)
|
||||||
|
|
||||||
|
target_link_libraries(blender_cpu_check PRIVATE ${PLATFORM_LINKLIBS})
|
||||||
|
target_compile_definitions(blender_cpu_check PUBLIC WITH_CPU_CHECK)
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
set(_LIB_SUB_FOLDER "lib/")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set_target_properties(blender_cpu_check
|
||||||
|
PROPERTIES
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${_LIB_SUB_FOLDER}"
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${_LIB_SUB_FOLDER}"
|
||||||
|
)
|
||||||
|
|
||||||
|
unset(_LIB_SUB_FOLDER)
|
|
@ -580,6 +580,30 @@ bool ANIM_animdata_can_have_greasepencil(const eAnimCont_Types type)
|
||||||
|
|
||||||
/* ----------- 'Private' Stuff --------------- */
|
/* ----------- 'Private' Stuff --------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set `ale` so that it points to the top-most 'summary' channel of the given `adt`.
|
||||||
|
* So this is either the Animation or the Action, or empty.
|
||||||
|
*/
|
||||||
|
static void key_data_from_adt(bAnimListElem &ale, AnimData *adt)
|
||||||
|
{
|
||||||
|
ale.adt = adt;
|
||||||
|
|
||||||
|
if (!adt) {
|
||||||
|
ale.key_data = nullptr;
|
||||||
|
ale.datatype = ALE_NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adt->action) {
|
||||||
|
ale.key_data = adt->action;
|
||||||
|
ale.datatype = ALE_ACT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ale.key_data = nullptr;
|
||||||
|
ale.datatype = ALE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* this function allocates memory for a new bAnimListElem struct for the
|
/* this function allocates memory for a new bAnimListElem struct for the
|
||||||
* provided animation channel-data.
|
* provided animation channel-data.
|
||||||
*/
|
*/
|
||||||
|
@ -655,244 +679,125 @@ static bAnimListElem *make_new_animlistelem(void *data,
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSMAT: {
|
case ANIMTYPE_DSMAT: {
|
||||||
Material *ma = (Material *)data;
|
Material *ma = (Material *)data;
|
||||||
AnimData *adt = ma->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_MAT_OBJD(ma);
|
ale->flag = FILTER_MAT_OBJD(ma);
|
||||||
|
key_data_from_adt(*ale, ma->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSLAM: {
|
case ANIMTYPE_DSLAM: {
|
||||||
Light *la = (Light *)data;
|
Light *la = (Light *)data;
|
||||||
AnimData *adt = la->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_LAM_OBJD(la);
|
ale->flag = FILTER_LAM_OBJD(la);
|
||||||
|
key_data_from_adt(*ale, la->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSCAM: {
|
case ANIMTYPE_DSCAM: {
|
||||||
Camera *ca = (Camera *)data;
|
Camera *ca = (Camera *)data;
|
||||||
AnimData *adt = ca->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_CAM_OBJD(ca);
|
ale->flag = FILTER_CAM_OBJD(ca);
|
||||||
|
key_data_from_adt(*ale, ca->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSCACHEFILE: {
|
case ANIMTYPE_DSCACHEFILE: {
|
||||||
CacheFile *cache_file = (CacheFile *)data;
|
CacheFile *cache_file = (CacheFile *)data;
|
||||||
AnimData *adt = cache_file->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_CACHEFILE_OBJD(cache_file);
|
ale->flag = FILTER_CACHEFILE_OBJD(cache_file);
|
||||||
|
key_data_from_adt(*ale, cache_file->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSCUR: {
|
case ANIMTYPE_DSCUR: {
|
||||||
Curve *cu = (Curve *)data;
|
Curve *cu = (Curve *)data;
|
||||||
AnimData *adt = cu->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_CUR_OBJD(cu);
|
ale->flag = FILTER_CUR_OBJD(cu);
|
||||||
|
key_data_from_adt(*ale, cu->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSARM: {
|
case ANIMTYPE_DSARM: {
|
||||||
bArmature *arm = (bArmature *)data;
|
bArmature *arm = (bArmature *)data;
|
||||||
AnimData *adt = arm->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_ARM_OBJD(arm);
|
ale->flag = FILTER_ARM_OBJD(arm);
|
||||||
|
key_data_from_adt(*ale, arm->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSMESH: {
|
case ANIMTYPE_DSMESH: {
|
||||||
Mesh *mesh = (Mesh *)data;
|
Mesh *mesh = (Mesh *)data;
|
||||||
AnimData *adt = mesh->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_MESH_OBJD(mesh);
|
ale->flag = FILTER_MESH_OBJD(mesh);
|
||||||
|
key_data_from_adt(*ale, mesh->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSLAT: {
|
case ANIMTYPE_DSLAT: {
|
||||||
Lattice *lt = (Lattice *)data;
|
Lattice *lt = (Lattice *)data;
|
||||||
AnimData *adt = lt->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_LATTICE_OBJD(lt);
|
ale->flag = FILTER_LATTICE_OBJD(lt);
|
||||||
|
key_data_from_adt(*ale, lt->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSSPK: {
|
case ANIMTYPE_DSSPK: {
|
||||||
Speaker *spk = (Speaker *)data;
|
Speaker *spk = (Speaker *)data;
|
||||||
AnimData *adt = spk->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_SPK_OBJD(spk);
|
ale->flag = FILTER_SPK_OBJD(spk);
|
||||||
|
key_data_from_adt(*ale, spk->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSHAIR: {
|
case ANIMTYPE_DSHAIR: {
|
||||||
Curves *curves = (Curves *)data;
|
Curves *curves = (Curves *)data;
|
||||||
AnimData *adt = curves->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_CURVES_OBJD(curves);
|
ale->flag = FILTER_CURVES_OBJD(curves);
|
||||||
|
key_data_from_adt(*ale, curves->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSPOINTCLOUD: {
|
case ANIMTYPE_DSPOINTCLOUD: {
|
||||||
PointCloud *pointcloud = (PointCloud *)data;
|
PointCloud *pointcloud = (PointCloud *)data;
|
||||||
AnimData *adt = pointcloud->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_POINTS_OBJD(pointcloud);
|
ale->flag = FILTER_POINTS_OBJD(pointcloud);
|
||||||
|
key_data_from_adt(*ale, pointcloud->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSVOLUME: {
|
case ANIMTYPE_DSVOLUME: {
|
||||||
Volume *volume = (Volume *)data;
|
Volume *volume = (Volume *)data;
|
||||||
AnimData *adt = volume->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_VOLUME_OBJD(volume);
|
ale->flag = FILTER_VOLUME_OBJD(volume);
|
||||||
|
key_data_from_adt(*ale, volume->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSSKEY: {
|
case ANIMTYPE_DSSKEY: {
|
||||||
Key *key = (Key *)data;
|
Key *key = (Key *)data;
|
||||||
AnimData *adt = key->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_SKE_OBJD(key);
|
ale->flag = FILTER_SKE_OBJD(key);
|
||||||
|
key_data_from_adt(*ale, key->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSWOR: {
|
case ANIMTYPE_DSWOR: {
|
||||||
World *wo = (World *)data;
|
World *wo = (World *)data;
|
||||||
AnimData *adt = wo->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_WOR_SCED(wo);
|
ale->flag = FILTER_WOR_SCED(wo);
|
||||||
|
key_data_from_adt(*ale, wo->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSNTREE: {
|
case ANIMTYPE_DSNTREE: {
|
||||||
bNodeTree *ntree = (bNodeTree *)data;
|
bNodeTree *ntree = (bNodeTree *)data;
|
||||||
AnimData *adt = ntree->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_NTREE_DATA(ntree);
|
ale->flag = FILTER_NTREE_DATA(ntree);
|
||||||
|
key_data_from_adt(*ale, ntree->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSLINESTYLE: {
|
case ANIMTYPE_DSLINESTYLE: {
|
||||||
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)data;
|
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)data;
|
||||||
AnimData *adt = linestyle->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_LS_SCED(linestyle);
|
ale->flag = FILTER_LS_SCED(linestyle);
|
||||||
|
key_data_from_adt(*ale, linestyle->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSPART: {
|
case ANIMTYPE_DSPART: {
|
||||||
ParticleSettings *part = (ParticleSettings *)ale->data;
|
ParticleSettings *part = (ParticleSettings *)ale->data;
|
||||||
AnimData *adt = part->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_PART_OBJD(part);
|
ale->flag = FILTER_PART_OBJD(part);
|
||||||
|
key_data_from_adt(*ale, part->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSTEX: {
|
case ANIMTYPE_DSTEX: {
|
||||||
Tex *tex = (Tex *)data;
|
Tex *tex = (Tex *)data;
|
||||||
AnimData *adt = tex->adt;
|
|
||||||
|
|
||||||
ale->flag = FILTER_TEX_DATA(tex);
|
ale->flag = FILTER_TEX_DATA(tex);
|
||||||
|
key_data_from_adt(*ale, tex->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSGPENCIL: {
|
case ANIMTYPE_DSGPENCIL: {
|
||||||
bGPdata *gpd = (bGPdata *)data;
|
bGPdata *gpd = (bGPdata *)data;
|
||||||
AnimData *adt = gpd->adt;
|
|
||||||
|
|
||||||
/* NOTE: we just reuse the same expand filter for this case */
|
/* NOTE: we just reuse the same expand filter for this case */
|
||||||
ale->flag = EXPANDED_GPD(gpd);
|
ale->flag = EXPANDED_GPD(gpd);
|
||||||
|
|
||||||
/* XXX: currently, this is only used for access to its animation data */
|
/* XXX: currently, this is only used for access to its animation data */
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
key_data_from_adt(*ale, gpd->adt);
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_DSMCLIP: {
|
case ANIMTYPE_DSMCLIP: {
|
||||||
MovieClip *clip = (MovieClip *)data;
|
MovieClip *clip = (MovieClip *)data;
|
||||||
AnimData *adt = clip->adt;
|
|
||||||
|
|
||||||
ale->flag = EXPANDED_MCLIP(clip);
|
ale->flag = EXPANDED_MCLIP(clip);
|
||||||
|
key_data_from_adt(*ale, clip->adt);
|
||||||
ale->key_data = (adt) ? adt->action : nullptr;
|
|
||||||
ale->datatype = ALE_ACT;
|
|
||||||
|
|
||||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ANIMTYPE_NLACONTROLS: {
|
case ANIMTYPE_NLACONTROLS: {
|
||||||
|
|
|
@ -54,6 +54,8 @@ struct AssetItemTree {
|
||||||
assets_per_path;
|
assets_per_path;
|
||||||
/** Assets not added to a catalog, not part of #assets_per_path. */
|
/** Assets not added to a catalog, not part of #assets_per_path. */
|
||||||
Vector<asset_system::AssetRepresentation *> unassigned_assets;
|
Vector<asset_system::AssetRepresentation *> unassigned_assets;
|
||||||
|
/** True if the tree is out of date compared to asset libraries and must be rebuilt. */
|
||||||
|
bool dirty = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
asset_system::AssetCatalogTree build_filtered_catalog_tree(
|
asset_system::AssetCatalogTree build_filtered_catalog_tree(
|
||||||
|
|
|
@ -150,7 +150,8 @@ AssetItemTree build_filtered_all_catalog_tree(
|
||||||
|
|
||||||
return {std::move(catalogs_with_node_assets),
|
return {std::move(catalogs_with_node_assets),
|
||||||
std::move(assets_per_path),
|
std::move(assets_per_path),
|
||||||
std::move(unassigned_assets)};
|
std::move(unassigned_assets),
|
||||||
|
false};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blender::ed::asset
|
} // namespace blender::ed::asset
|
||||||
|
|
|
@ -315,7 +315,7 @@ void AssetClearHelper::reportResults(const bContext *C, ReportList &reports) con
|
||||||
&reports, RPT_INFO, "Data-block '%s' is not an asset anymore", stats.last_id->name + 2);
|
&reports, RPT_INFO, "Data-block '%s' is not an asset anymore", stats.last_id->name + 2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BKE_reportf(&reports, RPT_INFO, "%i data-blocks are no assets anymore", stats.tot_cleared);
|
BKE_reportf(&reports, RPT_INFO, "%i data-blocks are not assets anymore", stats.tot_cleared);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -787,7 +787,7 @@ void clear_operator_asset_trees()
|
||||||
for (const ObjectType type : {OB_MESH, OB_CURVES, OB_POINTCLOUD}) {
|
for (const ObjectType type : {OB_MESH, OB_CURVES, OB_POINTCLOUD}) {
|
||||||
for (const eObjectMode mode : {OB_MODE_OBJECT, OB_MODE_EDIT, OB_MODE_SCULPT_CURVES}) {
|
for (const eObjectMode mode : {OB_MODE_OBJECT, OB_MODE_EDIT, OB_MODE_SCULPT_CURVES}) {
|
||||||
if (asset::AssetItemTree *tree = get_static_item_tree(type, mode)) {
|
if (asset::AssetItemTree *tree = get_static_item_tree(type, mode)) {
|
||||||
*tree = {};
|
tree->dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1105,7 +1105,7 @@ void ui_template_node_operator_asset_root_items(uiLayout &layout, const bContext
|
||||||
if (!tree) {
|
if (!tree) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (tree->assets_per_path.size() == 0) {
|
if (tree->dirty) {
|
||||||
*tree = build_catalog_tree(C, *active_object);
|
*tree = build_catalog_tree(C, *active_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1071,6 +1071,7 @@ void UI_theme_init_default()
|
||||||
BLI_findstring(&U.themes, U_theme_default.name, offsetof(bTheme, name)));
|
BLI_findstring(&U.themes, U_theme_default.name, offsetof(bTheme, name)));
|
||||||
if (btheme == nullptr) {
|
if (btheme == nullptr) {
|
||||||
btheme = MEM_cnew<bTheme>(__func__);
|
btheme = MEM_cnew<bTheme>(__func__);
|
||||||
|
STRNCPY(btheme->name, U_theme_default.name);
|
||||||
BLI_addhead(&U.themes, btheme);
|
BLI_addhead(&U.themes, btheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "sculpt_intern.hh"
|
#include "sculpt_intern.hh"
|
||||||
|
|
||||||
namespace blender::ed::sculpt_paint::trim {
|
namespace blender::ed::sculpt_paint::trim {
|
||||||
|
|
||||||
enum class OperationType {
|
enum class OperationType {
|
||||||
Intersect = 0,
|
Intersect = 0,
|
||||||
Difference = 1,
|
Difference = 1,
|
||||||
|
@ -112,6 +113,10 @@ struct TrimOperation {
|
||||||
/* Operator properties. */
|
/* Operator properties. */
|
||||||
bool use_cursor_depth;
|
bool use_cursor_depth;
|
||||||
|
|
||||||
|
bool initial_hit;
|
||||||
|
blender::float3 initial_location;
|
||||||
|
blender::float3 initial_normal;
|
||||||
|
|
||||||
OperationType mode;
|
OperationType mode;
|
||||||
SolverMode solver_mode;
|
SolverMode solver_mode;
|
||||||
OrientationType orientation;
|
OrientationType orientation;
|
||||||
|
@ -166,17 +171,17 @@ static void get_origin_and_normal(gesture::GestureData &gesture_data,
|
||||||
case OrientationType::View:
|
case OrientationType::View:
|
||||||
mul_v3_m4v3(r_origin,
|
mul_v3_m4v3(r_origin,
|
||||||
gesture_data.vc.obact->object_to_world().ptr(),
|
gesture_data.vc.obact->object_to_world().ptr(),
|
||||||
gesture_data.ss->gesture_initial_location);
|
trim_operation->initial_location);
|
||||||
copy_v3_v3(r_normal, gesture_data.world_space_view_normal);
|
copy_v3_v3(r_normal, gesture_data.world_space_view_normal);
|
||||||
negate_v3(r_normal);
|
negate_v3(r_normal);
|
||||||
break;
|
break;
|
||||||
case OrientationType::Surface:
|
case OrientationType::Surface:
|
||||||
mul_v3_m4v3(r_origin,
|
mul_v3_m4v3(r_origin,
|
||||||
gesture_data.vc.obact->object_to_world().ptr(),
|
gesture_data.vc.obact->object_to_world().ptr(),
|
||||||
gesture_data.ss->gesture_initial_location);
|
trim_operation->initial_location);
|
||||||
/* Transforming the normal does not take non uniform scaling into account. Sculpt mode is not
|
/* Transforming the normal does not take non uniform scaling into account. Sculpt mode is not
|
||||||
* expected to work on object with non uniform scaling. */
|
* expected to work on object with non uniform scaling. */
|
||||||
copy_v3_v3(r_normal, gesture_data.ss->gesture_initial_normal);
|
copy_v3_v3(r_normal, trim_operation->initial_normal);
|
||||||
mul_mat3_m4_v3(gesture_data.vc.obact->object_to_world().ptr(), r_normal);
|
mul_mat3_m4_v3(gesture_data.vc.obact->object_to_world().ptr(), r_normal);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -221,11 +226,11 @@ static void calculate_depth(gesture::GestureData &gesture_data,
|
||||||
float world_space_gesture_initial_location[3];
|
float world_space_gesture_initial_location[3];
|
||||||
mul_v3_m4v3(world_space_gesture_initial_location,
|
mul_v3_m4v3(world_space_gesture_initial_location,
|
||||||
vc->obact->object_to_world().ptr(),
|
vc->obact->object_to_world().ptr(),
|
||||||
ss->gesture_initial_location);
|
trim_operation->initial_location);
|
||||||
|
|
||||||
float mid_point_depth;
|
float mid_point_depth;
|
||||||
if (trim_operation->orientation == OrientationType::View) {
|
if (trim_operation->orientation == OrientationType::View) {
|
||||||
mid_point_depth = ss->gesture_initial_hit ?
|
mid_point_depth = trim_operation->initial_hit ?
|
||||||
dist_signed_to_plane_v3(world_space_gesture_initial_location,
|
dist_signed_to_plane_v3(world_space_gesture_initial_location,
|
||||||
shape_plane) :
|
shape_plane) :
|
||||||
(depth_back + depth_front) * 0.5f;
|
(depth_back + depth_front) * 0.5f;
|
||||||
|
@ -234,12 +239,12 @@ static void calculate_depth(gesture::GestureData &gesture_data,
|
||||||
/* When using normal orientation, if the stroke started over the mesh, position the mid point
|
/* When using normal orientation, if the stroke started over the mesh, position the mid point
|
||||||
* at 0 distance from the shape plane. This positions the trimming shape half inside of the
|
* at 0 distance from the shape plane. This positions the trimming shape half inside of the
|
||||||
* surface. */
|
* surface. */
|
||||||
mid_point_depth = ss->gesture_initial_hit ? 0.0f : (depth_back + depth_front) * 0.5f;
|
mid_point_depth = trim_operation->initial_hit ? 0.0f : (depth_back + depth_front) * 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float depth_radius;
|
float depth_radius;
|
||||||
|
|
||||||
if (ss->gesture_initial_hit) {
|
if (trim_operation->initial_hit) {
|
||||||
depth_radius = ss->cursor_radius;
|
depth_radius = ss->cursor_radius;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -254,7 +259,7 @@ static void calculate_depth(gesture::GestureData &gesture_data,
|
||||||
|
|
||||||
if (!BKE_brush_use_locked_size(scene, brush)) {
|
if (!BKE_brush_use_locked_size(scene, brush)) {
|
||||||
depth_radius = paint_calc_object_space_radius(
|
depth_radius = paint_calc_object_space_radius(
|
||||||
vc, ss->gesture_initial_location, BKE_brush_size_get(scene, brush));
|
vc, trim_operation->initial_location, BKE_brush_size_get(scene, brush));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
depth_radius = BKE_brush_unprojected_radius_get(scene, brush);
|
depth_radius = BKE_brush_unprojected_radius_get(scene, brush);
|
||||||
|
@ -609,13 +614,27 @@ static void init_operation(gesture::GestureData &gesture_data, wmOperator &op)
|
||||||
trim_operation->solver_mode = SolverMode(RNA_enum_get(op.ptr, "trim_solver"));
|
trim_operation->solver_mode = SolverMode(RNA_enum_get(op.ptr, "trim_solver"));
|
||||||
|
|
||||||
/* If the cursor was not over the mesh, force the orientation to view. */
|
/* If the cursor was not over the mesh, force the orientation to view. */
|
||||||
if (!gesture_data.ss->gesture_initial_hit) {
|
if (!trim_operation->initial_hit) {
|
||||||
trim_operation->orientation = OrientationType::View;
|
trim_operation->orientation = OrientationType::View;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void operator_properties(wmOperatorType *ot)
|
static void operator_properties(wmOperatorType *ot)
|
||||||
{
|
{
|
||||||
|
PropertyRNA *prop;
|
||||||
|
|
||||||
|
prop = RNA_def_int_vector(ot->srna,
|
||||||
|
"location",
|
||||||
|
2,
|
||||||
|
nullptr,
|
||||||
|
INT_MIN,
|
||||||
|
INT_MAX,
|
||||||
|
"Location",
|
||||||
|
"Mouse location",
|
||||||
|
INT_MIN,
|
||||||
|
INT_MAX);
|
||||||
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||||
|
|
||||||
RNA_def_enum(ot->srna,
|
RNA_def_enum(ot->srna,
|
||||||
"trim_mode",
|
"trim_mode",
|
||||||
operation_types,
|
operation_types,
|
||||||
|
@ -672,21 +691,26 @@ static bool can_exec(const bContext &C)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initialize_cursor_info(bContext &C, const wmEvent *event)
|
static void initialize_cursor_info(bContext &C,
|
||||||
|
const wmOperator &op,
|
||||||
|
gesture::GestureData &gesture_data)
|
||||||
{
|
{
|
||||||
const Object &ob = *CTX_data_active_object(&C);
|
const Object &ob = *CTX_data_active_object(&C);
|
||||||
SculptSession &ss = *ob.sculpt;
|
SculptSession &ss = *ob.sculpt;
|
||||||
|
|
||||||
SCULPT_vertex_random_access_ensure(&ss);
|
SCULPT_vertex_random_access_ensure(&ss);
|
||||||
|
|
||||||
SculptCursorGeometryInfo sgi;
|
int mval[2];
|
||||||
const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
|
RNA_int_get_array(op.ptr, "location", mval);
|
||||||
|
|
||||||
/* TODO: Remove gesture_* properties from SculptSession */
|
SculptCursorGeometryInfo sgi;
|
||||||
ss.gesture_initial_hit = SCULPT_cursor_geometry_info_update(&C, &sgi, mval_fl, false);
|
const float mval_fl[2] = {float(mval[0]), float(mval[1])};
|
||||||
if (ss.gesture_initial_hit) {
|
|
||||||
copy_v3_v3(ss.gesture_initial_location, sgi.location);
|
TrimOperation *trim_operation = (TrimOperation *)gesture_data.operation;
|
||||||
copy_v3_v3(ss.gesture_initial_normal, sgi.normal);
|
trim_operation->initial_hit = SCULPT_cursor_geometry_info_update(&C, &sgi, mval_fl, false);
|
||||||
|
if (trim_operation->initial_hit) {
|
||||||
|
copy_v3_v3(trim_operation->initial_location, sgi.location);
|
||||||
|
copy_v3_v3(trim_operation->initial_normal, sgi.normal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,7 +725,9 @@ static int gesture_box_exec(bContext *C, wmOperator *op)
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialize_cursor_info(*C, *op, *gesture_data);
|
||||||
init_operation(*gesture_data, *op);
|
init_operation(*gesture_data, *op);
|
||||||
|
|
||||||
gesture::apply(*C, *gesture_data, *op);
|
gesture::apply(*C, *gesture_data, *op);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
@ -712,7 +738,7 @@ static int gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize_cursor_info(*C, event);
|
RNA_int_set_array(op->ptr, "location", event->mval);
|
||||||
|
|
||||||
return WM_gesture_box_invoke(C, op, event);
|
return WM_gesture_box_invoke(C, op, event);
|
||||||
}
|
}
|
||||||
|
@ -727,7 +753,10 @@ static int gesture_lasso_exec(bContext *C, wmOperator *op)
|
||||||
if (!gesture_data) {
|
if (!gesture_data) {
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialize_cursor_info(*C, *op, *gesture_data);
|
||||||
init_operation(*gesture_data, *op);
|
init_operation(*gesture_data, *op);
|
||||||
|
|
||||||
gesture::apply(*C, *gesture_data, *op);
|
gesture::apply(*C, *gesture_data, *op);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
@ -738,7 +767,7 @@ static int gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize_cursor_info(*C, event);
|
RNA_int_set_array(op->ptr, "location", event->mval);
|
||||||
|
|
||||||
return WM_gesture_lasso_invoke(C, op, event);
|
return WM_gesture_lasso_invoke(C, op, event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,8 +242,10 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
|
||||||
graph_draw_curves(&ac, sipo, region, 1);
|
graph_draw_curves(&ac, sipo, region, 1);
|
||||||
|
|
||||||
/* XXX(ton): the slow way to set tot rect... but for nice sliders needed. */
|
/* XXX(ton): the slow way to set tot rect... but for nice sliders needed. */
|
||||||
|
/* Excluding handles from the calculation to save performance. This cuts the time it takes for
|
||||||
|
* this function to run in half which is a major performance bottleneck on heavy scenes. */
|
||||||
get_graph_keyframe_extents(
|
get_graph_keyframe_extents(
|
||||||
&ac, &v2d->tot.xmin, &v2d->tot.xmax, &v2d->tot.ymin, &v2d->tot.ymax, false, true);
|
&ac, &v2d->tot.xmin, &v2d->tot.xmax, &v2d->tot.ymin, &v2d->tot.ymax, false, false);
|
||||||
/* extra offset so that these items are visible */
|
/* extra offset so that these items are visible */
|
||||||
v2d->tot.xmin -= 10.0f;
|
v2d->tot.xmin -= 10.0f;
|
||||||
v2d->tot.xmax += 10.0f;
|
v2d->tot.xmax += 10.0f;
|
||||||
|
|
|
@ -2340,7 +2340,7 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
|
||||||
|
|
||||||
RNA_def_boolean(ot->srna,
|
RNA_def_boolean(ot->srna,
|
||||||
"do_recursive",
|
"do_recursive",
|
||||||
false,
|
true,
|
||||||
"Recursive Delete",
|
"Recursive Delete",
|
||||||
"Recursively check for indirectly unused data-blocks, ensuring that no orphaned "
|
"Recursively check for indirectly unused data-blocks, ensuring that no orphaned "
|
||||||
"data-blocks remain after execution");
|
"data-blocks remain after execution");
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "BKE_report.hh"
|
#include "BKE_report.hh"
|
||||||
|
|
||||||
#include "BLI_string.h"
|
#include "BLI_string.h"
|
||||||
|
#include "BLI_string_utils.hh"
|
||||||
|
|
||||||
#include "DEG_depsgraph_query.hh"
|
#include "DEG_depsgraph_query.hh"
|
||||||
|
|
||||||
|
@ -72,14 +73,16 @@ void export_frame(Depsgraph *depsgraph,
|
||||||
/* If exporting in batch, create writer for each iteration over objects. */
|
/* If exporting in batch, create writer for each iteration over objects. */
|
||||||
if (export_params.use_batch) {
|
if (export_params.use_batch) {
|
||||||
/* Get object name by skipping initial "OB" prefix. */
|
/* Get object name by skipping initial "OB" prefix. */
|
||||||
std::string object_name = (object->id.name + 2);
|
char object_name[sizeof(object->id.name) - 2];
|
||||||
|
STRNCPY(object_name, object->id.name + 2);
|
||||||
|
BLI_path_make_safe_filename(object_name);
|
||||||
/* Replace spaces with underscores. */
|
/* Replace spaces with underscores. */
|
||||||
std::replace(object_name.begin(), object_name.end(), ' ', '_');
|
BLI_string_replace_char(object_name, ' ', '_');
|
||||||
|
|
||||||
/* Include object name in the exported file name. */
|
/* Include object name in the exported file name. */
|
||||||
char filepath[FILE_MAX];
|
char filepath[FILE_MAX];
|
||||||
STRNCPY(filepath, export_params.filepath);
|
STRNCPY(filepath, export_params.filepath);
|
||||||
BLI_path_suffix(filepath, FILE_MAX, object_name.c_str(), "");
|
BLI_path_suffix(filepath, FILE_MAX, object_name, "");
|
||||||
/* Make sure we have .stl extension (case insensitive). */
|
/* Make sure we have .stl extension (case insensitive). */
|
||||||
if (!BLI_path_extension_check(filepath, ".stl")) {
|
if (!BLI_path_extension_check(filepath, ".stl")) {
|
||||||
BLI_path_extension_ensure(filepath, FILE_MAX, ".stl");
|
BLI_path_extension_ensure(filepath, FILE_MAX, ".stl");
|
||||||
|
|
|
@ -493,6 +493,16 @@ typedef struct bTheme {
|
||||||
|
|
||||||
/* NOTE: Values after `name` are copied when resetting the default theme. */
|
/* NOTE: Values after `name` are copied when resetting the default theme. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file-path for the preset that was loaded into this theme.
|
||||||
|
*
|
||||||
|
* This is needed so it's possible to know if updating or removing a theme preset
|
||||||
|
* should apply changes to the current theme.
|
||||||
|
*
|
||||||
|
* #FILE_MAX.
|
||||||
|
*/
|
||||||
|
char filepath[1024];
|
||||||
|
|
||||||
ThemeUI tui;
|
ThemeUI tui;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6333,7 +6333,7 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
|
||||||
{AV_CODEC_ID_MPEG2VIDEO, "MPEG2", 0, "MPEG-2", ""},
|
{AV_CODEC_ID_MPEG2VIDEO, "MPEG2", 0, "MPEG-2", ""},
|
||||||
{AV_CODEC_ID_MPEG4, "MPEG4", 0, "MPEG-4 (divx)", ""},
|
{AV_CODEC_ID_MPEG4, "MPEG4", 0, "MPEG-4 (divx)", ""},
|
||||||
{AV_CODEC_ID_PNG, "PNG", 0, "PNG", ""},
|
{AV_CODEC_ID_PNG, "PNG", 0, "PNG", ""},
|
||||||
{AV_CODEC_ID_QTRLE, "QTRLE", 0, "QT rle / QT Animation", ""},
|
{AV_CODEC_ID_QTRLE, "QTRLE", 0, "QuickTime Animation", ""},
|
||||||
{AV_CODEC_ID_THEORA, "THEORA", 0, "Theora", ""},
|
{AV_CODEC_ID_THEORA, "THEORA", 0, "Theora", ""},
|
||||||
{AV_CODEC_ID_VP9, "WEBM", 0, "WebM / VP9", ""},
|
{AV_CODEC_ID_VP9, "WEBM", 0, "WebM / VP9", ""},
|
||||||
{AV_CODEC_ID_AV1, "AV1", 0, "AV1", ""},
|
{AV_CODEC_ID_AV1, "AV1", 0, "AV1", ""},
|
||||||
|
|
|
@ -4301,6 +4301,11 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
|
||||||
/* XXX: for now putting this in presets is silly - its just Default */
|
/* XXX: for now putting this in presets is silly - its just Default */
|
||||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
|
||||||
|
RNA_def_property_string_sdna(prop, nullptr, "filepath");
|
||||||
|
RNA_def_property_ui_text(
|
||||||
|
prop, "File Path", "The path to the preset loaded into this theme (if any)");
|
||||||
|
|
||||||
prop = RNA_def_property(srna, "theme_area", PROP_ENUM, PROP_NONE);
|
prop = RNA_def_property(srna, "theme_area", PROP_ENUM, PROP_NONE);
|
||||||
RNA_def_property_enum_sdna(prop, nullptr, "active_theme_area");
|
RNA_def_property_enum_sdna(prop, nullptr, "active_theme_area");
|
||||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||||
|
|
|
@ -333,29 +333,10 @@ if(WITH_PYTHON_MODULE)
|
||||||
else()
|
else()
|
||||||
add_executable(blender ${EXETYPE} ${SRC})
|
add_executable(blender ${EXETYPE} ${SRC})
|
||||||
if(WITH_CPU_CHECK)
|
if(WITH_CPU_CHECK)
|
||||||
target_compile_definitions(blender PRIVATE WITH_CPU_CHECK)
|
|
||||||
# we cannot directly link against any blender libraries for the cpu_check module
|
|
||||||
# as they may have been build for an ISA that is unsupported by the CPU
|
|
||||||
# running this code.
|
|
||||||
add_library(blender_cpu_check SHARED
|
|
||||||
creator_cpu_check.cc
|
|
||||||
)
|
|
||||||
target_link_libraries(blender_cpu_check
|
|
||||||
PRIVATE ${PLATFORM_LINKLIBS}
|
|
||||||
)
|
|
||||||
# blender_cpu_check *NEEDS* to be linked first, there can be no exceptions
|
# blender_cpu_check *NEEDS* to be linked first, there can be no exceptions
|
||||||
# to this, this is to ensure this will be the first code to run once the
|
# to this, this is to ensure this will be the first code to run once the
|
||||||
# blender binary has been loaded by the OS.
|
# blender binary has been loaded by the OS.
|
||||||
target_link_libraries(blender PRIVATE blender_cpu_check)
|
target_link_libraries(blender PRIVATE blender_cpu_check)
|
||||||
if(NOT WIN32)
|
|
||||||
set(_LIB_SUB_FOLDER "lib/")
|
|
||||||
endif()
|
|
||||||
set_target_properties(blender_cpu_check
|
|
||||||
PROPERTIES
|
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${_LIB_SUB_FOLDER}"
|
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${_LIB_SUB_FOLDER}"
|
|
||||||
)
|
|
||||||
unset(_LIB_SUB_FOLDER)
|
|
||||||
endif()
|
endif()
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_executable(blender-launcher WIN32
|
add_executable(blender-launcher WIN32
|
||||||
|
|
|
@ -107,7 +107,7 @@ class MeshExportTest4(AbstractColladaTest):
|
||||||
outfile = tempdir / Path("%s_out.dae" % test)
|
outfile = tempdir / Path("%s_out.dae" % test)
|
||||||
|
|
||||||
bpy.ops.wm.collada_export(
|
bpy.ops.wm.collada_export(
|
||||||
filepath="%s" % str(outfile),
|
filepath=str(outfile),
|
||||||
check_existing=True,
|
check_existing=True,
|
||||||
filemode=8,
|
filemode=8,
|
||||||
display_type='DEFAULT',
|
display_type='DEFAULT',
|
||||||
|
@ -151,7 +151,7 @@ class MeshExportTest3(AbstractColladaTest):
|
||||||
outfile = tempdir / Path("%s_out.dae" % test)
|
outfile = tempdir / Path("%s_out.dae" % test)
|
||||||
|
|
||||||
bpy.ops.wm.collada_export(
|
bpy.ops.wm.collada_export(
|
||||||
filepath="%s" % str(outfile),
|
filepath=str(outfile),
|
||||||
check_existing=True,
|
check_existing=True,
|
||||||
filemode=8,
|
filemode=8,
|
||||||
display_type='DEFAULT',
|
display_type='DEFAULT',
|
||||||
|
@ -195,7 +195,7 @@ class MeshExportTest2(AbstractColladaTest):
|
||||||
outfile = tempdir / Path("%s_out.dae" % test)
|
outfile = tempdir / Path("%s_out.dae" % test)
|
||||||
|
|
||||||
bpy.ops.wm.collada_export(
|
bpy.ops.wm.collada_export(
|
||||||
filepath="%s" % str(outfile),
|
filepath=str(outfile),
|
||||||
check_existing=True,
|
check_existing=True,
|
||||||
filemode=8,
|
filemode=8,
|
||||||
display_type='DEFAULT',
|
display_type='DEFAULT',
|
||||||
|
@ -239,7 +239,7 @@ class MeshExportTest1(AbstractColladaTest):
|
||||||
outfile = tempdir / Path("%s_out.dae" % test)
|
outfile = tempdir / Path("%s_out.dae" % test)
|
||||||
|
|
||||||
bpy.ops.wm.collada_export(
|
bpy.ops.wm.collada_export(
|
||||||
filepath="%s" % str(outfile),
|
filepath=str(outfile),
|
||||||
check_existing=True,
|
check_existing=True,
|
||||||
filemode=8,
|
filemode=8,
|
||||||
display_type='DEFAULT',
|
display_type='DEFAULT',
|
||||||
|
|
|
@ -107,7 +107,7 @@ class MeshExportTest(AbstractColladaTest):
|
||||||
outfile = tempdir / Path("%s_out.dae" % test)
|
outfile = tempdir / Path("%s_out.dae" % test)
|
||||||
|
|
||||||
bpy.ops.wm.collada_export(
|
bpy.ops.wm.collada_export(
|
||||||
filepath="%s" % str(outfile),
|
filepath=str(outfile),
|
||||||
check_existing=True,
|
check_existing=True,
|
||||||
filemode=8,
|
filemode=8,
|
||||||
display_type="DEFAULT",
|
display_type="DEFAULT",
|
||||||
|
|
|
@ -1638,7 +1638,7 @@ class edit_generators:
|
||||||
):
|
):
|
||||||
edits.append(Edit(
|
edits.append(Edit(
|
||||||
span=match.span(),
|
span=match.span(),
|
||||||
content='%s' % match.group(2),
|
content=match.group(2),
|
||||||
content_fail='__ALWAYS_FAIL__',
|
content_fail='__ALWAYS_FAIL__',
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue