Geometry Node: Multi-input socket tooltip #104468
|
@ -1399,13 +1399,12 @@ endif()
|
|||
|
||||
# Test SIMD support, before platform includes to determine if sse2neon is needed.
|
||||
if(WITH_CPU_SIMD)
|
||||
set(COMPILER_SSE_FLAG)
|
||||
set(COMPILER_SSE2_FLAG)
|
||||
set(COMPILER_SSE42_FLAG)
|
||||
|
||||
# Test Neon first since macOS Arm can compile and run x86-64 SSE binaries.
|
||||
test_neon_support()
|
||||
if(NOT SUPPORT_NEON_BUILD)
|
||||
test_sse_support(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
|
||||
test_sse_support(COMPILER_SSE42_FLAG)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -1445,8 +1444,6 @@ endif()
|
|||
|
||||
# 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(SUPPORT_NEON_BUILD)
|
||||
# Neon
|
||||
|
@ -1456,15 +1453,20 @@ if(WITH_CPU_SIMD)
|
|||
endif()
|
||||
else()
|
||||
# SSE
|
||||
if(SUPPORT_SSE_BUILD)
|
||||
string(PREPEND PLATFORM_CFLAGS "${COMPILER_SSE_FLAG} ")
|
||||
add_definitions(-D__SSE__ -D__MMX__)
|
||||
endif()
|
||||
if(SUPPORT_SSE2_BUILD)
|
||||
string(APPEND PLATFORM_CFLAGS " ${COMPILER_SSE2_FLAG}")
|
||||
add_definitions(-D__SSE2__)
|
||||
if(NOT SUPPORT_SSE_BUILD) # don't double up
|
||||
add_definitions(-D__MMX__)
|
||||
if(SUPPORT_SSE42_BUILD)
|
||||
string(APPEND CMAKE_CXX_FLAGS " ${COMPILER_SSE42_FLAG}")
|
||||
string(APPEND CMAKE_C_FLAGS " ${COMPILER_SSE42_FLAG}")
|
||||
# MSVC doesn't define any of these and only does the AVX and higher flags.
|
||||
# For consistency we define these flags for MSVC.
|
||||
if(WIN32)
|
||||
add_compile_definitions(
|
||||
__MMX__
|
||||
__SSE__
|
||||
__SSE2__
|
||||
__SSE3__
|
||||
__SSE4_1__
|
||||
__SSE4_2__
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
@ -1479,10 +1481,8 @@ if(FIRST_RUN)
|
|||
else()
|
||||
message(STATUS "Neon SIMD instructions detected but unused, requires sse2neon")
|
||||
endif()
|
||||
elseif(SUPPORT_SSE2_BUILD)
|
||||
message(STATUS "SSE2 SIMD instructions enabled")
|
||||
elseif(SUPPORT_SSE_BUILD)
|
||||
message(STATUS "SSE SIMD instructions enabled")
|
||||
elseif(SUPPORT_SSE42_BUILD)
|
||||
message(STATUS "SSE42 SIMD instructions enabled")
|
||||
else()
|
||||
message(STATUS "No SIMD instructions detected")
|
||||
endif()
|
||||
|
|
|
@ -540,49 +540,37 @@ function(setup_platform_linker_libs
|
|||
endfunction()
|
||||
|
||||
macro(TEST_SSE_SUPPORT
|
||||
_sse_flags
|
||||
_sse2_flags)
|
||||
_sse42_flags)
|
||||
|
||||
include(CheckCSourceRuns)
|
||||
|
||||
# message(STATUS "Detecting SSE support")
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
|
||||
set(${_sse_flags} "-msse")
|
||||
set(${_sse2_flags} "-msse2")
|
||||
set(${_sse42_flags} "-march=x86-64-v2")
|
||||
elseif(MSVC)
|
||||
# x86_64 has this auto enabled
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(${_sse_flags} "")
|
||||
set(${_sse2_flags} "")
|
||||
else()
|
||||
set(${_sse_flags} "/arch:SSE")
|
||||
set(${_sse2_flags} "/arch:SSE2")
|
||||
endif()
|
||||
# msvc has no specific build flags for SSE42, but when using intrinsics it will
|
||||
# generate the right instructions.
|
||||
set(${_sse42_flags} "")
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel")
|
||||
set(${_sse_flags} "") # icc defaults to -msse
|
||||
set(${_sse2_flags} "") # icc defaults to -msse2
|
||||
if(WIN32)
|
||||
set(${_sse42_flags} "/QxSSE4.2")
|
||||
else()
|
||||
set(${_sse42_flags} "-xsse4.2")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "SSE flags for this compiler: '${CMAKE_C_COMPILER_ID}' not known")
|
||||
set(${_sse_flags})
|
||||
set(${_sse2_flags})
|
||||
set(${_sse42_flags})
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS "${${_sse_flags}} ${${_sse2_flags}}")
|
||||
set(CMAKE_REQUIRED_FLAGS "${${_sse42_flags}}")
|
||||
|
||||
if(NOT DEFINED SUPPORT_SSE_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)
|
||||
if(NOT DEFINED SUPPORT_SSE42_BUILD)
|
||||
# result cached
|
||||
check_c_source_runs("
|
||||
#include <nmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
int main(void) { __m128d v = _mm_setzero_pd(); return 0; }"
|
||||
SUPPORT_SSE2_BUILD)
|
||||
int main(void) { __m128i v = _mm_setzero_si128(); v = _mm_cmpgt_epi64(v,v); return 0; }"
|
||||
SUPPORT_SSE42_BUILD)
|
||||
endif()
|
||||
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
|
|
|
@ -21,4 +21,4 @@ if "Cube" in bpy.data.meshes:
|
|||
import os
|
||||
with open(os.path.splitext(bpy.data.filepath)[0] + ".txt", 'w') as fs:
|
||||
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):
|
||||
self.report(
|
||||
{'INFO'}, 'F: %.2f B: %s S: %r' %
|
||||
(self.my_float, self.my_bool, self.my_string)
|
||||
{'INFO'}, "F: {:.2f} B: {:s} S: {!r}".format(
|
||||
self.my_float, self.my_bool, self.my_string,
|
||||
)
|
||||
)
|
||||
print('My float:', self.my_float)
|
||||
print('My bool:', self.my_bool)
|
||||
|
|
|
@ -53,9 +53,9 @@ class OBJECT_OT_addon_prefs_example(Operator):
|
|||
preferences = context.preferences
|
||||
addon_prefs = preferences.addons[__name__].preferences
|
||||
|
||||
info = ("Path: %s, Number: %d, Boolean %r" %
|
||||
(addon_prefs.filepath, addon_prefs.number, addon_prefs.boolean))
|
||||
|
||||
info = "Path: {:s}, Number: {:d}, Boolean {!r}".format(
|
||||
addon_prefs.filepath, addon_prefs.number, addon_prefs.boolean,
|
||||
)
|
||||
self.report({'INFO'}, info)
|
||||
print(info)
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ import bpy
|
|||
|
||||
def dump(obj, text):
|
||||
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):
|
||||
|
|
|
@ -31,10 +31,10 @@ me = bpy.context.object.data
|
|||
uv_layer = me.uv_layers.active.data
|
||||
|
||||
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,
|
||||
# for convenience 'poly.loop_indices' can be used instead.
|
||||
for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
|
||||
print(" Vertex: %d" % me.loops[loop_index].vertex_index)
|
||||
print(" UV: %r" % uv_layer[loop_index].uv)
|
||||
print(" Vertex: {:d}".format(me.loops[loop_index].vertex_index))
|
||||
print(" UV: {!r}".format(uv_layer[loop_index].uv))
|
||||
|
|
|
@ -34,7 +34,7 @@ class SimpleMouseOperator(bpy.types.Operator):
|
|||
def execute(self, context):
|
||||
# rather than printing, use the report function,
|
||||
# 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'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
|
|
|
@ -16,9 +16,8 @@ class DialogOperator(bpy.types.Operator):
|
|||
my_string: bpy.props.StringProperty(name="String Value")
|
||||
|
||||
def execute(self, context):
|
||||
message = (
|
||||
"Popup Values: %f, %d, '%s'" %
|
||||
(self.my_float, self.my_bool, self.my_string)
|
||||
message = "Popup Values: {:f}, {:d}, '{:s}'".format(
|
||||
self.my_float, self.my_bool, self.my_string,
|
||||
)
|
||||
self.report({'INFO'}, message)
|
||||
return {'FINISHED'}
|
||||
|
|
|
@ -10,21 +10,21 @@ col.s *= 0.5
|
|||
print("Color R:", col.r)
|
||||
print("Color G:", 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
|
||||
col[:] = 0.0, 0.5, 1.0
|
||||
|
||||
# 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
|
||||
col += mathutils.Color((0.25, 0.0, 0.0))
|
||||
|
||||
# Color can be multiplied, in this example color is scaled to 0-255
|
||||
# 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
|
||||
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
|
||||
|
||||
# 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
|
||||
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("Final Rotation:")
|
||||
print(quat_out)
|
||||
print("%.2f, %.2f, %.2f" % tuple(math.degrees(a) for a in quat_out.to_euler()))
|
||||
print("(%.2f, %.2f, %.2f), %.2f" % (quat_out.axis[:] +
|
||||
(math.degrees(quat_out.angle), )))
|
||||
print("{:.2f}, {:.2f}, {:.2f}".format(*(math.degrees(a) for a in quat_out.to_euler())))
|
||||
print("({:.2f}, {:.2f}, {:.2f}), {:.2f}".format(*quat_out.axis, math.degrees(quat_out.angle)))
|
||||
|
||||
# multiple rotations can be interpolated using the exponential map
|
||||
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"
|
||||
|
||||
@staticmethod
|
||||
def post_cb(context):
|
||||
def post_cb(context, _filepath):
|
||||
# Modify an arbitrary built-in scene property to force a depsgraph
|
||||
# update, because add-on properties don't. (see #62325)
|
||||
render = context.scene.render
|
||||
|
|
|
@ -332,7 +332,7 @@ class InfoPropertyRNA:
|
|||
self.default_str = "\"%s\"" % self.default
|
||||
elif self.type == "enum":
|
||||
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]
|
||||
else:
|
||||
self.default_str = "'%s'" % self.default
|
||||
|
|
|
@ -818,7 +818,7 @@ class TransformsToDeltasAnim(Operator):
|
|||
if fcu.array_index in existingFCurves[dpath]:
|
||||
# conflict
|
||||
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") %
|
||||
(obj.name, dpath))
|
||||
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:
|
||||
"""Base preset class, only for subclassing
|
||||
subclasses must define
|
||||
|
@ -241,8 +260,7 @@ class ExecutePreset(Operator):
|
|||
self.report({'ERROR'}, rpt_("Unknown file type: %r") % ext)
|
||||
return {'CANCELLED'}
|
||||
|
||||
if hasattr(preset_class, "reset_cb"):
|
||||
preset_class.reset_cb(context)
|
||||
_call_preset_cb(getattr(preset_class, "reset_cb", None), context, filepath)
|
||||
|
||||
if ext == ".py":
|
||||
try:
|
||||
|
@ -254,8 +272,7 @@ class ExecutePreset(Operator):
|
|||
import rna_xml
|
||||
rna_xml.xml_file_run(context, filepath, preset_class.preset_xml_map)
|
||||
|
||||
if hasattr(preset_class, "post_cb"):
|
||||
preset_class.post_cb(context)
|
||||
_call_preset_cb(getattr(preset_class, "post_cb", None), context, filepath)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
@ -637,6 +654,8 @@ class SavePresetInterfaceTheme(AddPresetBase, Operator):
|
|||
traceback.print_exc()
|
||||
return {'CANCELLED'}
|
||||
|
||||
context.preferences.themes[0].filepath = filepath
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
|
|
|
@ -166,7 +166,7 @@ class PlayRenderedAnim(Operator):
|
|||
opts = ["-fps", str(rd.fps), "-play"]
|
||||
if scene.use_preview_range:
|
||||
opts += [
|
||||
"%s" % file.replace("#", "", file.count('#') - 1),
|
||||
file.replace("#", "", file.count('#') - 1),
|
||||
"%d-%d" % (frame_start, frame_end),
|
||||
]
|
||||
else:
|
||||
|
|
|
@ -66,7 +66,7 @@ class OUTLINER_HT_header(Header):
|
|||
layout.operator("outliner.collection_new", text="", icon='COLLECTION_NEW').nested = True
|
||||
|
||||
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':
|
||||
layout.separator()
|
||||
|
|
|
@ -860,21 +860,37 @@ class USERPREF_MT_interface_theme_presets(Menu):
|
|||
draw = Menu.draw_preset
|
||||
|
||||
@staticmethod
|
||||
def reset_cb(context):
|
||||
def reset_cb(_context, _filepath):
|
||||
bpy.ops.preferences.reset_default_theme()
|
||||
|
||||
@staticmethod
|
||||
def post_cb(context, filepath):
|
||||
context.preferences.themes[0].filepath = filepath
|
||||
|
||||
|
||||
class USERPREF_PT_theme(ThemePanel, Panel):
|
||||
bl_label = "Themes"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
|
||||
def draw(self, _context):
|
||||
def draw(self, context):
|
||||
import os
|
||||
|
||||
layout = self.layout
|
||||
|
||||
split = layout.split(factor=0.6)
|
||||
|
||||
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_remove", text="", icon='REMOVE')
|
||||
row.operator("wm.interface_theme_preset_save", text="", icon='FILE_TICK')
|
||||
|
|
|
@ -108,7 +108,7 @@ class MyCustomShapeWidget(Gizmo):
|
|||
delta /= 10.0
|
||||
value = self.init_value - delta
|
||||
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'}
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import bpy
|
|||
def write_some_data(context, filepath, use_some_setting):
|
||||
print("running write_some_data...")
|
||||
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()
|
||||
|
||||
return {'FINISHED'}
|
||||
|
|
|
@ -26,7 +26,7 @@ class ViewOperator(bpy.types.Operator):
|
|||
if event.type == 'MOUSEMOVE':
|
||||
self.offset = (self._initial_mouse - Vector((event.mouse_x, event.mouse_y, 0.0))) * 0.02
|
||||
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':
|
||||
context.area.header_text_set(None)
|
||||
|
|
|
@ -39,7 +39,7 @@ def enum_previews_from_directory_items(self, context):
|
|||
if directory == pcoll.my_previews_dir:
|
||||
return pcoll.my_previews
|
||||
|
||||
print("Scanning directory: %s" % directory)
|
||||
print("Scanning directory:", directory)
|
||||
|
||||
if directory and os.path.exists(directory):
|
||||
# Scan the directory for `*.png` files
|
||||
|
|
|
@ -181,3 +181,7 @@ endif()
|
|||
if(WITH_FREESTYLE)
|
||||
add_subdirectory(freestyle)
|
||||
endif()
|
||||
|
||||
if(WITH_CPU_CHECK)
|
||||
add_subdirectory(cpucheck)
|
||||
endif()
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format 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
|
||||
* 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_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 */
|
||||
RegionView3D *rv3d;
|
||||
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)
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
* build. */
|
||||
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)) {
|
||||
|
@ -145,7 +145,7 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
|
|||
FROM_DEFAULT_V4_UCHAR(space_console.console_cursor);
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(402, 14)) {
|
||||
if (!USER_VERSION_ATLEAST(402, 16)) {
|
||||
BLI_uniquename(
|
||||
&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. */
|
||||
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
|
||||
|
|
|
@ -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 --------------- */
|
||||
|
||||
/**
|
||||
* 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
|
||||
* provided animation channel-data.
|
||||
*/
|
||||
|
@ -655,244 +679,125 @@ static bAnimListElem *make_new_animlistelem(void *data,
|
|||
}
|
||||
case ANIMTYPE_DSMAT: {
|
||||
Material *ma = (Material *)data;
|
||||
AnimData *adt = ma->adt;
|
||||
|
||||
ale->flag = FILTER_MAT_OBJD(ma);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, ma->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSLAM: {
|
||||
Light *la = (Light *)data;
|
||||
AnimData *adt = la->adt;
|
||||
|
||||
ale->flag = FILTER_LAM_OBJD(la);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, la->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSCAM: {
|
||||
Camera *ca = (Camera *)data;
|
||||
AnimData *adt = ca->adt;
|
||||
|
||||
ale->flag = FILTER_CAM_OBJD(ca);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, ca->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSCACHEFILE: {
|
||||
CacheFile *cache_file = (CacheFile *)data;
|
||||
AnimData *adt = cache_file->adt;
|
||||
|
||||
ale->flag = FILTER_CACHEFILE_OBJD(cache_file);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, cache_file->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSCUR: {
|
||||
Curve *cu = (Curve *)data;
|
||||
AnimData *adt = cu->adt;
|
||||
|
||||
ale->flag = FILTER_CUR_OBJD(cu);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, cu->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSARM: {
|
||||
bArmature *arm = (bArmature *)data;
|
||||
AnimData *adt = arm->adt;
|
||||
|
||||
ale->flag = FILTER_ARM_OBJD(arm);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, arm->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSMESH: {
|
||||
Mesh *mesh = (Mesh *)data;
|
||||
AnimData *adt = mesh->adt;
|
||||
|
||||
ale->flag = FILTER_MESH_OBJD(mesh);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, mesh->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSLAT: {
|
||||
Lattice *lt = (Lattice *)data;
|
||||
AnimData *adt = lt->adt;
|
||||
|
||||
ale->flag = FILTER_LATTICE_OBJD(lt);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, lt->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSSPK: {
|
||||
Speaker *spk = (Speaker *)data;
|
||||
AnimData *adt = spk->adt;
|
||||
|
||||
ale->flag = FILTER_SPK_OBJD(spk);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, spk->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSHAIR: {
|
||||
Curves *curves = (Curves *)data;
|
||||
AnimData *adt = curves->adt;
|
||||
|
||||
ale->flag = FILTER_CURVES_OBJD(curves);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, curves->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSPOINTCLOUD: {
|
||||
PointCloud *pointcloud = (PointCloud *)data;
|
||||
AnimData *adt = pointcloud->adt;
|
||||
|
||||
ale->flag = FILTER_POINTS_OBJD(pointcloud);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, pointcloud->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSVOLUME: {
|
||||
Volume *volume = (Volume *)data;
|
||||
AnimData *adt = volume->adt;
|
||||
|
||||
ale->flag = FILTER_VOLUME_OBJD(volume);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, volume->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSSKEY: {
|
||||
Key *key = (Key *)data;
|
||||
AnimData *adt = key->adt;
|
||||
|
||||
ale->flag = FILTER_SKE_OBJD(key);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, key->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSWOR: {
|
||||
World *wo = (World *)data;
|
||||
AnimData *adt = wo->adt;
|
||||
|
||||
ale->flag = FILTER_WOR_SCED(wo);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, wo->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSNTREE: {
|
||||
bNodeTree *ntree = (bNodeTree *)data;
|
||||
AnimData *adt = ntree->adt;
|
||||
|
||||
ale->flag = FILTER_NTREE_DATA(ntree);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, ntree->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSLINESTYLE: {
|
||||
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)data;
|
||||
AnimData *adt = linestyle->adt;
|
||||
|
||||
ale->flag = FILTER_LS_SCED(linestyle);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, linestyle->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSPART: {
|
||||
ParticleSettings *part = (ParticleSettings *)ale->data;
|
||||
AnimData *adt = part->adt;
|
||||
|
||||
ale->flag = FILTER_PART_OBJD(part);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, part->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSTEX: {
|
||||
Tex *tex = (Tex *)data;
|
||||
AnimData *adt = tex->adt;
|
||||
|
||||
ale->flag = FILTER_TEX_DATA(tex);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, tex->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSGPENCIL: {
|
||||
bGPdata *gpd = (bGPdata *)data;
|
||||
AnimData *adt = gpd->adt;
|
||||
|
||||
/* NOTE: we just reuse the same expand filter for this case */
|
||||
ale->flag = EXPANDED_GPD(gpd);
|
||||
|
||||
/* XXX: currently, this is only used for access to its animation data */
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, gpd->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSMCLIP: {
|
||||
MovieClip *clip = (MovieClip *)data;
|
||||
AnimData *adt = clip->adt;
|
||||
|
||||
ale->flag = EXPANDED_MCLIP(clip);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : nullptr;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(static_cast<ID *>(data));
|
||||
key_data_from_adt(*ale, clip->adt);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_NLACONTROLS: {
|
||||
|
|
|
@ -54,6 +54,8 @@ struct AssetItemTree {
|
|||
assets_per_path;
|
||||
/** Assets not added to a catalog, not part of #assets_per_path. */
|
||||
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(
|
||||
|
|
|
@ -150,7 +150,8 @@ AssetItemTree build_filtered_all_catalog_tree(
|
|||
|
||||
return {std::move(catalogs_with_node_assets),
|
||||
std::move(assets_per_path),
|
||||
std::move(unassigned_assets)};
|
||||
std::move(unassigned_assets),
|
||||
false};
|
||||
}
|
||||
|
||||
} // 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);
|
||||
}
|
||||
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 eObjectMode mode : {OB_MODE_OBJECT, OB_MODE_EDIT, OB_MODE_SCULPT_CURVES}) {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
if (tree->assets_per_path.size() == 0) {
|
||||
if (tree->dirty) {
|
||||
*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)));
|
||||
if (btheme == nullptr) {
|
||||
btheme = MEM_cnew<bTheme>(__func__);
|
||||
STRNCPY(btheme->name, U_theme_default.name);
|
||||
BLI_addhead(&U.themes, btheme);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "sculpt_intern.hh"
|
||||
|
||||
namespace blender::ed::sculpt_paint::trim {
|
||||
|
||||
enum class OperationType {
|
||||
Intersect = 0,
|
||||
Difference = 1,
|
||||
|
@ -112,6 +113,10 @@ struct TrimOperation {
|
|||
/* Operator properties. */
|
||||
bool use_cursor_depth;
|
||||
|
||||
bool initial_hit;
|
||||
blender::float3 initial_location;
|
||||
blender::float3 initial_normal;
|
||||
|
||||
OperationType mode;
|
||||
SolverMode solver_mode;
|
||||
OrientationType orientation;
|
||||
|
@ -166,17 +171,17 @@ static void get_origin_and_normal(gesture::GestureData &gesture_data,
|
|||
case OrientationType::View:
|
||||
mul_v3_m4v3(r_origin,
|
||||
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);
|
||||
negate_v3(r_normal);
|
||||
break;
|
||||
case OrientationType::Surface:
|
||||
mul_v3_m4v3(r_origin,
|
||||
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
|
||||
* 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);
|
||||
break;
|
||||
}
|
||||
|
@ -221,11 +226,11 @@ static void calculate_depth(gesture::GestureData &gesture_data,
|
|||
float world_space_gesture_initial_location[3];
|
||||
mul_v3_m4v3(world_space_gesture_initial_location,
|
||||
vc->obact->object_to_world().ptr(),
|
||||
ss->gesture_initial_location);
|
||||
trim_operation->initial_location);
|
||||
|
||||
float mid_point_depth;
|
||||
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,
|
||||
shape_plane) :
|
||||
(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
|
||||
* at 0 distance from the shape plane. This positions the trimming shape half inside of the
|
||||
* 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;
|
||||
|
||||
if (ss->gesture_initial_hit) {
|
||||
if (trim_operation->initial_hit) {
|
||||
depth_radius = ss->cursor_radius;
|
||||
}
|
||||
else {
|
||||
|
@ -254,7 +259,7 @@ static void calculate_depth(gesture::GestureData &gesture_data,
|
|||
|
||||
if (!BKE_brush_use_locked_size(scene, brush)) {
|
||||
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 {
|
||||
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"));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
"trim_mode",
|
||||
operation_types,
|
||||
|
@ -672,21 +691,26 @@ static bool can_exec(const bContext &C)
|
|||
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);
|
||||
SculptSession &ss = *ob.sculpt;
|
||||
|
||||
SCULPT_vertex_random_access_ensure(&ss);
|
||||
|
||||
SculptCursorGeometryInfo sgi;
|
||||
const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
|
||||
int mval[2];
|
||||
RNA_int_get_array(op.ptr, "location", mval);
|
||||
|
||||
/* TODO: Remove gesture_* properties from SculptSession */
|
||||
ss.gesture_initial_hit = SCULPT_cursor_geometry_info_update(&C, &sgi, mval_fl, false);
|
||||
if (ss.gesture_initial_hit) {
|
||||
copy_v3_v3(ss.gesture_initial_location, sgi.location);
|
||||
copy_v3_v3(ss.gesture_initial_normal, sgi.normal);
|
||||
SculptCursorGeometryInfo sgi;
|
||||
const float mval_fl[2] = {float(mval[0]), float(mval[1])};
|
||||
|
||||
TrimOperation *trim_operation = (TrimOperation *)gesture_data.operation;
|
||||
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;
|
||||
}
|
||||
|
||||
initialize_cursor_info(*C, *op, *gesture_data);
|
||||
init_operation(*gesture_data, *op);
|
||||
|
||||
gesture::apply(*C, *gesture_data, *op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@ -712,7 +738,7 @@ static int gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
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);
|
||||
}
|
||||
|
@ -727,7 +753,10 @@ static int gesture_lasso_exec(bContext *C, wmOperator *op)
|
|||
if (!gesture_data) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
initialize_cursor_info(*C, *op, *gesture_data);
|
||||
init_operation(*gesture_data, *op);
|
||||
|
||||
gesture::apply(*C, *gesture_data, *op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@ -738,7 +767,7 @@ static int gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -242,8 +242,10 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
|
|||
graph_draw_curves(&ac, sipo, region, 1);
|
||||
|
||||
/* 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(
|
||||
&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 */
|
||||
v2d->tot.xmin -= 10.0f;
|
||||
v2d->tot.xmax += 10.0f;
|
||||
|
|
|
@ -2340,7 +2340,7 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
|
|||
|
||||
RNA_def_boolean(ot->srna,
|
||||
"do_recursive",
|
||||
false,
|
||||
true,
|
||||
"Recursive Delete",
|
||||
"Recursively check for indirectly unused data-blocks, ensuring that no orphaned "
|
||||
"data-blocks remain after execution");
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "BKE_report.hh"
|
||||
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utils.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 (export_params.use_batch) {
|
||||
/* 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. */
|
||||
std::replace(object_name.begin(), object_name.end(), ' ', '_');
|
||||
BLI_string_replace_char(object_name, ' ', '_');
|
||||
|
||||
/* Include object name in the exported file name. */
|
||||
char filepath[FILE_MAX];
|
||||
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). */
|
||||
if (!BLI_path_extension_check(filepath, ".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. */
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -6333,7 +6333,7 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
|
|||
{AV_CODEC_ID_MPEG2VIDEO, "MPEG2", 0, "MPEG-2", ""},
|
||||
{AV_CODEC_ID_MPEG4, "MPEG4", 0, "MPEG-4 (divx)", ""},
|
||||
{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_VP9, "WEBM", 0, "WebM / VP9", ""},
|
||||
{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 */
|
||||
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);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "active_theme_area");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
|
|
@ -333,29 +333,10 @@ if(WITH_PYTHON_MODULE)
|
|||
else()
|
||||
add_executable(blender ${EXETYPE} ${SRC})
|
||||
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
|
||||
# to this, this is to ensure this will be the first code to run once the
|
||||
# blender binary has been loaded by the OS.
|
||||
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()
|
||||
if(WIN32)
|
||||
add_executable(blender-launcher WIN32
|
||||
|
|
|
@ -107,7 +107,7 @@ class MeshExportTest4(AbstractColladaTest):
|
|||
outfile = tempdir / Path("%s_out.dae" % test)
|
||||
|
||||
bpy.ops.wm.collada_export(
|
||||
filepath="%s" % str(outfile),
|
||||
filepath=str(outfile),
|
||||
check_existing=True,
|
||||
filemode=8,
|
||||
display_type='DEFAULT',
|
||||
|
@ -151,7 +151,7 @@ class MeshExportTest3(AbstractColladaTest):
|
|||
outfile = tempdir / Path("%s_out.dae" % test)
|
||||
|
||||
bpy.ops.wm.collada_export(
|
||||
filepath="%s" % str(outfile),
|
||||
filepath=str(outfile),
|
||||
check_existing=True,
|
||||
filemode=8,
|
||||
display_type='DEFAULT',
|
||||
|
@ -195,7 +195,7 @@ class MeshExportTest2(AbstractColladaTest):
|
|||
outfile = tempdir / Path("%s_out.dae" % test)
|
||||
|
||||
bpy.ops.wm.collada_export(
|
||||
filepath="%s" % str(outfile),
|
||||
filepath=str(outfile),
|
||||
check_existing=True,
|
||||
filemode=8,
|
||||
display_type='DEFAULT',
|
||||
|
@ -239,7 +239,7 @@ class MeshExportTest1(AbstractColladaTest):
|
|||
outfile = tempdir / Path("%s_out.dae" % test)
|
||||
|
||||
bpy.ops.wm.collada_export(
|
||||
filepath="%s" % str(outfile),
|
||||
filepath=str(outfile),
|
||||
check_existing=True,
|
||||
filemode=8,
|
||||
display_type='DEFAULT',
|
||||
|
|
|
@ -107,7 +107,7 @@ class MeshExportTest(AbstractColladaTest):
|
|||
outfile = tempdir / Path("%s_out.dae" % test)
|
||||
|
||||
bpy.ops.wm.collada_export(
|
||||
filepath="%s" % str(outfile),
|
||||
filepath=str(outfile),
|
||||
check_existing=True,
|
||||
filemode=8,
|
||||
display_type="DEFAULT",
|
||||
|
|
|
@ -1638,7 +1638,7 @@ class edit_generators:
|
|||
):
|
||||
edits.append(Edit(
|
||||
span=match.span(),
|
||||
content='%s' % match.group(2),
|
||||
content=match.group(2),
|
||||
content_fail='__ALWAYS_FAIL__',
|
||||
))
|
||||
|
||||
|
|
Loading…
Reference in New Issue