Image Editor Vectorscope Improvement #116974

Merged
Aras Pranckevicius merged 13 commits from JonasDichelle/blender:vectorscope-update into main 2024-02-06 12:22:57 +01:00
5 changed files with 220 additions and 84 deletions

View File

@ -1431,8 +1431,11 @@ class IMAGE_PT_view_vectorscope(ImageScopesPanel, Panel):
layout = self.layout
sima = context.space_data
layout.template_vectorscope(sima, "scopes")
layout.prop(sima.scopes, "vectorscope_alpha")
row = layout.split(factor=0.75)
row.prop(sima.scopes, "vectorscope_alpha")
row.prop(sima.scopes, "vectorscope_mode", text="")
class IMAGE_PT_sample_line(ImageScopesPanel, Panel):

View File

@ -1359,6 +1359,12 @@ static void save_sample_line(
scopes->vecscope[idx + 0] = yuv[1];
scopes->vecscope[idx + 1] = yuv[2];
int color_idx = (idx / 2) * 4;
scopes->vecscope_rgb[color_idx + 0] = rgb[0];
scopes->vecscope_rgb[color_idx + 1] = rgb[1];
scopes->vecscope_rgb[color_idx + 2] = rgb[2];
scopes->vecscope_rgb[color_idx + 3] = scopes->vecscope_alpha;
aras_p marked this conversation as resolved

Given that vecscope_rgb always uses the same single value for the alpha component of each point, would it be worth changing it to allocate 3 floats per sample instead of 4? Would save some memory, and at draw time could just fetch the alpha from vecscope_alpha field.

Given that `vecscope_rgb` always uses the same single value for the alpha component of each point, would it be worth changing it to allocate 3 floats per sample instead of 4? Would save some memory, and at draw time could just fetch the alpha from `vecscope_alpha` field.
Review

I did this because we need to pass in 4 values for each Vertex into the shader.
Having individual alphas for each vertex is necessary to get good looking accumulation.
If we didn't do this here we would need to add the alpha values to the array at a later point.
The only way to avoid this would be to create a new shader.
But please correct me if I'm wrong.

I did this because we need to pass in 4 values for each Vertex into the shader. Having individual alphas for each vertex is necessary to get good looking accumulation. If we didn't do this here we would need to add the alpha values to the array at a later point. The only way to avoid this would be to create a new shader. But please correct me if I'm wrong.

Ah, I see, this array is directly copied into the GPU vertex buffer. Ignore me then!

Ah, I see, this array is directly copied into the GPU vertex buffer. Ignore me then!
/* Waveform. */
switch (scopes->wavefrm_mode) {
case SCOPES_WAVEFRM_RGB:
@ -1707,6 +1713,7 @@ void BKE_scopes_update(Scopes *scopes,
}
if (scopes->vecscope) {
MEM_freeN(scopes->vecscope);
MEM_freeN(scopes->vecscope_rgb);
}
scopes->waveform_1 = static_cast<float *>(
@ -1717,6 +1724,8 @@ void BKE_scopes_update(Scopes *scopes,
MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3"));
scopes->vecscope = static_cast<float *>(
MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel"));
scopes->vecscope_rgb = static_cast<float *>(
MEM_callocN(scopes->waveform_tot * 4 * sizeof(float), "vectorscope color channel"));
if (ibuf->float_buffer.data) {
cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
@ -1794,6 +1803,7 @@ void BKE_scopes_free(Scopes *scopes)
MEM_SAFE_FREE(scopes->waveform_2);
MEM_SAFE_FREE(scopes->waveform_3);
MEM_SAFE_FREE(scopes->vecscope);
MEM_SAFE_FREE(scopes->vecscope_rgb);
}
void BKE_scopes_new(Scopes *scopes)
@ -1810,6 +1820,7 @@ void BKE_scopes_new(Scopes *scopes)
scopes->waveform_2 = nullptr;
scopes->waveform_3 = nullptr;
scopes->vecscope = nullptr;
scopes->vecscope_rgb = nullptr;
}
void BKE_color_managed_display_settings_init(ColorManagedDisplaySettings *settings)

View File

@ -610,6 +610,44 @@ static void waveform_draw_one(float *waveform, int waveform_num, const float col
GPU_batch_discard(batch);
}
static void waveform_draw_rgb(float *waveform, int waveform_num, float *col)
{
GPUVertFormat format = {0};
const uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
const uint col_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, waveform_num);
GPU_vertbuf_attr_fill(vbo, pos_id, waveform);
GPU_vertbuf_attr_fill(vbo, col_id, col);
GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR);
GPU_batch_draw(batch);
GPU_batch_discard(batch);
}
static void circle_draw_rgb(float *points, int tot_points, float *col, GPUPrimType prim)
{
GPUVertFormat format = {0};
const uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
const uint col_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, tot_points);
GPU_vertbuf_attr_fill(vbo, pos_id, points);
GPU_vertbuf_attr_fill(vbo, col_id, col);
GPUBatch *batch = GPU_batch_create_ex(prim, vbo, nullptr, GPU_BATCH_OWNS_VBO);
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR);
GPU_batch_draw(batch);
GPU_batch_discard(batch);
}
void ui_draw_but_WAVEFORM(ARegion * /*region*/,
uiBut *but,
const uiWidgetColors * /*wcol*/,
@ -687,8 +725,6 @@ void ui_draw_but_WAVEFORM(ARegion * /*region*/,
/* Flush text cache before drawing things on top. */
BLF_batch_draw_flush();
GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@ -863,11 +899,12 @@ static float polar_to_y(float center, float diam, float ampli, float angle)
}
static void vectorscope_draw_target(
uint pos, float centerx, float centery, float diam, const float colf[3])
uint pos, float centerx, float centery, float diam, const float colf[3], char label)
{
float y, u, v;
float tangle = 0.0f, tampli;
float dangle, dampli, dangle2, dampli2;
char labelstr[2] = {label, '\0'};
rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v, BLI_YUV_ITU_BT709);
@ -905,56 +942,15 @@ static void vectorscope_draw_target(
immVertex2f(pos,
polar_to_x(centerx, diam, tampli + dampli, tangle - dangle),
polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
immEnd();
/* big target vary by 10 degree and 20% amplitude */
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
dangle = DEG2RADF(10.0f);
dampli = 0.2f * tampli;
dangle2 = DEG2RADF(5.0f);
dampli2 = 0.5f * dampli;
immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos,
polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle + dangle),
polar_to_y(centery, diam, tampli + dampli - dampli2, tangle + dangle));
immVertex2f(pos,
polar_to_x(centerx, diam, tampli + dampli, tangle + dangle),
polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
immVertex2f(pos,
polar_to_x(centerx, diam, tampli + dampli, tangle + dangle - dangle2),
polar_to_y(centery, diam, tampli + dampli, tangle + dangle - dangle2));
immEnd();
immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos,
polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle + dangle),
polar_to_y(centery, diam, tampli - dampli + dampli2, tangle + dangle));
immVertex2f(pos,
polar_to_x(centerx, diam, tampli - dampli, tangle + dangle),
polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
immVertex2f(pos,
polar_to_x(centerx, diam, tampli - dampli, tangle + dangle - dangle2),
polar_to_y(centery, diam, tampli - dampli, tangle + dangle - dangle2));
immEnd();
immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos,
polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle - dangle),
polar_to_y(centery, diam, tampli - dampli + dampli2, tangle - dangle));
immVertex2f(pos,
polar_to_x(centerx, diam, tampli - dampli, tangle - dangle),
polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
immVertex2f(pos,
polar_to_x(centerx, diam, tampli - dampli, tangle - dangle + dangle2),
polar_to_y(centery, diam, tampli - dampli, tangle - dangle + dangle2));
immEnd();
immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex2f(pos,
polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle - dangle),
polar_to_y(centery, diam, tampli + dampli - dampli2, tangle - dangle));
immVertex2f(pos,
polar_to_x(centerx, diam, tampli + dampli, tangle - dangle),
polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
immVertex2f(pos,
polar_to_x(centerx, diam, tampli + dampli, tangle - dangle + dangle2),
polar_to_y(centery, diam, tampli + dampli, tangle - dangle + dangle2));
/* draw color letter as text */
BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.3f);
BLF_draw_default(polar_to_x(centerx, diam, tampli, tangle) + 5,
polar_to_y(centery, diam, tampli, tangle),
0,
labelstr,
strlen(labelstr));
JonasDichelle marked this conversation as resolved Outdated

In general blender uses C style comments, i.e. /* foo */ not // foo

In general blender uses C style comments, i.e. `/* foo */` not `// foo`

thanks for the hint!

thanks for the hint!
immEnd();
}
@ -967,14 +963,16 @@ void ui_draw_but_VECTORSCOPE(ARegion * /*region*/,
Scopes *scopes = (Scopes *)but->poin;
const float colors[6][3] = {
{0.75, 0.0, 0.0},
{0.75, 0.75, 0.0},
{0.0, 0.75, 0.0},
{0.0, 0.75, 0.75},
{0.0, 0.0, 0.75},
{0.75, 0.0, 0.75},
{0.75, 0.0, 0.0}, /* Red */
{0.75, 0.75, 0.0}, /* Yellow */
{0.0, 0.75, 0.0}, /* Green */
{0.0, 0.75, 0.75}, /* Cyan */
{0.0, 0.0, 0.75}, /* Blue */
{0.75, 0.0, 0.75}, /* Magenta */
};
const char color_names[] = {'R', 'Y', 'G', 'C', 'B', 'M'};
aras_p marked this conversation as resolved Outdated

Minor: not sure why color names are array of 4 characters each, when they are all a single char. Maybe change them to not be strings at all, and make vectorscope_draw_target just take a single char for the letter? (and internally have a char[2] buffer for passing to font drawing functions)

Minor: not sure why color names are array of 4 characters each, when they are all a single char. Maybe change them to not be strings at all, and make vectorscope_draw_target just take a single char for the letter? (and internally have a `char[2]` buffer for passing to font drawing functions)

Good call, I'll change that!

Good call, I'll change that!

i updated it in 2bebddf117

i updated it in 2bebddf117
rctf rect{};
rect.xmin = float(recti->xmin + 1);
rect.xmax = float(recti->xmax - 1);
@ -987,8 +985,9 @@ void ui_draw_but_VECTORSCOPE(ARegion * /*region*/,
const float centery = rect.ymin + h * 0.5f;
const float diam = (w < h) ? w : h;
const float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha;
const float alpha = scopes->vecscope_alpha;
GPU_line_smooth(true);
GPU_blend(GPU_BLEND_ALPHA);
float color[4];
@ -1013,10 +1012,118 @@ void ui_draw_but_VECTORSCOPE(ARegion * /*region*/,
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
const int increment = 6;
const int tot_points = int(360 / increment);
const float r = 0.5f;
float step = 360.0f / (tot_points - 1);
float circle_fill_points[(tot_points * 2) + 2];
float circle_fill_vertex_colors[(tot_points * 4) + 4];
/* draw filled RGB circle for background, only for LUMA mode */
if (scopes->vecscope_mode == SCOPES_VECSCOPE_LUMA) {
/* Initialize center point and color */
circle_fill_points[0] = centerx;
circle_fill_points[1] = centery;
circle_fill_vertex_colors[0] = 0.2f;
circle_fill_vertex_colors[1] = 0.2f;
circle_fill_vertex_colors[2] = 0.2f;
circle_fill_vertex_colors[3] = 0.8f;
for (int i = 0; i < tot_points; i++) {
float angle = step * i;
const float a = DEG2RADF(angle);
const float x = polar_to_x(centerx, diam, r, a);
const float y = polar_to_y(centery, diam, r, a);
const float u = polar_to_x(0.0f, 1.0, 1.0f, a);
const float v = polar_to_y(0.0f, 1.0, 1.0f, a);
circle_fill_points[(i + 1) * 2] = x;
circle_fill_points[(i + 1) * 2 + 1] = y;
float r, g, b;
yuv_to_rgb(0.5f, u, v, &r, &g, &b, BLI_YUV_ITU_BT709);
circle_fill_vertex_colors[(i + 1) * 4] = r * 0.2f;
circle_fill_vertex_colors[(i + 1) * 4 + 1] = g * 0.2f;
circle_fill_vertex_colors[(i + 1) * 4 + 2] = b * 0.2f;
circle_fill_vertex_colors[(i + 1) * 4 + 3] = 0.8f;
}
GPU_blend(GPU_BLEND_ALPHA);
circle_draw_rgb(
circle_fill_points, tot_points + 2, circle_fill_vertex_colors, GPU_PRIM_TRI_FAN);
}
/* draw filled Gray circle for background, only for RGB mode */
else if (scopes->vecscope_mode == SCOPES_VECSCOPE_RGB) {
GPU_blend(GPU_BLEND_NONE);
immBegin(GPU_PRIM_TRI_FAN, tot_points + 2);
immUniformColor3f(0.16f, 0.16f, 0.16f);
immVertex2f(pos, centerx, centery);
for (int i = 0; i <= 360; i += increment) {
const float a = DEG2RADF(float(i));
immVertex2f(pos, polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
}
immEnd();
}
/* draw RGB ring */
float circle_points[(tot_points * 2) + 3] = {};
float circle_vertex_colors[(tot_points * 4) + 5] = {};
for (int i = 0; i < tot_points; i++) {
float angle = step * i;
const float a = DEG2RADF(angle);
const float x = polar_to_x(centerx, diam, 0.5f, a);
const float y = polar_to_y(centery, diam, 0.5f, a);
circle_points[i * 2] = x;
circle_points[i * 2 + 1] = y;
const float u = polar_to_x(0.0f, 1.0, 1.0f, a);
const float v = polar_to_y(0.0f, 1.0, 1.0f, a);
float r, g, b;
yuv_to_rgb(0.5f, u, v, &r, &g, &b, BLI_YUV_ITU_BT709);
circle_vertex_colors[i * 4] = r;
circle_vertex_colors[i * 4 + 1] = g;
circle_vertex_colors[i * 4 + 2] = b;
circle_vertex_colors[i * 4 + 3] = 0.8f;
}
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_width(2.5f);
circle_draw_rgb(circle_points, tot_points, circle_vertex_colors, GPU_PRIM_LINE_LOOP);
GPU_line_width(1.5f);
/* inner circles */
aras_p marked this conversation as resolved Outdated

Should the inner circles also use circle_draw_rgb machinery, instead of immediate mode?

Should the inner circles also use `circle_draw_rgb` machinery, instead of immediate mode?

Yes we can do that, updated it in the latest commit!

Yes we can do that, updated it in the latest commit!
GPU_blend(GPU_BLEND_ADDITIVE);
for (int j = 0; j < 4; j++) {
float inner_circle_points[(tot_points * 2) + 3] = {};
float inner_circle_colors[(tot_points * 4) + 5] = {};
const float r = (j + 1) * 0.1f;
for (int i = 0; i < tot_points; i++) {
float angle = step * i;
const float a = DEG2RADF(angle);
inner_circle_points[i * 2] = polar_to_x(centerx, diam, r, a);
inner_circle_points[i * 2 + 1] = polar_to_y(centery, diam, r, a);
inner_circle_colors[i * 4] = 0.1f;
inner_circle_colors[i * 4 + 1] = 0.1f;
inner_circle_colors[i * 4 + 2] = 0.1f;
inner_circle_colors[i * 4 + 3] = 0.8f;
}
circle_draw_rgb(inner_circle_points, tot_points, inner_circle_colors, GPU_PRIM_LINE_LOOP);
}
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
/* draw grid elements */
/* cross */
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.1f);
immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery);
@ -1027,19 +1134,9 @@ void ui_draw_but_VECTORSCOPE(ARegion * /*region*/,
immEnd();
/* circles */
for (int j = 0; j < 5; j++) {
const int increment = 15;
immBegin(GPU_PRIM_LINE_LOOP, int(360 / increment));
for (int i = 0; i <= 360 - increment; i += increment) {
const float a = DEG2RADF(float(i));
const float r = (j + 1) * 0.1f;
immVertex2f(pos, polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
}
immEnd();
}
/* skin tone line */
immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
GPU_blend(GPU_BLEND_ADDITIVE);
immUniformColor3f(0.25f, 0.25f, 0.25f);
immBegin(GPU_PRIM_LINES, 2);
immVertex2f(
@ -1050,21 +1147,26 @@ void ui_draw_but_VECTORSCOPE(ARegion * /*region*/,
/* saturation points */
for (int i = 0; i < 6; i++) {
vectorscope_draw_target(pos, centerx, centery, diam, colors[i]);
vectorscope_draw_target(pos, centerx, centery, diam, colors[i], color_names[i]);
}
if (scopes->ok && scopes->vecscope != nullptr) {
/* pixel point cloud */
const float col[3] = {alpha, alpha, alpha};
GPU_blend(GPU_BLEND_ADDITIVE);
GPU_point_size(1.0);
GPU_matrix_push();
GPU_matrix_translate_2f(centerx, centery);
GPU_matrix_scale_1f(diam);
waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col);
const float col[3] = {alpha, alpha, alpha};
if (scopes->vecscope_mode == SCOPES_VECSCOPE_RGB) {
GPU_blend(GPU_BLEND_ALPHA);
waveform_draw_rgb(scopes->vecscope, scopes->waveform_tot, scopes->vecscope_rgb);
}
else if (scopes->vecscope_mode == SCOPES_VECSCOPE_LUMA) {
GPU_blend(GPU_BLEND_ADDITIVE);
waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col);
}
GPU_matrix_pop();
}

View File

@ -150,21 +150,22 @@ typedef struct Scopes {
int ok;
int sample_full;
int sample_lines;
float accuracy;
int wavefrm_mode;
int vecscope_mode;
int wavefrm_height;
int vecscope_height;
int waveform_tot;
float accuracy;
float wavefrm_alpha;
float wavefrm_yfac;
int wavefrm_height;
float vecscope_alpha;
int vecscope_height;
float minmax[3][2];
struct Histogram hist;
float *waveform_1;
float *waveform_2;
float *waveform_3;
float *vecscope;
int waveform_tot;
char _pad[4];
float *vecscope_rgb;
} Scopes;
JonasDichelle marked this conversation as resolved Outdated

Is the _pad needed at all now?

Is the `_pad` needed at all now?

good catch thanks!

good catch thanks!
/** #Scopes.wavefrm_mode */
@ -177,6 +178,12 @@ enum {
SCOPES_WAVEFRM_RGB = 5,
};
/** #Scopes.vecscope_mode */
enum {
SCOPES_VECSCOPE_RGB = 0,
SCOPES_VECSCOPE_LUMA = 1,
};
typedef struct ColorManagedViewSettings {
int flag;
char _pad[4];

View File

@ -1144,6 +1144,12 @@ static void rna_def_scopes(BlenderRNA *brna)
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem prop_vecscope_mode_items[] = {
{SCOPES_VECSCOPE_LUMA, "LUMA", ICON_COLOR, "Luma", ""},
{SCOPES_VECSCOPE_RGB, "RGB", ICON_COLOR, "Red Green Blue", ""},
{0, nullptr, 0, nullptr, nullptr},
aras_p marked this conversation as resolved Outdated

"Red Green Blue" as a UI label feels a bit weird (and hardly fits into UI control space). Maybe "RGB" or "Color" instead?

"Red Green Blue" as a UI label feels a bit weird (and hardly fits into UI control space). Maybe "RGB" or "Color" instead?

I had the same issue with this but looking at all other scopes they use Red Green Blue. This patch is just following what's already there.

Once this gets in we can do a pass and rename that for all scopes. I'd also like to make a few changes in that UI later for all scopes (the opacity slider after the type selector, leave just "opacity" in the label so it's less verbose, remove icon from enum, etc).

I had the same issue with this but looking at all other scopes they use `Red Green Blue`. This patch is just following what's already there. Once this gets in we can do a pass and rename that for all scopes. I'd also like to make a few changes in that UI later for all scopes (the opacity slider after the type selector, leave just "opacity" in the label so it's less verbose, remove icon from enum, etc).

I agree RGB would be better.
I just copied the label from the Waveform which has "Red Green Blue".
But I'm also in favor of changing this.

I agree RGB would be better. I just copied the label from the Waveform which has "Red Green Blue". But I'm also in favor of changing this.
};
srna = RNA_def_struct(brna, "Scopes", nullptr);
RNA_def_struct_ui_text(srna, "Scopes", "Scopes for statistical view of an image");
@ -1176,10 +1182,17 @@ static void rna_def_scopes(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Waveform Opacity", "Opacity of the points");
prop = RNA_def_property(srna, "vectorscope_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, "Scopes", "vecscope_mode");
RNA_def_property_enum_items(prop, prop_vecscope_mode_items);
RNA_def_property_ui_text(prop, "Vectorscope Mode", "");
RNA_def_property_update(prop, 0, "rna_Scopes_update");
prop = RNA_def_property(srna, "vectorscope_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, "Scopes", "vecscope_alpha");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Vectorscope Opacity", "Opacity of the points");
RNA_def_property_update(prop, 0, "rna_Scopes_update");
}
static void rna_def_colormanage(BlenderRNA *brna)