Merge branch 'master' into sculpt-dev
This commit is contained in:
commit
3efb094fd3
|
@ -135,6 +135,8 @@ class GRAPH_MT_view(Menu):
|
|||
|
||||
layout.separator()
|
||||
|
||||
layout.prop(st, "show_extrapolation")
|
||||
|
||||
layout.prop(st, "show_handles")
|
||||
|
||||
layout.prop(st, "use_only_selected_curves_handles")
|
||||
|
|
|
@ -256,6 +256,157 @@ static ReadAttributePtr adapt_mesh_domain_point_to_corner(const Mesh &mesh,
|
|||
return new_attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* \note Theoretically this interpolation does not need to compute all values at once.
|
||||
* However, doing that makes the implementation simpler, and this can be optimized in the future if
|
||||
* only some values are required.
|
||||
*/
|
||||
template<typename T>
|
||||
static void adapt_mesh_domain_corner_to_polygon_impl(const Mesh &mesh,
|
||||
Span<T> old_values,
|
||||
MutableSpan<T> r_values)
|
||||
{
|
||||
BLI_assert(r_values.size() == mesh.totpoly);
|
||||
attribute_math::DefaultMixer<T> mixer(r_values);
|
||||
|
||||
for (const int poly_index : IndexRange(mesh.totpoly)) {
|
||||
const MPoly &poly = mesh.mpoly[poly_index];
|
||||
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
|
||||
const T value = old_values[loop_index];
|
||||
mixer.mix_in(poly_index, value);
|
||||
}
|
||||
}
|
||||
|
||||
mixer.finalize();
|
||||
}
|
||||
|
||||
static ReadAttributePtr adapt_mesh_domain_corner_to_polygon(const Mesh &mesh,
|
||||
ReadAttributePtr attribute)
|
||||
{
|
||||
ReadAttributePtr new_attribute;
|
||||
const CustomDataType data_type = attribute->custom_data_type();
|
||||
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
|
||||
using T = decltype(dummy);
|
||||
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
|
||||
Array<T> values(mesh.totpoly);
|
||||
adapt_mesh_domain_corner_to_polygon_impl<T>(mesh, attribute->get_span<T>(), values);
|
||||
new_attribute = std::make_unique<OwnedArrayReadAttribute<T>>(ATTR_DOMAIN_POINT,
|
||||
std::move(values));
|
||||
}
|
||||
});
|
||||
return new_attribute;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void adapt_mesh_domain_polygon_to_point_impl(const Mesh &mesh,
|
||||
Span<T> old_values,
|
||||
MutableSpan<T> r_values)
|
||||
{
|
||||
BLI_assert(r_values.size() == mesh.totvert);
|
||||
attribute_math::DefaultMixer<T> mixer(r_values);
|
||||
|
||||
for (const int poly_index : IndexRange(mesh.totpoly)) {
|
||||
const MPoly &poly = mesh.mpoly[poly_index];
|
||||
const T value = old_values[poly_index];
|
||||
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
|
||||
const MLoop &loop = mesh.mloop[loop_index];
|
||||
const int point_index = loop.v;
|
||||
mixer.mix_in(point_index, value);
|
||||
}
|
||||
}
|
||||
|
||||
mixer.finalize();
|
||||
}
|
||||
|
||||
static ReadAttributePtr adapt_mesh_domain_polygon_to_point(const Mesh &mesh,
|
||||
ReadAttributePtr attribute)
|
||||
{
|
||||
ReadAttributePtr new_attribute;
|
||||
const CustomDataType data_type = attribute->custom_data_type();
|
||||
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
|
||||
using T = decltype(dummy);
|
||||
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
|
||||
Array<T> values(mesh.totvert);
|
||||
adapt_mesh_domain_polygon_to_point_impl<T>(mesh, attribute->get_span<T>(), values);
|
||||
new_attribute = std::make_unique<OwnedArrayReadAttribute<T>>(ATTR_DOMAIN_POINT,
|
||||
std::move(values));
|
||||
}
|
||||
});
|
||||
return new_attribute;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void adapt_mesh_domain_polygon_to_corner_impl(const Mesh &mesh,
|
||||
const Span<T> old_values,
|
||||
MutableSpan<T> r_values)
|
||||
{
|
||||
BLI_assert(r_values.size() == mesh.totloop);
|
||||
|
||||
for (const int poly_index : IndexRange(mesh.totpoly)) {
|
||||
const MPoly &poly = mesh.mpoly[poly_index];
|
||||
MutableSpan<T> poly_corner_values = r_values.slice(poly.loopstart, poly.totloop);
|
||||
poly_corner_values.fill(old_values[poly_index]);
|
||||
}
|
||||
}
|
||||
|
||||
static ReadAttributePtr adapt_mesh_domain_polygon_to_corner(const Mesh &mesh,
|
||||
ReadAttributePtr attribute)
|
||||
{
|
||||
ReadAttributePtr new_attribute;
|
||||
const CustomDataType data_type = attribute->custom_data_type();
|
||||
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
|
||||
using T = decltype(dummy);
|
||||
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
|
||||
Array<T> values(mesh.totloop);
|
||||
adapt_mesh_domain_polygon_to_corner_impl<T>(mesh, attribute->get_span<T>(), values);
|
||||
new_attribute = std::make_unique<OwnedArrayReadAttribute<T>>(ATTR_DOMAIN_POINT,
|
||||
std::move(values));
|
||||
}
|
||||
});
|
||||
return new_attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* \note Theoretically this interpolation does not need to compute all values at once.
|
||||
* However, doing that makes the implementation simpler, and this can be optimized in the future if
|
||||
* only some values are required.
|
||||
*/
|
||||
template<typename T>
|
||||
static void adapt_mesh_domain_point_to_polygon_impl(const Mesh &mesh,
|
||||
const Span<T> old_values,
|
||||
MutableSpan<T> r_values)
|
||||
{
|
||||
BLI_assert(r_values.size() == mesh.totpoly);
|
||||
attribute_math::DefaultMixer<T> mixer(r_values);
|
||||
|
||||
for (const int poly_index : IndexRange(mesh.totpoly)) {
|
||||
const MPoly &poly = mesh.mpoly[poly_index];
|
||||
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
|
||||
MLoop &loop = mesh.mloop[loop_index];
|
||||
const int point_index = loop.v;
|
||||
mixer.mix_in(poly_index, old_values[point_index]);
|
||||
}
|
||||
}
|
||||
mixer.finalize();
|
||||
}
|
||||
|
||||
static ReadAttributePtr adapt_mesh_domain_point_to_polygon(const Mesh &mesh,
|
||||
ReadAttributePtr attribute)
|
||||
{
|
||||
ReadAttributePtr new_attribute;
|
||||
const CustomDataType data_type = attribute->custom_data_type();
|
||||
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
|
||||
using T = decltype(dummy);
|
||||
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
|
||||
Array<T> values(mesh.totpoly);
|
||||
adapt_mesh_domain_point_to_polygon_impl<T>(mesh, attribute->get_span<T>(), values);
|
||||
new_attribute = std::make_unique<OwnedArrayReadAttribute<T>>(ATTR_DOMAIN_POINT,
|
||||
std::move(values));
|
||||
}
|
||||
});
|
||||
return new_attribute;
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
ReadAttributePtr MeshComponent::attribute_try_adapt_domain(ReadAttributePtr attribute,
|
||||
|
@ -277,6 +428,8 @@ ReadAttributePtr MeshComponent::attribute_try_adapt_domain(ReadAttributePtr attr
|
|||
switch (new_domain) {
|
||||
case ATTR_DOMAIN_POINT:
|
||||
return blender::bke::adapt_mesh_domain_corner_to_point(*mesh_, std::move(attribute));
|
||||
case ATTR_DOMAIN_POLYGON:
|
||||
return blender::bke::adapt_mesh_domain_corner_to_polygon(*mesh_, std::move(attribute));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -286,9 +439,23 @@ ReadAttributePtr MeshComponent::attribute_try_adapt_domain(ReadAttributePtr attr
|
|||
switch (new_domain) {
|
||||
case ATTR_DOMAIN_CORNER:
|
||||
return blender::bke::adapt_mesh_domain_point_to_corner(*mesh_, std::move(attribute));
|
||||
case ATTR_DOMAIN_POLYGON:
|
||||
return blender::bke::adapt_mesh_domain_point_to_polygon(*mesh_, std::move(attribute));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ATTR_DOMAIN_POLYGON: {
|
||||
switch (new_domain) {
|
||||
case ATTR_DOMAIN_POINT:
|
||||
return blender::bke::adapt_mesh_domain_polygon_to_point(*mesh_, std::move(attribute));
|
||||
case ATTR_DOMAIN_CORNER:
|
||||
return blender::bke::adapt_mesh_domain_polygon_to_corner(*mesh_, std::move(attribute));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -1760,7 +1760,7 @@ void BKE_sculpt_update_object_before_eval(Object *ob)
|
|||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
if (ss && ss->building_vp_handle == false) {
|
||||
if (!ss->cache && !ss->filter_cache) {
|
||||
if (!ss->cache && !ss->filter_cache && !ss->expand_cache) {
|
||||
/* We free pbvh on changes, except in the middle of drawing a stroke
|
||||
* since it can't deal with changing PVBH node organization, we hope
|
||||
* topology does not change in the meantime .. weak. */
|
||||
|
|
|
@ -89,6 +89,14 @@ bool _bli_array_iter_span(const void *arr,
|
|||
bool _bli_array_is_zeroed(const void *arr, unsigned int arr_len, size_t arr_stride);
|
||||
#define BLI_array_is_zeroed(arr, arr_len) _bli_array_is_zeroed(arr, arr_len, sizeof(*(arr)))
|
||||
|
||||
bool _bli_array_iter_spiral_square(const void *arr_v,
|
||||
const int arr_shape[2],
|
||||
const size_t elem_size,
|
||||
const int center[2],
|
||||
const bool (*test_fn)(const void *arr_item, void *user_data),
|
||||
void *user_data);
|
||||
#define BLI_array_iter_spiral_square(arr, arr_shape, center, test_fn, user_data) \
|
||||
_bli_array_iter_spiral_square(arr, arr_shape, sizeof(*(arr)), center, test_fn, user_data)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -27,13 +27,13 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_array_utils.h"
|
||||
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_strict_flags.h"
|
||||
#include "BLI_sys_types.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLI_strict_flags.h"
|
||||
#include "BLI_array_utils.h"
|
||||
|
||||
/**
|
||||
*In-place array reverse.
|
||||
|
@ -318,3 +318,94 @@ bool _bli_array_is_zeroed(const void *arr_v, unsigned int arr_len, size_t arr_st
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Smart function to sample a rect spiraling outside.
|
||||
* Nice for selection ID.
|
||||
*
|
||||
* \param arr_shape: dimensions [w, h].
|
||||
* \param center: coordinates [x, y] indicating where to start transversing.
|
||||
*/
|
||||
bool _bli_array_iter_spiral_square(const void *arr_v,
|
||||
const int arr_shape[2],
|
||||
size_t elem_size,
|
||||
const int center[2],
|
||||
const bool (*test_fn)(const void *arr_item, void *user_data),
|
||||
void *user_data)
|
||||
{
|
||||
BLI_assert(center[0] >= 0 && center[1] >= 0 && center[0] < arr_shape[0] &&
|
||||
center[1] < arr_shape[1]);
|
||||
|
||||
const char *arr = arr_v;
|
||||
const int stride[2] = {arr_shape[1] * (int)elem_size, (int)elem_size};
|
||||
|
||||
/* Test center first. */
|
||||
int ofs[2] = {center[0] * stride[0], center[1] * stride[1]};
|
||||
if (test_fn(arr + ofs[0] + ofs[1], user_data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* #steps_in and #steps_out are the "diameters" of the inscribed and ciscunscript squares in the
|
||||
* rectangle. Each step smaller than #steps_in does not need to check bounds. */
|
||||
int steps_in, steps_out;
|
||||
{
|
||||
int x_minus = center[0];
|
||||
int x_plus = arr_shape[0] - center[0] - 1;
|
||||
int y_minus = center[1];
|
||||
int y_plus = arr_shape[1] - center[1] - 1;
|
||||
|
||||
steps_in = 2 * min_iiii(x_minus, x_plus, y_minus, y_plus);
|
||||
steps_out = 2 * max_iiii(x_minus, x_plus, y_minus, y_plus);
|
||||
}
|
||||
|
||||
/* For check_bounds. */
|
||||
int limits[2] = {(arr_shape[0] - 1) * stride[0], stride[0] - stride[1]};
|
||||
|
||||
int steps = 0;
|
||||
while (steps < steps_out) {
|
||||
steps += 2;
|
||||
|
||||
/* Move one step to the diagonal of the negative quadrant. */
|
||||
ofs[0] -= stride[0];
|
||||
ofs[1] -= stride[1];
|
||||
|
||||
bool check_bounds = steps > steps_in;
|
||||
|
||||
/* sign: 0 neg; 1 pos; */
|
||||
for (int sign = 2; sign--;) {
|
||||
/* axis: 0 x; 1 y; */
|
||||
for (int axis = 2; axis--;) {
|
||||
int ofs_step = stride[axis];
|
||||
if (!sign) {
|
||||
ofs_step *= -1;
|
||||
}
|
||||
|
||||
int ofs_iter = ofs[axis] + ofs_step;
|
||||
int ofs_dest = ofs[axis] + steps * ofs_step;
|
||||
int ofs_other = ofs[!axis];
|
||||
|
||||
ofs[axis] = ofs_dest;
|
||||
if (check_bounds) {
|
||||
if (ofs_other < 0 || ofs_other > limits[!axis]) {
|
||||
/* Out of bounds. */
|
||||
continue;
|
||||
}
|
||||
|
||||
CLAMP(ofs_iter, 0, limits[axis]);
|
||||
CLAMP(ofs_dest, 0, limits[axis]);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (test_fn(arr + ofs_other + ofs_iter, user_data)) {
|
||||
return true;
|
||||
}
|
||||
if (ofs_iter == ofs_dest) {
|
||||
break;
|
||||
}
|
||||
ofs_iter += ofs_step;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_array_utils.h"
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_bitmap_draw_2d.h"
|
||||
#include "BLI_rect.h"
|
||||
|
@ -336,6 +337,26 @@ uint DRW_select_buffer_sample_point(struct Depsgraph *depsgraph,
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct SelectReadData {
|
||||
const void *val_ptr;
|
||||
uint id_min;
|
||||
uint id_max;
|
||||
uint r_index;
|
||||
};
|
||||
|
||||
static bool select_buffer_test_fn(const void *__restrict value, void *__restrict userdata)
|
||||
{
|
||||
struct SelectReadData *data = userdata;
|
||||
uint hit_id = *(uint *)value;
|
||||
if (hit_id && hit_id >= data->id_min && hit_id < data->id_max) {
|
||||
/* Start at 1 to confirm. */
|
||||
data->val_ptr = value;
|
||||
data->r_index = (hit_id - data->id_min) + 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the selection id closest to \a center.
|
||||
* \param dist: Use to initialize the distance,
|
||||
|
@ -349,13 +370,8 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph,
|
|||
const uint id_max,
|
||||
uint *dist)
|
||||
{
|
||||
/* Smart function to sample a rect spiraling outside, nice for selection ID. */
|
||||
|
||||
/* Create region around center (typically the mouse cursor).
|
||||
* This must be square and have an odd width,
|
||||
* the spiraling algorithm does not work with arbitrary rectangles. */
|
||||
|
||||
uint index = 0;
|
||||
* This must be square and have an odd width. */
|
||||
|
||||
rcti rect;
|
||||
BLI_rcti_init_pt_radius(&rect, center, *dist);
|
||||
|
@ -364,7 +380,6 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph,
|
|||
|
||||
int width = BLI_rcti_size_x(&rect);
|
||||
int height = width;
|
||||
BLI_assert(width == height);
|
||||
|
||||
/* Read from selection framebuffer. */
|
||||
|
||||
|
@ -372,64 +387,23 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph,
|
|||
const uint *buf = DRW_select_buffer_read(depsgraph, region, v3d, &rect, &buf_len);
|
||||
|
||||
if (buf == NULL) {
|
||||
return index;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BLI_assert(width * height == buf_len);
|
||||
const int shape[2] = {height, width};
|
||||
const int center_yx[2] = {(height - 1) / 2, (width - 1) / 2};
|
||||
struct SelectReadData data = {NULL, id_min, id_max, 0};
|
||||
BLI_array_iter_spiral_square(buf, shape, center_yx, select_buffer_test_fn, &data);
|
||||
|
||||
/* Spiral, starting from center of buffer. */
|
||||
int spiral_offset = height * (int)(width / 2) + (height / 2);
|
||||
int spiral_direction = 0;
|
||||
|
||||
for (int nr = 1; nr <= height; nr++) {
|
||||
for (int a = 0; a < 2; a++) {
|
||||
for (int b = 0; b < nr; b++) {
|
||||
/* Find hit within the specified range. */
|
||||
uint hit_id = buf[spiral_offset];
|
||||
|
||||
if (hit_id && hit_id >= id_min && hit_id < id_max) {
|
||||
/* Get x/y from spiral offset. */
|
||||
int hit_x = spiral_offset % width;
|
||||
int hit_y = spiral_offset / width;
|
||||
|
||||
int center_x = width / 2;
|
||||
int center_y = height / 2;
|
||||
|
||||
/* Manhattan distance in keeping with other screen-based selection. */
|
||||
*dist = (uint)(abs(hit_x - center_x) + abs(hit_y - center_y));
|
||||
|
||||
/* Indices start at 1 here. */
|
||||
index = (hit_id - id_min) + 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Next spiral step. */
|
||||
if (spiral_direction == 0) {
|
||||
spiral_offset += 1; /* right */
|
||||
}
|
||||
else if (spiral_direction == 1) {
|
||||
spiral_offset -= width; /* down */
|
||||
}
|
||||
else if (spiral_direction == 2) {
|
||||
spiral_offset -= 1; /* left */
|
||||
}
|
||||
else {
|
||||
spiral_offset += width; /* up */
|
||||
}
|
||||
|
||||
/* Stop if we are outside the buffer. */
|
||||
if (spiral_offset < 0 || spiral_offset >= buf_len) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
spiral_direction = (spiral_direction + 1) % 4;
|
||||
}
|
||||
if (data.val_ptr) {
|
||||
size_t offset = ((size_t)data.val_ptr - (size_t)buf) / sizeof(*buf);
|
||||
int hit_x = offset % width;
|
||||
int hit_y = offset / width;
|
||||
*dist = (uint)(abs(hit_y - center_yx[0]) + abs(hit_x - center_yx[1]));
|
||||
}
|
||||
|
||||
exit:
|
||||
MEM_freeN((void *)buf);
|
||||
return index;
|
||||
return data.r_index;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -173,15 +173,11 @@ static PanelType *fmodifier_panel_register(ARegionType *region_type,
|
|||
PanelTypePollFn poll,
|
||||
const char *id_prefix)
|
||||
{
|
||||
/* Get the name for the modifier's panel. */
|
||||
char panel_idname[BKE_ST_MAXNAME];
|
||||
const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(type);
|
||||
BLI_snprintf(panel_idname, BKE_ST_MAXNAME, "%s_PT_%s", id_prefix, fmi->name);
|
||||
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
|
||||
|
||||
/* Intentionally leave the label field blank. The header is filled with buttons. */
|
||||
BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
|
||||
const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(type);
|
||||
BLI_snprintf(panel_type->idname, BKE_ST_MAXNAME, "%s_PT_%s", id_prefix, fmi->name);
|
||||
BLI_strncpy(panel_type->category, "Modifiers", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
|
||||
|
||||
|
@ -215,13 +211,9 @@ static PanelType *fmodifier_subpanel_register(ARegionType *region_type,
|
|||
PanelTypePollFn poll,
|
||||
PanelType *parent)
|
||||
{
|
||||
/* Create the subpanel's ID name. */
|
||||
char panel_idname[BKE_ST_MAXNAME];
|
||||
BLI_snprintf(panel_idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
|
||||
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
|
||||
|
||||
BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
|
||||
BLI_snprintf(panel_type->idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
|
||||
BLI_strncpy(panel_type->label, label, BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->category, "Modifiers", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
|
||||
|
|
|
@ -556,14 +556,6 @@ static bool sculpt_face_sets_init_bevel_weight_test(
|
|||
return BM_elem_float_data_get(&bm->edata, from_e, CD_BWEIGHT) < threshold;
|
||||
}
|
||||
|
||||
static bool sculpt_face_sets_init_face_set_boundary_test(
|
||||
BMesh *bm, BMFace *from_f, BMEdge *UNUSED(from_e), BMFace *to_f, const float UNUSED(threshold))
|
||||
{
|
||||
const int cd_face_sets_offset = CustomData_get_offset(&bm->pdata, CD_SCULPT_FACE_SETS);
|
||||
return BM_ELEM_CD_GET_INT(from_f, cd_face_sets_offset) ==
|
||||
BM_ELEM_CD_GET_INT(to_f, cd_face_sets_offset);
|
||||
}
|
||||
|
||||
static bool sculpt_face_sets_init_sharp_edges_test(BMesh *UNUSED(bm),
|
||||
BMFace *UNUSED(from_f),
|
||||
BMEdge *from_e,
|
||||
|
@ -573,6 +565,14 @@ static bool sculpt_face_sets_init_sharp_edges_test(BMesh *UNUSED(bm),
|
|||
return BM_elem_flag_test(from_e, BM_ELEM_SMOOTH);
|
||||
}
|
||||
|
||||
static bool sculpt_face_sets_init_face_set_boundary_test(
|
||||
BMesh *bm, BMFace *from_f, BMEdge *UNUSED(from_e), BMFace *to_f, const float UNUSED(threshold))
|
||||
{
|
||||
const int cd_face_sets_offset = CustomData_get_offset(&bm->pdata, CD_SCULPT_FACE_SETS);
|
||||
return BM_ELEM_CD_GET_INT(from_f, cd_face_sets_offset) ==
|
||||
BM_ELEM_CD_GET_INT(to_f, cd_face_sets_offset);
|
||||
}
|
||||
|
||||
static void sculpt_face_sets_init_flood_fill(Object *ob,
|
||||
face_sets_flood_fill_test test,
|
||||
const float threshold)
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_anim_data.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curve.h"
|
||||
|
@ -579,8 +580,13 @@ static void draw_fcurve_samples(SpaceGraph *sipo, ARegion *region, FCurve *fcu)
|
|||
|
||||
/* Helper func - just draw the F-Curve by sampling the visible region
|
||||
* (for drawing curves with modifiers). */
|
||||
static void draw_fcurve_curve(
|
||||
bAnimContext *ac, ID *id, FCurve *fcu_, View2D *v2d, uint pos, const bool use_nla_remap)
|
||||
static void draw_fcurve_curve(bAnimContext *ac,
|
||||
ID *id,
|
||||
FCurve *fcu_,
|
||||
View2D *v2d,
|
||||
uint pos,
|
||||
const bool use_nla_remap,
|
||||
const bool draw_extrapolation)
|
||||
{
|
||||
SpaceGraph *sipo = (SpaceGraph *)ac->sl;
|
||||
short mapping_flag = ANIM_get_normalization_flags(ac);
|
||||
|
@ -641,40 +647,90 @@ static void draw_fcurve_curve(
|
|||
|
||||
/* the start/end times are simply the horizontal extents of the 'cur' rect */
|
||||
float stime = v2d->cur.xmin;
|
||||
float etime = v2d->cur.xmax +
|
||||
samplefreq; /* + samplefreq here so that last item gets included... */
|
||||
float etime = v2d->cur.xmax;
|
||||
|
||||
/* at each sampling interval, add a new vertex
|
||||
* - apply the unit correction factor to the calculated values so that
|
||||
* the displayed values appear correctly in the viewport
|
||||
*/
|
||||
AnimData *adt = use_nla_remap ? BKE_animdata_from_id(id) : NULL;
|
||||
|
||||
int n = roundf((etime - stime) / samplefreq);
|
||||
/* If not drawing extrapolation, then change fcurve drawing bounds to its keyframe bounds clamped
|
||||
* by graph editor bounds. */
|
||||
if (!draw_extrapolation) {
|
||||
float fcu_start = 0;
|
||||
float fcu_end = 0;
|
||||
BKE_fcurve_calc_range(fcu_, &fcu_start, &fcu_end, false, false);
|
||||
|
||||
if (n > 0) {
|
||||
immBegin(GPU_PRIM_LINE_STRIP, (n + 1));
|
||||
fcu_start = BKE_nla_tweakedit_remap(adt, fcu_start, NLATIME_CONVERT_MAP);
|
||||
fcu_end = BKE_nla_tweakedit_remap(adt, fcu_end, NLATIME_CONVERT_MAP);
|
||||
|
||||
AnimData *adt = use_nla_remap ? BKE_animdata_from_id(id) : NULL;
|
||||
/* NLA remapping is linear so we don't have to remap per iteration. */
|
||||
const float eval_start = BKE_nla_tweakedit_remap(adt, stime, NLATIME_CONVERT_UNMAP);
|
||||
const float eval_freq = BKE_nla_tweakedit_remap(
|
||||
adt, stime + samplefreq, NLATIME_CONVERT_UNMAP) -
|
||||
eval_start;
|
||||
|
||||
for (int i = 0; i <= n; i++) {
|
||||
float ctime = stime + i * samplefreq;
|
||||
const float eval_time = eval_start + i * eval_freq;
|
||||
immVertex2f(pos, ctime, (evaluate_fcurve(&fcurve_for_draw, eval_time) + offset) * unitFac);
|
||||
/* Account for reversed NLA strip effect. */
|
||||
if (fcu_end < fcu_start) {
|
||||
SWAP(float, fcu_start, fcu_end);
|
||||
}
|
||||
|
||||
immEnd();
|
||||
/* Clamp to graph editor rendering bounds. */
|
||||
stime = max_ff(stime, fcu_start);
|
||||
etime = min_ff(etime, fcu_end);
|
||||
}
|
||||
|
||||
const int total_samples = roundf((etime - stime) / samplefreq);
|
||||
if (total_samples <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* NLA remapping is linear so we don't have to remap per iteration. */
|
||||
const float eval_start = BKE_nla_tweakedit_remap(adt, stime, NLATIME_CONVERT_UNMAP);
|
||||
const float eval_freq = BKE_nla_tweakedit_remap(adt, stime + samplefreq, NLATIME_CONVERT_UNMAP) -
|
||||
eval_start;
|
||||
const float eval_end = BKE_nla_tweakedit_remap(adt, etime, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
immBegin(GPU_PRIM_LINE_STRIP, (total_samples + 1));
|
||||
|
||||
/* At each sampling interval, add a new vertex.
|
||||
*
|
||||
* Apply the unit correction factor to the calculated values so that the displayed values appear
|
||||
* correctly in the viewport.
|
||||
*/
|
||||
for (int i = 0; i < total_samples; i++) {
|
||||
const float ctime = stime + i * samplefreq;
|
||||
float eval_time = eval_start + i * eval_freq;
|
||||
|
||||
/* Prevent drawing past bounds, due to floating point problems.
|
||||
* User-wise, prevent visual flickering.
|
||||
*
|
||||
* This is to cover the case where:
|
||||
* eval_start + total_samples * eval_freq > eval_end
|
||||
* due to floating point problems.
|
||||
*/
|
||||
if (eval_time > eval_end) {
|
||||
eval_time = eval_end;
|
||||
}
|
||||
|
||||
immVertex2f(pos, ctime, (evaluate_fcurve(&fcurve_for_draw, eval_time) + offset) * unitFac);
|
||||
}
|
||||
|
||||
/* Ensure we include end boundary point.
|
||||
* User-wise, prevent visual flickering.
|
||||
*
|
||||
* This is to cover the case where:
|
||||
* eval_start + total_samples * eval_freq < eval_end
|
||||
* due to floating point problems.
|
||||
*/
|
||||
immVertex2f(pos, etime, (evaluate_fcurve(&fcurve_for_draw, eval_end) + offset) * unitFac);
|
||||
|
||||
immEnd();
|
||||
}
|
||||
|
||||
/* helper func - draw a samples-based F-Curve */
|
||||
static void draw_fcurve_curve_samples(
|
||||
bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, const uint shdr_pos)
|
||||
static void draw_fcurve_curve_samples(bAnimContext *ac,
|
||||
ID *id,
|
||||
FCurve *fcu,
|
||||
View2D *v2d,
|
||||
const uint shdr_pos,
|
||||
const bool draw_extrapolation)
|
||||
{
|
||||
if (!draw_extrapolation && fcu->totvert == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
FPoint *prevfpt = fcu->fpt;
|
||||
FPoint *fpt = prevfpt + 1;
|
||||
float fac, v[2];
|
||||
|
@ -683,11 +739,13 @@ static void draw_fcurve_curve_samples(
|
|||
short mapping_flag = ANIM_get_normalization_flags(ac);
|
||||
int count = fcu->totvert;
|
||||
|
||||
if (prevfpt->vec[0] > v2d->cur.xmin) {
|
||||
const bool extrap_left = draw_extrapolation && prevfpt->vec[0] > v2d->cur.xmin;
|
||||
if (extrap_left) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if ((prevfpt + b - 1)->vec[0] < v2d->cur.xmax) {
|
||||
const bool extrap_right = draw_extrapolation && (prevfpt + b - 1)->vec[0] < v2d->cur.xmax;
|
||||
if (extrap_right) {
|
||||
count++;
|
||||
}
|
||||
|
||||
|
@ -700,7 +758,7 @@ static void draw_fcurve_curve_samples(
|
|||
immBegin(GPU_PRIM_LINE_STRIP, count);
|
||||
|
||||
/* extrapolate to left? - left-side of view comes before first keyframe? */
|
||||
if (prevfpt->vec[0] > v2d->cur.xmin) {
|
||||
if (extrap_left) {
|
||||
v[0] = v2d->cur.xmin;
|
||||
|
||||
/* y-value depends on the interpolation */
|
||||
|
@ -734,7 +792,7 @@ static void draw_fcurve_curve_samples(
|
|||
}
|
||||
|
||||
/* extrapolate to right? (see code for left-extrapolation above too) */
|
||||
if (prevfpt->vec[0] < v2d->cur.xmax) {
|
||||
if (extrap_right) {
|
||||
v[0] = v2d->cur.xmax;
|
||||
|
||||
/* y-value depends on the interpolation */
|
||||
|
@ -779,8 +837,13 @@ static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu)
|
|||
}
|
||||
|
||||
/* helper func - draw one repeat of an F-Curve (using Bezier curve approximations) */
|
||||
static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, uint pos)
|
||||
static void draw_fcurve_curve_bezts(
|
||||
bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, uint pos, const bool draw_extrapolation)
|
||||
{
|
||||
if (!draw_extrapolation && fcu->totvert == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
BezTriple *prevbezt = fcu->bezt;
|
||||
BezTriple *bezt = prevbezt + 1;
|
||||
float v1[2], v2[2], v3[2], v4[2];
|
||||
|
@ -803,7 +866,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
|
|||
immBeginAtMost(GPU_PRIM_LINE_STRIP, (b * 32 + 3));
|
||||
|
||||
/* extrapolate to left? */
|
||||
if (prevbezt->vec[1][0] > v2d->cur.xmin) {
|
||||
if (draw_extrapolation && prevbezt->vec[1][0] > v2d->cur.xmin) {
|
||||
/* left-side of view comes before first keyframe, so need to extend as not cyclic */
|
||||
v1[0] = v2d->cur.xmin;
|
||||
|
||||
|
@ -923,7 +986,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
|
|||
}
|
||||
|
||||
/* extrapolate to right? (see code for left-extrapolation above too) */
|
||||
if (prevbezt->vec[1][0] < v2d->cur.xmax) {
|
||||
if (draw_extrapolation && prevbezt->vec[1][0] < v2d->cur.xmax) {
|
||||
v1[0] = v2d->cur.xmax;
|
||||
|
||||
/* y-value depends on the interpolation */
|
||||
|
@ -1026,6 +1089,7 @@ static void draw_fcurve(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, bAn
|
|||
immUniformColor3fvAlpha(fcu->color, fcurve_display_alpha(fcu));
|
||||
}
|
||||
|
||||
const bool draw_extrapolation = (sipo->flag & SIPO_NO_DRAW_EXTRAPOLATION) == 0;
|
||||
/* draw F-Curve */
|
||||
if ((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) {
|
||||
/* draw a curve affected by modifiers or only allowed to have integer values
|
||||
|
@ -1039,25 +1103,25 @@ static void draw_fcurve(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, bAn
|
|||
* curve itself. Afterward, we go back and redo the keyframe remapping so the controls are
|
||||
* drawn properly. */
|
||||
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, true, false);
|
||||
draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, true);
|
||||
draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, true, draw_extrapolation);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, false, false);
|
||||
}
|
||||
else {
|
||||
draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, false);
|
||||
draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, false, draw_extrapolation);
|
||||
}
|
||||
}
|
||||
else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
|
||||
/* just draw curve based on defined data (i.e. no modifiers) */
|
||||
if (fcu->bezt) {
|
||||
if (fcurve_can_use_simple_bezt_drawing(fcu)) {
|
||||
draw_fcurve_curve_bezts(ac, ale->id, fcu, ®ion->v2d, shdr_pos);
|
||||
draw_fcurve_curve_bezts(ac, ale->id, fcu, ®ion->v2d, shdr_pos, draw_extrapolation);
|
||||
}
|
||||
else {
|
||||
draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, false);
|
||||
draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, false, draw_extrapolation);
|
||||
}
|
||||
}
|
||||
else if (fcu->fpt) {
|
||||
draw_fcurve_curve_samples(ac, ale->id, fcu, ®ion->v2d, shdr_pos);
|
||||
draw_fcurve_curve_samples(ac, ale->id, fcu, ®ion->v2d, shdr_pos, draw_extrapolation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1278,6 +1342,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region
|
|||
immUniform1f("dash_width", 20.0f);
|
||||
immUniform1f("dash_factor", 0.5f);
|
||||
|
||||
const bool draw_extrapolation = (sipo->flag & SIPO_NO_DRAW_EXTRAPOLATION) == 0;
|
||||
/* the ghost curves are simply sampled F-Curves stored in sipo->runtime.ghost_curves */
|
||||
for (fcu = sipo->runtime.ghost_curves.first; fcu; fcu = fcu->next) {
|
||||
/* set whatever color the curve has set
|
||||
|
@ -1287,7 +1352,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region
|
|||
immUniformColor3fvAlpha(fcu->color, 0.5f);
|
||||
|
||||
/* simply draw the stored samples */
|
||||
draw_fcurve_curve_samples(ac, NULL, fcu, ®ion->v2d, shdr_pos);
|
||||
draw_fcurve_curve_samples(ac, NULL, fcu, ®ion->v2d, shdr_pos, draw_extrapolation);
|
||||
}
|
||||
|
||||
immUnbindProgram();
|
||||
|
|
|
@ -371,14 +371,9 @@ PanelType *gpencil_modifier_panel_register(ARegionType *region_type,
|
|||
GpencilModifierType type,
|
||||
PanelDrawFn draw)
|
||||
{
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
|
||||
|
||||
/* Get the name for the modifier's panel. */
|
||||
char panel_idname[BKE_ST_MAXNAME];
|
||||
BKE_gpencil_modifierType_panel_id(type, panel_idname);
|
||||
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
|
||||
|
||||
BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
|
||||
BKE_gpencil_modifierType_panel_id(type, panel_type->idname);
|
||||
BLI_strncpy(panel_type->label, "", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->context, "modifier", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
|
||||
|
@ -412,13 +407,9 @@ PanelType *gpencil_modifier_subpanel_register(ARegionType *region_type,
|
|||
PanelDrawFn draw,
|
||||
PanelType *parent)
|
||||
{
|
||||
/* Create the subpanel's ID name. */
|
||||
char panel_idname[BKE_ST_MAXNAME];
|
||||
BLI_snprintf(panel_idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
|
||||
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
|
||||
|
||||
BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
|
||||
BLI_snprintf(panel_type->idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
|
||||
BLI_strncpy(panel_type->label, label, BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->context, "modifier", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
|
||||
|
|
|
@ -492,6 +492,7 @@ typedef enum eGraphEdit_Flag {
|
|||
SIPO_NORMALIZE_FREEZE = (1 << 15),
|
||||
/* show markers region */
|
||||
SIPO_SHOW_MARKERS = (1 << 16),
|
||||
SIPO_NO_DRAW_EXTRAPOLATION = (1 << 17),
|
||||
} eGraphEdit_Flag;
|
||||
|
||||
/* SpaceGraph.mode (Graph Editor Mode) */
|
||||
|
|
|
@ -5681,6 +5681,11 @@ static void rna_def_space_graph(BlenderRNA *brna)
|
|||
"If any exists, show markers in a separate row at the bottom of the editor");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_extrapolation", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NO_DRAW_EXTRAPOLATION);
|
||||
RNA_def_property_ui_text(prop, "Show Extrapolation", "");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
|
||||
|
||||
/* editing */
|
||||
prop = RNA_def_property(srna, "use_auto_merge_keyframes", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NOTRANSKEYCULL);
|
||||
|
|
|
@ -409,13 +409,9 @@ static void modifier_panel_header(const bContext *C, Panel *panel)
|
|||
*/
|
||||
PanelType *modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
|
||||
{
|
||||
/* Get the name for the modifier's panel. */
|
||||
char panel_idname[BKE_ST_MAXNAME];
|
||||
BKE_modifier_type_panel_id(type, panel_idname);
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
|
||||
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
|
||||
|
||||
BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
|
||||
BKE_modifier_type_panel_id(type, panel_type->idname);
|
||||
BLI_strncpy(panel_type->label, "", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->context, "modifier", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
|
||||
|
@ -450,13 +446,9 @@ PanelType *modifier_subpanel_register(ARegionType *region_type,
|
|||
PanelDrawFn draw,
|
||||
PanelType *parent)
|
||||
{
|
||||
/* Create the subpanel's ID name. */
|
||||
char panel_idname[BKE_ST_MAXNAME];
|
||||
BLI_snprintf(panel_idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
|
||||
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
|
||||
|
||||
BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
|
||||
BLI_snprintf(panel_type->idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
|
||||
BLI_strncpy(panel_type->label, label, BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->context, "modifier", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
|
||||
|
|
|
@ -241,14 +241,9 @@ static bool shaderfx_ui_poll(const bContext *C, PanelType *UNUSED(pt))
|
|||
*/
|
||||
PanelType *shaderfx_panel_register(ARegionType *region_type, ShaderFxType type, PanelDrawFn draw)
|
||||
{
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
|
||||
|
||||
/* Get the name for the effect's panel. */
|
||||
char panel_idname[BKE_ST_MAXNAME];
|
||||
BKE_shaderfxType_panel_id(type, panel_idname);
|
||||
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
|
||||
|
||||
BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
|
||||
BKE_shaderfxType_panel_id(type, panel_type->idname);
|
||||
BLI_strncpy(panel_type->label, "", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->context, "shaderfx", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
|
||||
|
@ -282,13 +277,9 @@ PanelType *shaderfx_subpanel_register(ARegionType *region_type,
|
|||
PanelDrawFn draw,
|
||||
PanelType *parent)
|
||||
{
|
||||
/* Create the subpanel's ID name. */
|
||||
char panel_idname[BKE_ST_MAXNAME];
|
||||
BLI_snprintf(panel_idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
|
||||
|
||||
PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
|
||||
|
||||
BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
|
||||
BLI_snprintf(panel_type->idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
|
||||
BLI_strncpy(panel_type->label, label, BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->context, "shaderfx", BKE_ST_MAXNAME);
|
||||
BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
|
||||
|
|
Loading…
Reference in New Issue