Fix #105430: Curves pick select selects multiple objects #105495

Merged
Hans Goudey merged 5 commits from HooglyBoogly/blender:fix-curves-pick-select-multi-object into blender-v3.5-release 2023-03-07 21:39:58 +01:00
32 changed files with 369 additions and 103 deletions
Showing only changes of commit 684cc24cb8 - Show all commits

View File

@ -2,4 +2,4 @@ ${CommitTitle}
${CommitBody}
Pull Request #${PullRequestIndex}
Pull Request: https://projects.blender.org/blender/blender/pulls/${PullRequestIndex}

View File

@ -1,3 +1,3 @@
${PullRequestTitle}
Pull Request #${PullRequestIndex}
Pull Request: https://projects.blender.org/blender/blender/pulls/${PullRequestIndex}

View File

@ -1673,7 +1673,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
driver_version = "470"
col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
icon='BLANK1', translate=False)
col.label(text="and NVIDIA driver version %s or newer" % driver_version,
col.label(text=iface_("and NVIDIA driver version %s or newer") % driver_version,
icon='BLANK1', translate=False)
elif device_type == 'HIP':
import sys
@ -1716,7 +1716,8 @@ class CyclesPreferences(bpy.types.AddonPreferences):
.replace('(TM)', unicodedata.lookup('TRADE MARK SIGN'))
.replace('(tm)', unicodedata.lookup('TRADE MARK SIGN'))
.replace('(R)', unicodedata.lookup('REGISTERED SIGN'))
.replace('(C)', unicodedata.lookup('COPYRIGHT SIGN'))
.replace('(C)', unicodedata.lookup('COPYRIGHT SIGN')),
translate=False
)
def draw_impl(self, layout, context):

View File

@ -161,25 +161,12 @@ ShaderCache::~ShaderCache()
running = false;
cond_var.notify_all();
int num_incomplete = int(incomplete_requests);
if (num_incomplete) {
/* Shutting down the app with incomplete shader compilation requests. Give 1 second's grace for
* clean shutdown. */
metal_printf("ShaderCache busy (incomplete_requests = %d)...\n", num_incomplete);
std::this_thread::sleep_for(std::chrono::seconds(1));
num_incomplete = int(incomplete_requests);
}
if (num_incomplete && !MetalDeviceKernels::is_benchmark_warmup()) {
metal_printf("ShaderCache still busy (incomplete_requests = %d). Terminating...\n",
num_incomplete);
std::terminate();
}
metal_printf("ShaderCache idle. Shutting down.\n");
metal_printf("Waiting for ShaderCache threads... (incomplete_requests = %d)\n",
int(incomplete_requests));
for (auto &thread : compile_threads) {
thread.join();
}
metal_printf("ShaderCache shut down.\n");
}
void ShaderCache::wait_for_all()
@ -675,7 +662,9 @@ void MetalKernelPipeline::compile()
}
}
__block bool creating_new_archive = false;
bool creating_new_archive = false;
bool recreate_archive = false;
if (@available(macOS 11.0, *)) {
if (use_binary_archive) {
if (!archive) {
@ -684,51 +673,101 @@ void MetalKernelPipeline::compile()
archive = [mtlDevice newBinaryArchiveWithDescriptor:archiveDesc error:nil];
creating_new_archive = true;
}
computePipelineStateDescriptor.binaryArchives = [NSArray arrayWithObjects:archive, nil];
pipelineOptions = MTLPipelineOptionFailOnBinaryArchiveMiss;
else {
pipelineOptions = MTLPipelineOptionFailOnBinaryArchiveMiss;
computePipelineStateDescriptor.binaryArchives = [NSArray arrayWithObjects:archive, nil];
}
}
}
/* Lambda to do the actual pipeline compilation. */
auto do_compilation = [&]() {
__block bool compilation_finished = false;
__block string error_str;
if (archive && path_exists(metalbin_path)) {
/* Use the blocking variant of newComputePipelineStateWithDescriptor if an archive exists on
* disk. It should load almost instantaneously, and will fail gracefully when loading a
* corrupt archive (unlike the async variant). */
NSError *error = nil;
pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
options:pipelineOptions
reflection:nullptr
error:&error];
const char *err = error ? [[error localizedDescription] UTF8String] : nullptr;
error_str = err ? err : "nil";
}
else {
/* Use the async variant of newComputePipelineStateWithDescriptor if no archive exists on
* disk. This allows us responds to app shutdown. */
[mtlDevice
newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
options:pipelineOptions
completionHandler:^(id<MTLComputePipelineState> computePipelineState,
MTLComputePipelineReflection *reflection,
NSError *error) {
pipeline = computePipelineState;
/* Retain the pipeline so we can use it safely past the completion
* handler. */
if (pipeline) {
[pipeline retain];
}
const char *err = error ?
[[error localizedDescription] UTF8String] :
nullptr;
error_str = err ? err : "nil";
compilation_finished = true;
}];
/* Immediately wait for either the compilation to finish or for app shutdown. */
while (ShaderCache::running && !compilation_finished) {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
if (creating_new_archive && pipeline && ShaderCache::running) {
/* Add pipeline into the new archive. It should be instantaneous following
* newComputePipelineStateWithDescriptor. */
NSError *error;
computePipelineStateDescriptor.binaryArchives = [NSArray arrayWithObjects:archive, nil];
if (![archive addComputePipelineFunctionsWithDescriptor:computePipelineStateDescriptor
error:&error]) {
NSString *errStr = [error localizedDescription];
metal_printf("Failed to add PSO to archive:\n%s\n", errStr ? [errStr UTF8String] : "nil");
}
}
else if (!pipeline) {
metal_printf(
"newComputePipelineStateWithDescriptor failed for \"%s\"%s. "
"Error:\n%s\n",
device_kernel_as_string((DeviceKernel)device_kernel),
(archive && !recreate_archive) ? " Archive may be incomplete or corrupt - attempting "
"recreation.." :
"",
error_str.c_str());
}
};
double starttime = time_dt();
/* Block on load to ensure we continue with a valid kernel function */
if (creating_new_archive) {
starttime = time_dt();
NSError *error;
if (![archive addComputePipelineFunctionsWithDescriptor:computePipelineStateDescriptor
error:&error]) {
NSString *errStr = [error localizedDescription];
metal_printf("Failed to add PSO to archive:\n%s\n", errStr ? [errStr UTF8String] : "nil");
}
}
do_compilation();
pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
options:pipelineOptions
reflection:nullptr
error:&error];
bool recreate_archive = false;
/* An archive might have a corrupt entry and fail to materialize the pipeline. This shouldn't
* happen, but if it does we recreate it. */
if (pipeline == nil && archive) {
NSString *errStr = [error localizedDescription];
metal_printf(
"Failed to create compute pipeline state \"%s\" from archive - attempting recreation... "
"(error: %s)\n",
device_kernel_as_string((DeviceKernel)device_kernel),
errStr ? [errStr UTF8String] : "nil");
pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
options:MTLPipelineOptionNone
reflection:nullptr
error:&error];
recreate_archive = true;
pipelineOptions = MTLPipelineOptionNone;
path_remove(metalbin_path);
do_compilation();
}
double duration = time_dt() - starttime;
if (pipeline == nil) {
NSString *errStr = [error localizedDescription];
error_str = string_printf("Failed to create compute pipeline state \"%s\", error: \n",
device_kernel_as_string((DeviceKernel)device_kernel));
error_str += (errStr ? [errStr UTF8String] : "nil");
metal_printf("%16s | %2d | %-55s | %7.2fs | FAILED!\n",
kernel_type_as_string(pso_type),
device_kernel,
@ -748,7 +787,8 @@ void MetalKernelPipeline::compile()
if (creating_new_archive || recreate_archive) {
if (![archive serializeToURL:[NSURL fileURLWithPath:@(metalbin_path.c_str())]
error:&error]) {
metal_printf("Failed to save binary archive, error:\n%s\n",
metal_printf("Failed to save binary archive to %s, error:\n%s\n",
metalbin_path.c_str(),
[[error localizedDescription] UTF8String]);
}
else {

View File

@ -13,6 +13,7 @@
#ifndef __FFMPEG_COMPAT_H__
#define __FFMPEG_COMPAT_H__
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
/* Check if our ffmpeg is new enough, avoids user complaints.

View File

@ -20,11 +20,13 @@ enum TransformType {
TRANSFORM_SRGB_TO_LINEAR,
TRANSFORM_SCALE,
TRANSFORM_EXPONENT,
TRANSFORM_NONE,
TRANSFORM_UNKNOWN,
};
#define COLORSPACE_LINEAR ((OCIO_ConstColorSpaceRcPtr *)1)
#define COLORSPACE_SRGB ((OCIO_ConstColorSpaceRcPtr *)2)
#define COLORSPACE_DATA ((OCIO_ConstColorSpaceRcPtr *)3)
typedef struct OCIO_PackedImageDescription {
float *data;
@ -165,6 +167,8 @@ OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcP
return COLORSPACE_LINEAR;
else if (strcmp(name, "sRGB") == 0)
return COLORSPACE_SRGB;
else if (strcmp(name, "data") == 0)
return COLORSPACE_DATA;
return NULL;
}
@ -179,6 +183,9 @@ int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, con
else if (cs == COLORSPACE_SRGB) {
return 1;
}
else if (cs == COLORSPACE_DATA) {
return 2;
}
return -1;
}
@ -314,7 +321,10 @@ OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstCo
OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName);
OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName);
FallbackTransform transform;
if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
if (cs_src == COLORSPACE_DATA || cs_dst == COLORSPACE_DATA) {
transform.type = TRANSFORM_NONE;
}
else if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
transform.type = TRANSFORM_LINEAR_TO_SRGB;
}
else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) {
@ -433,6 +443,9 @@ const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
else if (cs == COLORSPACE_SRGB) {
return "sRGB";
}
else if (cs == COLORSPACE_DATA) {
return "data";
}
return NULL;
}

View File

@ -692,6 +692,15 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
else:
continue
# Skip function if it's marked as not translatable.
do_translate = True
for kw in node.keywords:
if kw.arg == "translate" and not kw.value.value:
do_translate = False
break
if not do_translate:
continue
func_args = func_translate_args.get(func_id, {})
# First try to get i18n contexts, for every possible msgid id.

View File

@ -2,7 +2,10 @@
import bpy
from bpy.types import Menu
from bl_ui import node_add_menu
from bpy.app.translations import pgettext_iface as iface_
from bpy.app.translations import (
pgettext_iface as iface_,
contexts as i18n_contexts,
)
class NODE_MT_geometry_node_GEO_ATTRIBUTE(Menu):
@ -238,6 +241,7 @@ class NODE_MT_geometry_node_GEO_INPUT(Menu):
class NODE_MT_geometry_node_GEO_INPUT_CONSTANT(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_INPUT_CONSTANT"
bl_label = "Constant"
bl_translation_context = i18n_contexts.id_nodetree
def draw(self, _context):
layout = self.layout

View File

@ -745,6 +745,8 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
row.operator("asset.open_containing_blend_file", text="", icon='TOOL_SETTINGS')
layout.prop(asset_file_handle.asset_data, "description")
layout.prop(asset_file_handle.asset_data, "license")
layout.prop(asset_file_handle.asset_data, "copyright")
layout.prop(asset_file_handle.asset_data, "author")

View File

@ -79,6 +79,7 @@ class TEXT_HT_footer(Header):
text=iface_("Text: External")
if text.library
else iface_("Text: Internal"),
translate=False
)

View File

@ -44,6 +44,8 @@ AssetMetaData::~AssetMetaData()
}
MEM_SAFE_FREE(author);
MEM_SAFE_FREE(description);
MEM_SAFE_FREE(copyright);
MEM_SAFE_FREE(license);
BLI_freelistN(&tags);
}
@ -161,13 +163,19 @@ void BKE_asset_metadata_write(BlendWriter *writer, AssetMetaData *asset_data)
if (asset_data->properties) {
IDP_BlendWrite(writer, asset_data->properties);
}
if (asset_data->author) {
BLO_write_string(writer, asset_data->author);
}
if (asset_data->description) {
BLO_write_string(writer, asset_data->description);
}
if (asset_data->copyright) {
BLO_write_string(writer, asset_data->copyright);
}
if (asset_data->license) {
BLO_write_string(writer, asset_data->license);
}
LISTBASE_FOREACH (AssetTag *, tag, &asset_data->tags) {
BLO_write_struct(writer, AssetTag, tag);
}
@ -185,6 +193,8 @@ void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
BLO_read_data_address(reader, &asset_data->author);
BLO_read_data_address(reader, &asset_data->description);
BLO_read_data_address(reader, &asset_data->copyright);
BLO_read_data_address(reader, &asset_data->license);
BLO_read_list(reader, &asset_data->tags);
BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
}

View File

@ -272,7 +272,7 @@ static bool library_foreach_ID_link(Main *bmain,
}
if (bmain != NULL && bmain->relations != NULL && (flag & IDWALK_READONLY) &&
(flag & IDWALK_DO_INTERNAL_RUNTIME_POINTERS) == 0 &&
(flag & (IDWALK_DO_INTERNAL_RUNTIME_POINTERS | IDWALK_DO_LIBRARY_POINTER)) == 0 &&
(((bmain->relations->flag & MAINIDRELATIONS_INCLUDE_UI) == 0) ==
((data.flag & IDWALK_INCLUDE_UI) == 0))) {
/* Note that this is minor optimization, even in worst cases (like id being an object with

View File

@ -342,7 +342,7 @@ MaskLayer *BKE_mask_layer_new(Mask *mask, const char *name)
BLI_strncpy(masklay->name, name, sizeof(masklay->name));
}
else {
strcpy(masklay->name, "MaskLayer");
strcpy(masklay->name, DATA_("MaskLayer"));
}
BLI_addtail(&mask->masklayers, masklay);

View File

@ -130,6 +130,8 @@ const char *BLT_translate_do_new_dataname(const char *msgctxt, const char *msgid
#define BLT_I18NCONTEXT_VIRTUAL_REALITY "Virtual reality"
#define BLT_I18NCONTEXT_CONSTRAINT "Constraint"
#define BLT_I18NCONTEXT_COLOR "Color"
#define BLT_I18NCONTEXT_AMOUNT "Amount"
#define BLT_I18NCONTEXT_UNIT "Unit"
/* Helper for bpy.app.i18n object... */
typedef struct {
@ -198,6 +200,8 @@ typedef struct {
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_VIRTUAL_REALITY, "virtual_reality"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_CONSTRAINT, "constraint"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_COLOR, "color"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_AMOUNT, "amount"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_UNIT, "unit"), \
{ \
NULL, NULL, NULL \
} \

View File

@ -559,21 +559,21 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->p_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX));
mr->material_indices = static_cast<const int *>(
CustomData_get_layer_named(&me->pdata, CD_PROP_INT32, "material_index"));
CustomData_get_layer_named(&mr->me->pdata, CD_PROP_INT32, "material_index"));
mr->hide_vert = static_cast<const bool *>(
CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert"));
CustomData_get_layer_named(&mr->me->vdata, CD_PROP_BOOL, ".hide_vert"));
mr->hide_edge = static_cast<const bool *>(
CustomData_get_layer_named(&me->edata, CD_PROP_BOOL, ".hide_edge"));
CustomData_get_layer_named(&mr->me->edata, CD_PROP_BOOL, ".hide_edge"));
mr->hide_poly = static_cast<const bool *>(
CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".hide_poly"));
CustomData_get_layer_named(&mr->me->pdata, CD_PROP_BOOL, ".hide_poly"));
mr->select_vert = static_cast<const bool *>(
CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".select_vert"));
CustomData_get_layer_named(&mr->me->vdata, CD_PROP_BOOL, ".select_vert"));
mr->select_edge = static_cast<const bool *>(
CustomData_get_layer_named(&me->edata, CD_PROP_BOOL, ".select_edge"));
CustomData_get_layer_named(&mr->me->edata, CD_PROP_BOOL, ".select_edge"));
mr->select_poly = static_cast<const bool *>(
CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".select_poly"));
CustomData_get_layer_named(&mr->me->pdata, CD_PROP_BOOL, ".select_poly"));
}
else {
/* #BMesh */
@ -586,7 +586,7 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len);
}
retrieve_active_attribute_names(*mr, *object, *me);
retrieve_active_attribute_names(*mr, *object, *mr->me);
return mr;
}

View File

@ -56,13 +56,16 @@ using namespace blender::bke::idprop;
* "catalog_name": "<catalog_name>",
* "description": "<description>",
* "author": "<author>",
* "copyright": "<copyright>",
* "license": "<license>",
* "tags": ["<tag>"],
* "properties": [..]
* }]
* }
* \endcode
*
* NOTE: entries, author, description, tags and properties are optional attributes.
* NOTE: entries, author, description, copyright, license, tags and properties are optional
* attributes.
*
* NOTE: File browser uses name and idcode separate. Inside the index they are joined together like
* #ID.name.
@ -75,6 +78,8 @@ constexpr StringRef ATTRIBUTE_ENTRIES_CATALOG_ID("catalog_id");
constexpr StringRef ATTRIBUTE_ENTRIES_CATALOG_NAME("catalog_name");
constexpr StringRef ATTRIBUTE_ENTRIES_DESCRIPTION("description");
constexpr StringRef ATTRIBUTE_ENTRIES_AUTHOR("author");
constexpr StringRef ATTRIBUTE_ENTRIES_COPYRIGHT("copyright");
constexpr StringRef ATTRIBUTE_ENTRIES_LICENSE("license");
constexpr StringRef ATTRIBUTE_ENTRIES_TAGS("tags");
constexpr StringRef ATTRIBUTE_ENTRIES_PROPERTIES("properties");
@ -178,6 +183,26 @@ struct AssetEntryReader {
return lookup.lookup(ATTRIBUTE_ENTRIES_AUTHOR)->as_string_value()->value();
}
bool has_copyright() const
{
return lookup.contains(ATTRIBUTE_ENTRIES_COPYRIGHT);
}
StringRefNull get_copyright() const
{
return lookup.lookup(ATTRIBUTE_ENTRIES_COPYRIGHT)->as_string_value()->value();
}
bool has_license() const
{
return lookup.contains(ATTRIBUTE_ENTRIES_LICENSE);
}
StringRefNull get_license() const
{
return lookup.lookup(ATTRIBUTE_ENTRIES_LICENSE)->as_string_value()->value();
}
StringRefNull get_catalog_name() const
{
return lookup.lookup(ATTRIBUTE_ENTRIES_CATALOG_NAME)->as_string_value()->value();
@ -267,6 +292,16 @@ struct AssetEntryWriter {
attributes.append_as(std::pair(ATTRIBUTE_ENTRIES_AUTHOR, new StringValue(author)));
}
void add_copyright(const StringRefNull copyright)
{
attributes.append_as(std::pair(ATTRIBUTE_ENTRIES_COPYRIGHT, new StringValue(copyright)));
}
void add_license(const StringRefNull license)
{
attributes.append_as(std::pair(ATTRIBUTE_ENTRIES_LICENSE, new StringValue(license)));
}
void add_tags(const ListBase /* AssetTag */ *asset_tags)
{
ArrayValue *tags = new ArrayValue();
@ -305,6 +340,12 @@ static void init_value_from_file_indexer_entry(AssetEntryWriter &result,
if (asset_data.author != nullptr) {
result.add_author(asset_data.author);
}
if (asset_data.copyright != nullptr) {
result.add_copyright(asset_data.copyright);
}
if (asset_data.license != nullptr) {
result.add_license(asset_data.license);
}
if (!BLI_listbase_is_empty(&asset_data.tags)) {
result.add_tags(&asset_data.tags);
@ -372,6 +413,18 @@ static void init_indexer_entry_from_value(FileIndexerEntry &indexer_entry,
BLI_strncpy(author_c_str, author.c_str(), author.size() + 1);
asset_data->author = author_c_str;
}
if (entry.has_copyright()) {
const StringRefNull copyright = entry.get_copyright();
char *copyright_c_str = static_cast<char *>(MEM_mallocN(copyright.size() + 1, __func__));
BLI_strncpy(copyright_c_str, copyright.c_str(), copyright.size() + 1);
asset_data->copyright = copyright_c_str;
}
if (entry.has_license()) {
const StringRefNull license = entry.get_license();
char *license_c_str = static_cast<char *>(MEM_mallocN(license.size() + 1, __func__));
BLI_strncpy(license_c_str, license.c_str(), license.size() + 1);
asset_data->license = license_c_str;
}
const StringRefNull catalog_name = entry.get_catalog_name();
BLI_strncpy(asset_data->catalog_simple_name,

View File

@ -3877,7 +3877,7 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
case UI_BTYPE_KEY_EVENT: {
const char *str;
if (but->flag & UI_SELECT) {
str = "Press a key";
str = IFACE_("Press a key");
}
else {
UI_GET_BUT_VALUE_INIT(but, value);
@ -3910,7 +3910,7 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
(void)str; /* UNUSED */
}
else {
BLI_strncpy(but->drawstr, "Press a key", UI_MAX_DRAW_STR);
BLI_strncpy(but->drawstr, IFACE_("Press a key"), UI_MAX_DRAW_STR);
}
}
else {

View File

@ -5912,7 +5912,8 @@ static bool ui_layout_has_panel_label(const uiLayout *layout, const PanelType *p
LISTBASE_FOREACH (uiItem *, subitem, &layout->items) {
if (subitem->type == ITEM_BUTTON) {
uiButtonItem *bitem = (uiButtonItem *)subitem;
if (!(bitem->but->flag & UI_HIDDEN) && STREQ(bitem->but->str, pt->label)) {
if (!(bitem->but->flag & UI_HIDDEN) &&
STREQ(bitem->but->str, CTX_IFACE_(pt->translation_context, pt->label))) {
return true;
}
}

View File

@ -2810,8 +2810,10 @@ void TEXT_OT_scroll(wmOperatorType *ot)
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_XY | OPTYPE_INTERNAL;
/* properties */
RNA_def_int(
PropertyRNA *prop;
prop = RNA_def_int(
ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll", -100, 100);
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_TEXT);
}
/** \} */
@ -2915,8 +2917,10 @@ void TEXT_OT_scroll_bar(wmOperatorType *ot)
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
/* properties */
RNA_def_int(
PropertyRNA *prop;
prop = RNA_def_int(
ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll", -100, 100);
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_TEXT);
}
/** \} */

View File

@ -3059,6 +3059,7 @@ static bool ed_curves_select_pick(bContext &C, const int mval[2], const SelectPi
}
if (!closest.curves_id) {
MEM_freeN(bases_ptr);
HooglyBoogly marked this conversation as resolved
Review

Needs a MEM_freeN(bases_ptr).

Needs a `MEM_freeN(bases_ptr)`.
return deselected;
}

View File

@ -146,12 +146,21 @@ void solve_length_and_collision_constraints(const OffsetIndices<int> points_by_c
float slide_direction_length_cu;
const float3 normalized_slide_direction_cu = math::normalize_and_get_length(
slide_direction_cu, slide_direction_length_cu);
const float slide_normal_length_sq_cu = math::length_squared(slide_normal_cu);
/* Use pythagorian theorem to determine how far to slide. */
const float slide_distance_cu = std::sqrt(pow2f(goal_segment_length_cu) -
math::length_squared(slide_normal_cu)) -
slide_direction_length_cu;
positions_cu[point_i] = plane_pos_cu + normalized_slide_direction_cu * slide_distance_cu;
if (pow2f(goal_segment_length_cu) > slide_normal_length_sq_cu) {
/* Use pythagorian theorem to determine how far to slide. */
const float slide_distance_cu = std::sqrt(pow2f(goal_segment_length_cu) -
slide_normal_length_sq_cu) -
slide_direction_length_cu;
positions_cu[point_i] = plane_pos_cu +
normalized_slide_direction_cu * slide_distance_cu;
}
else {
/* Minimum distance is larger than allowed segment length.
* The unilateral collision constraint is satisfied by just clamping segment length. */
positions_cu[point_i] = prev_pos_cu + math::normalize(old_pos_su - prev_pos_cu) * goal_segment_length_cu;
}
}
if (used_iterations == max_collisions) {
revert_curve = true;

View File

@ -62,11 +62,24 @@ template<> uint denormalize<uint>(float val)
return uint(float(DEPTH_SCALE_FACTOR) * val);
}
/* Float to other type case. */
template<typename T> T convert_type(float type)
{
return T(type);
}
/* Uint to other types. */
template<typename T> T convert_type(uint type)
{
return T(type);
}
/* Int to other types. */
template<typename T> T convert_type(int type)
{
return T(type);
}
template<> uchar convert_type<uchar>(float val)
{
return uchar(val * float(0xFF));
@ -141,8 +154,8 @@ kernel void compute_texture_read(constant TextureReadParams &params [[buffer(0)]
uint xx = position[0];
uint yy = position[1];
uint zz = position[2];
int index = (zz * (params.extent[0] * params.extent[1]) + yy * params.extnt[0] + xx) *
COMPONENT_COUNT_INPUT;
int index = (zz * (params.extent[0] * params.extent[1]) + yy * params.extent[0] + xx) *
COMPONENT_COUNT_OUTPUT;
read_colour = read_tex.read(uint3(params.offset[0], params.offset[1], params.offset[2]) +
uint3(xx, yy, zz));
@ -163,7 +176,7 @@ kernel void compute_texture_read(constant TextureReadParams &params [[buffer(0)]
uint yy = position[1];
uint layer = position[2];
int index = (layer * (params.extent[0] * params.extent[1]) + yy * params.extent[0] + xx) *
COMPONENT_COUNT_INPUT;
COMPONENT_COUNT_OUTPUT;
/* Read data */
# if IS_DEPTH_FORMAT == 1

View File

@ -606,17 +606,6 @@ void MTLFrameBuffer::update_attachments(bool update_viewport)
if (!dirty_attachments_) {
return;
}
/* Cache viewport and scissor (If we have existing attachments). */
int t_viewport[4], t_scissor[4];
update_viewport = update_viewport &&
(this->get_attachment_count() > 0 && this->has_depth_attachment() &&
this->has_stencil_attachment());
if (update_viewport) {
this->viewport_get(t_viewport);
this->scissor_get(t_scissor);
}
/* Clear current attachments state. */
this->remove_all_attachments();
@ -738,22 +727,25 @@ void MTLFrameBuffer::update_attachments(bool update_viewport)
}
}
/* Check whether the first attachment is SRGB. */
/* Extract attachment size and determine if framebuffer is SRGB. */
if (first_attachment != GPU_FB_MAX_ATTACHMENT) {
srgb_ = (first_attachment_mtl.texture->format_get() == GPU_SRGB8_A8);
}
/* Reset viewport and Scissor (If viewport is smaller or equal to the framebuffer size). */
if (update_viewport && t_viewport[2] <= width_ && t_viewport[3] <= height_) {
this->viewport_set(t_viewport);
this->scissor_set(t_viewport);
/* Ensure size is correctly assigned. */
GPUAttachment &attach = attachments_[first_attachment];
int size[3];
GPU_texture_get_mipmap_size(attach.tex, attach.mip, size);
this->size_set(size[0], size[1]);
srgb_ = (GPU_texture_format(attach.tex) == GPU_SRGB8_A8);
}
else {
this->viewport_reset();
this->scissor_reset();
/* Empty frame-buffer. */
width_ = 0;
height_ = 0;
}
/* Reset viewport and Scissor. */
this->viewport_reset();
this->scissor_reset();
/* We have now updated our internal structures. */
dirty_attachments_ = false;
}

View File

@ -72,6 +72,12 @@ typedef struct AssetMetaData {
/** Optional description of this asset for display in the UI. Dynamic length. */
char *description;
/** Optional copyright of this asset for display in the UI. Dynamic length. */
char *copyright;
/** Optional license of this asset for display in the UI. Dynamic length. */
char *license;
/** User defined tags for this asset. The asset manager uses these for filtering, but how they
* function exactly (e.g. how they are registered to provide a list of searchable available tags)
* is up to the asset-engine. */

View File

@ -205,6 +205,74 @@ static void rna_AssetMetaData_description_set(PointerRNA *ptr, const char *value
}
}
static void rna_AssetMetaData_copyright_get(PointerRNA *ptr, char *value)
{
AssetMetaData *asset_data = ptr->data;
if (asset_data->copyright) {
strcpy(value, asset_data->copyright);
}
else {
value[0] = '\0';
}
}
static int rna_AssetMetaData_copyright_length(PointerRNA *ptr)
{
AssetMetaData *asset_data = ptr->data;
return asset_data->copyright ? strlen(asset_data->copyright) : 0;
}
static void rna_AssetMetaData_copyright_set(PointerRNA *ptr, const char *value)
{
AssetMetaData *asset_data = ptr->data;
if (asset_data->copyright) {
MEM_freeN(asset_data->copyright);
}
if (value[0]) {
asset_data->copyright = BLI_strdup(value);
}
else {
asset_data->copyright = NULL;
}
}
static void rna_AssetMetaData_license_get(PointerRNA *ptr, char *value)
{
AssetMetaData *asset_data = ptr->data;
if (asset_data->license) {
strcpy(value, asset_data->license);
}
else {
value[0] = '\0';
}
}
static int rna_AssetMetaData_license_length(PointerRNA *ptr)
{
AssetMetaData *asset_data = ptr->data;
return asset_data->license ? strlen(asset_data->license) : 0;
}
static void rna_AssetMetaData_license_set(PointerRNA *ptr, const char *value)
{
AssetMetaData *asset_data = ptr->data;
if (asset_data->license) {
MEM_freeN(asset_data->license);
}
if (value[0]) {
asset_data->license = BLI_strdup(value);
}
else {
asset_data->license = NULL;
}
}
static void rna_AssetMetaData_active_tag_range(
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
{
@ -397,6 +465,30 @@ static void rna_def_asset_data(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Description", "A description of the asset to be displayed for the user");
prop = RNA_def_property(srna, "copyright", PROP_STRING, PROP_NONE);
RNA_def_property_editable_func(prop, "rna_AssetMetaData_editable");
RNA_def_property_string_funcs(prop,
"rna_AssetMetaData_copyright_get",
"rna_AssetMetaData_copyright_length",
"rna_AssetMetaData_copyright_set");
RNA_def_property_ui_text(
prop,
"Copyright",
"Copyright notice for this asset. An empty copyright notice does not necessarily indicate "
"that this is copyright-free. Contact the author if any clarification is needed");
prop = RNA_def_property(srna, "license", PROP_STRING, PROP_NONE);
RNA_def_property_editable_func(prop, "rna_AssetMetaData_editable");
RNA_def_property_string_funcs(prop,
"rna_AssetMetaData_license_get",
"rna_AssetMetaData_license_length",
"rna_AssetMetaData_license_set");
RNA_def_property_ui_text(prop,
"License",
"The type of license this asset is distributed under. An empty license "
"name does not necessarily indicate that this is free of licensing "
"terms. Contact the author if any clarification is needed");
prop = RNA_def_property(srna, "tags", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "AssetTag");
RNA_def_property_editable_func(prop, "rna_AssetMetaData_editable");

View File

@ -2556,6 +2556,8 @@ static void rna_def_brush(BlenderRNA *brna)
prop = RNA_def_property(srna, "curve_preset", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, brush_curve_preset_items);
RNA_def_property_ui_text(prop, "Curve Preset", "");
RNA_def_property_translation_context(prop,
BLT_I18NCONTEXT_ID_CURVES); /* Abusing id_curves :/ */
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "deform_target", PROP_ENUM, PROP_NONE);

View File

@ -8,6 +8,8 @@
#include "DNA_cachefile_types.h"
#include "DNA_scene_types.h"
#include "BLT_translation.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@ -364,6 +366,7 @@ static void rna_def_cachefile(BlenderRNA *brna)
"Velocity Unit",
"Define how the velocity vectors are interpreted with regard to time, 'frame' means "
"the delta time is 1 frame, 'second' means the delta time is 1 / FPS");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_UNIT);
RNA_def_property_update(prop, 0, "rna_CacheFile_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);

View File

@ -1821,6 +1821,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_range(prop, 1, 5);
RNA_def_property_ui_text(
prop, "Number", "Particle number factor (higher value results in more particles)");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_AMOUNT);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
prop = RNA_def_property(srna, "particle_min", PROP_INT, PROP_NONE);

View File

@ -2948,6 +2948,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_range(prop, 0, 1000000, 1, -1);
RNA_def_property_ui_text(prop, "Number", "Total number of particles");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_AMOUNT);
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop = RNA_def_property(

View File

@ -6440,6 +6440,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "hair_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, hair_shape_type_items);
RNA_def_property_ui_text(prop, "Curves Shape Type", "Curves shape type");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVES);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_render_update");
prop = RNA_def_property(srna, "hair_subdiv", PROP_INT, PROP_NONE);

View File

@ -237,6 +237,7 @@ static void rna_def_text(BlenderRNA *brna)
prop = RNA_def_property(srna, "lines", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "TextLine");
RNA_def_property_ui_text(prop, "Lines", "Lines of text");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_TEXT);
prop = RNA_def_property(srna, "current_line", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);

View File

@ -664,6 +664,7 @@ static void rna_def_volume(BlenderRNA *brna)
"Velocity Unit",
"Define how the velocity vectors are interpreted with regard to time, 'frame' means "
"the delta time is 1 frame, 'second' means the delta time is 1 / FPS");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_UNIT);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "velocity_scale", PROP_FLOAT, PROP_NONE);