Cycles: new Microfacet-based Hair BSDF with elliptical cross-section support #105600

Merged
Weizhen Huang merged 114 commits from weizhen/blender:microfacet_hair into main 2023-08-18 12:46:20 +02:00
13 changed files with 199 additions and 70 deletions
Showing only changes of commit c78f23f71b - Show all commits

View File

@ -2832,7 +2832,9 @@ class VIEW3D_MT_object_parent(Menu):
layout.separator()
layout.operator_context = 'EXEC_REGION_WIN'
layout.operator("object.parent_no_inverse_set")
layout.operator("object.parent_no_inverse_set").keep_transform = False
props = layout.operator("object.parent_no_inverse_set", text="Make Parent without Inverse (Keep Transform)")
props.keep_transform = True
layout.operator_context = operator_context_default
layout.separator()
@ -6376,6 +6378,9 @@ class VIEW3D_PT_overlay_object(Panel):
sub = split.column(align=True)
sub.prop(overlay, "show_extras", text="Extras")
subsub = sub.column()
subsub.active = overlay.show_extras
subsub.prop(overlay, "show_light_colors")
sub.prop(overlay, "show_relationship_lines")
sub.prop(overlay, "show_outline_selected")

View File

@ -16,27 +16,27 @@
namespace blender {
template<typename T> class ListBaseWrapper {
template<typename LB, typename T> class ListBaseWrapperTemplate {
private:
ListBase *listbase_;
LB *listbase_;
public:
ListBaseWrapper(ListBase *listbase) : listbase_(listbase)
ListBaseWrapperTemplate(LB *listbase) : listbase_(listbase)
{
BLI_assert(listbase);
}
ListBaseWrapper(ListBase &listbase) : ListBaseWrapper(&listbase)
ListBaseWrapperTemplate(LB &listbase) : ListBaseWrapperTemplate(&listbase)
{
}
class Iterator {
private:
ListBase *listbase_;
LB *listbase_;
T *current_;
public:
Iterator(ListBase *listbase, T *current) : listbase_(listbase), current_(current)
Iterator(LB *listbase, T *current) : listbase_(listbase), current_(current)
{
}
@ -96,4 +96,7 @@ template<typename T> class ListBaseWrapper {
}
};
template<typename T> using ListBaseWrapper = ListBaseWrapperTemplate<ListBase, T>;
template<typename T> using ConstListBaseWrapper = ListBaseWrapperTemplate<const ListBase, const T>;
} /* namespace blender */

View File

@ -233,7 +233,7 @@ void MotionBlurModule::render(View &view, GPUTexture **input_tx, GPUTexture **ou
tiles_tx_.acquire(tiles_extent, GPU_RGBA16F);
GPU_storagebuf_clear_to_zero(tile_indirection_buf_);
tile_indirection_buf_.clear_to_zero();
inst_.manager->submit(motion_blur_ps_, view);

View File

@ -18,6 +18,7 @@
#include "DRW_render.h"
#include "BLI_listbase_wrapper.hh"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@ -46,6 +47,8 @@
#define PT_DEFAULT_RAD 0.05f /* radius of the point batch. */
using namespace blender;
struct ArmatureDrawContext {
/* Current armature object */
Object *ob;
@ -2355,7 +2358,7 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
const Object *obact_orig = DEG_get_original_object(draw_ctx->obact);
const ListBase *defbase = BKE_object_defgroup_list(obact_orig);
LISTBASE_FOREACH (const bDeformGroup *, dg, defbase) {
for (const bDeformGroup *dg : ConstListBaseWrapper<bDeformGroup>(defbase)) {
if (dg->flag & DG_LOCK_WEIGHT) {
pchan = BKE_pose_channel_find_name(ob->pose, dg->name);

View File

@ -123,6 +123,9 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
cb->field_tube_limit = BUF_INSTANCE(grp_sub, format, DRW_cache_field_tube_limit_get());
cb->field_vortex = BUF_INSTANCE(grp_sub, format, DRW_cache_field_vortex_get());
cb->field_wind = BUF_INSTANCE(grp_sub, format, DRW_cache_field_wind_get());
cb->light_icon_inner = BUF_INSTANCE(grp_sub, format, DRW_cache_light_icon_inner_lines_get());
cb->light_icon_outer = BUF_INSTANCE(grp_sub, format, DRW_cache_light_icon_outer_lines_get());
cb->light_icon_sun_rays = BUF_INSTANCE(grp_sub, format, DRW_cache_light_icon_sun_rays_get());
cb->light_area[0] = BUF_INSTANCE(grp_sub, format, DRW_cache_light_area_disk_lines_get());
cb->light_area[1] = BUF_INSTANCE(grp_sub, format, DRW_cache_light_area_square_lines_get());
cb->light_point = BUF_INSTANCE(grp_sub, format, DRW_cache_light_point_lines_get());
@ -605,8 +608,9 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
Light *la = static_cast<Light *>(ob->data);
float *color_p;
DRW_object_wire_theme_get(ob, view_layer, &color_p);
/* Remove the alpha. */
float color[4] = {UNPACK3(color_p), 1.0f};
float theme_color[4] = {UNPACK3(color_p), 1.0f};
/* Pack render data into object matrix. */
union {
float mat[4][4];
@ -636,12 +640,25 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
DRW_buffer_add_entry(cb->groundline, instdata.pos);
float light_color[4] = {1.0f};
const bool show_light_colors = vedata->stl->pd->overlay.flag & V3D_OVERLAY_SHOW_LIGHT_COLORS;
if (show_light_colors) {
copy_v3_v3(light_color, &la->r);
}
/* Draw the outer ring of the light icon and the sun rays in `light_color`, if required. */
DRW_buffer_add_entry(
cb->light_icon_outer, show_light_colors ? light_color : theme_color, &instdata);
DRW_buffer_add_entry(cb->light_icon_inner, theme_color, &instdata);
if (la->type == LA_LOCAL) {
instdata.area_size_x = instdata.area_size_y = la->radius;
DRW_buffer_add_entry(cb->light_point, color, &instdata);
DRW_buffer_add_entry(cb->light_point, theme_color, &instdata);
}
else if (la->type == LA_SUN) {
DRW_buffer_add_entry(cb->light_sun, color, &instdata);
DRW_buffer_add_entry(cb->light_sun, theme_color, &instdata);
DRW_buffer_add_entry(
cb->light_icon_sun_rays, show_light_colors ? light_color : theme_color, &instdata);
}
else if (la->type == LA_SPOT) {
/* Previous implementation was using the clip-end distance as cone size.
@ -664,8 +681,8 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
instdata.spot_blend = sqrtf((a2 - a2 * c2) / (c2 - a2 * c2));
instdata.spot_cosine = a;
/* HACK: We pack the area size in alpha color. This is decoded by the shader. */
color[3] = -max_ff(la->radius, FLT_MIN);
DRW_buffer_add_entry(cb->light_spot, color, &instdata);
theme_color[3] = -max_ff(la->radius, FLT_MIN);
DRW_buffer_add_entry(cb->light_spot, theme_color, &instdata);
if ((la->mode & LA_SHOW_CONE) && !DRW_state_is_select()) {
const float color_inside[4] = {0.0f, 0.0f, 0.0f, 0.5f};
@ -679,7 +696,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
int sqr = ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_RECT);
instdata.area_size_x = la->area_size;
instdata.area_size_y = uniform_scale ? la->area_size : la->area_sizey;
DRW_buffer_add_entry(cb->light_area[sqr], color, &instdata);
DRW_buffer_add_entry(cb->light_area[sqr], theme_color, &instdata);
}
}

View File

@ -178,6 +178,9 @@ typedef struct OVERLAY_ExtraCallBuffers {
DRWCallBuffer *groundline;
DRWCallBuffer *light_icon_inner;
DRWCallBuffer *light_icon_outer;
DRWCallBuffer *light_icon_sun_rays;
DRWCallBuffer *light_point;
DRWCallBuffer *light_sun;
DRWCallBuffer *light_spot;

View File

@ -116,6 +116,9 @@ static struct DRWShapeCache {
GPUBatch *drw_field_cone_limit;
GPUBatch *drw_field_sphere_limit;
GPUBatch *drw_ground_line;
GPUBatch *drw_light_icon_inner_lines;
GPUBatch *drw_light_icon_outer_lines;
GPUBatch *drw_light_icon_sun_rays;
GPUBatch *drw_light_point_lines;
GPUBatch *drw_light_sun_lines;
GPUBatch *drw_light_spot_lines;
@ -1461,21 +1464,90 @@ GPUBatch *DRW_cache_groundline_get(void)
return SHC.drw_ground_line;
}
GPUBatch *DRW_cache_light_point_lines_get(void)
GPUBatch *DRW_cache_light_icon_inner_lines_get(void)
{
if (!SHC.drw_light_point_lines) {
if (!SHC.drw_light_icon_inner_lines) {
GPUVertFormat format = extra_vert_format();
int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS + OUTER_NSEGMENTS + CIRCLE_NSEGMENTS);
int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS);
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, v_len);
const float r = 9.0f;
int v = 0;
/* Light Icon */
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
SHC.drw_light_icon_inner_lines = GPU_batch_create_ex(
GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
return SHC.drw_light_icon_inner_lines;
}
GPUBatch *DRW_cache_light_icon_outer_lines_get(void)
{
if (!SHC.drw_light_icon_outer_lines) {
GPUVertFormat format = extra_vert_format();
int v_len = 2 * OUTER_NSEGMENTS;
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, v_len);
const float r = 9.0f;
int v = 0;
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
SHC.drw_light_icon_outer_lines = GPU_batch_create_ex(
GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
return SHC.drw_light_icon_outer_lines;
}
GPUBatch *DRW_cache_light_icon_sun_rays_get(void)
{
if (!SHC.drw_light_icon_sun_rays) {
GPUVertFormat format = extra_vert_format();
const int num_rays = 8;
int v_len = 4 * num_rays;
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, v_len);
const float r = 9.0f;
int v = 0;
/* Sun Rays */
for (int a = 0; a < num_rays; a++) {
float angle = (2.0f * M_PI * a) / (float)num_rays;
float s = sinf(angle) * r;
float c = cosf(angle) * r;
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.6f, c * 1.6f, 0.0f}, VCLASS_SCREENSPACE});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.9f, c * 1.9f, 0.0f}, VCLASS_SCREENSPACE});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.2f, c * 2.2f, 0.0f}, VCLASS_SCREENSPACE});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.5f, c * 2.5f, 0.0f}, VCLASS_SCREENSPACE});
}
SHC.drw_light_icon_sun_rays = GPU_batch_create_ex(
GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
return SHC.drw_light_icon_sun_rays;
}
GPUBatch *DRW_cache_light_point_lines_get(void)
{
if (!SHC.drw_light_point_lines) {
GPUVertFormat format = extra_vert_format();
int v_len = 2 * CIRCLE_NSEGMENTS;
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, v_len);
int v = 0;
/* Light area */
int flag = VCLASS_SCREENALIGNED | VCLASS_LIGHT_AREA_SHAPE;
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
@ -1490,26 +1562,12 @@ GPUBatch *DRW_cache_light_sun_lines_get(void)
if (!SHC.drw_light_sun_lines) {
GPUVertFormat format = extra_vert_format();
int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS + OUTER_NSEGMENTS + 8 * 2 + 1);
int v_len = 2;
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, v_len);
const float r = 9.0f;
int v = 0;
/* Light Icon */
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
/* Sun Rays */
for (int a = 0; a < 8; a++) {
float angle = (2.0f * M_PI * a) / 8.0f;
float s = sinf(angle) * r;
float c = cosf(angle) * r;
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.6f, c * 1.6f, 0.0f}, VCLASS_SCREENSPACE});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.9f, c * 1.9f, 0.0f}, VCLASS_SCREENSPACE});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.2f, c * 2.2f, 0.0f}, VCLASS_SCREENSPACE});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.5f, c * 2.5f, 0.0f}, VCLASS_SCREENSPACE});
}
/* Direction Line */
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0, 0.0, 0.0}, 0});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0, 0.0, -20.0}, 0}); /* Good default. */
@ -1524,17 +1582,12 @@ GPUBatch *DRW_cache_light_spot_lines_get(void)
if (!SHC.drw_light_spot_lines) {
GPUVertFormat format = extra_vert_format();
int v_len = 2 * (DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS +
CIRCLE_NSEGMENTS * 4 + 1);
int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + CIRCLE_NSEGMENTS * 4 + 1);
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, v_len);
const float r = 9.0f;
int v = 0;
/* Light Icon */
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
/* Light area */
int flag = VCLASS_SCREENALIGNED | VCLASS_LIGHT_AREA_SHAPE;
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
@ -1597,17 +1650,12 @@ GPUBatch *DRW_cache_light_area_disk_lines_get(void)
if (!SHC.drw_light_area_disk_lines) {
GPUVertFormat format = extra_vert_format();
int v_len = 2 *
(DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS + CIRCLE_NSEGMENTS + 1);
int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + CIRCLE_NSEGMENTS + 1);
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, v_len);
const float r = 9.0f;
int v = 0;
/* Light Icon */
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
/* Light area */
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 0.5f, 0.0f, VCLASS_LIGHT_AREA_SHAPE);
/* Direction Line */
@ -1630,15 +1678,11 @@ GPUBatch *DRW_cache_light_area_square_lines_get(void)
GPUVertFormat format = extra_vert_format();
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
int v_len = 2 * (DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS + 4 + 1);
int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + 4 + 1);
GPU_vertbuf_data_alloc(vbo, v_len);
const float r = 9.0f;
int v = 0;
/* Light Icon */
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
/* Light area */
int flag = VCLASS_LIGHT_AREA_SHAPE;
for (int a = 0; a < 4; a++) {

View File

@ -106,6 +106,9 @@ struct GPUBatch *DRW_cache_field_sphere_limit_get(void);
/* Lights */
struct GPUBatch *DRW_cache_light_icon_inner_lines_get(void);
struct GPUBatch *DRW_cache_light_icon_outer_lines_get(void);
struct GPUBatch *DRW_cache_light_icon_sun_rays_get(void);
struct GPUBatch *DRW_cache_light_point_lines_get(void);
struct GPUBatch *DRW_cache_light_sun_lines_get(void);
struct GPUBatch *DRW_cache_light_spot_lines_get(void);

View File

@ -580,12 +580,19 @@ static void cage2d_draw_circle_wire(const float color[3],
immUnbindProgram();
}
static void cage2d_draw_rect_handles(const rctf *r,
const float margin[2],
const float color[3],
const int transform_flag,
bool solid)
static void cage2d_draw_rect_corner_handles(const rctf *r,
const int highlighted,
const float margin[2],
const float color[3],
const int transform_flag,
bool solid)
{
/* Only draw corner handles when hovering over the corners. */
if (highlighted < ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y ||
highlighted > ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y) {
return;
}
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
void (*circle_fn)(uint, float, float, float, float, int) = (solid) ?
imm_draw_circle_fill_aspect_2d :
@ -615,6 +622,38 @@ static void cage2d_draw_rect_handles(const rctf *r,
immUnbindProgram();
}
static void cage2d_draw_rect_edge_handles(const rctf *r,
const int highlighted,
const float size[2],
const float margin[2],
const float color[3],
bool solid)
{
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor3fv(color);
switch (highlighted) {
case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X:
case ED_GIZMO_CAGE2D_PART_SCALE_MAX_X: {
const float rad[2] = {0.2f * margin[0], 0.4f * size[1]};
imm_draw_point_aspect_2d(pos, r->xmin, 0.f, rad[0], rad[1], solid);
imm_draw_point_aspect_2d(pos, r->xmax, 0.f, rad[0], rad[1], solid);
break;
}
case ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y:
case ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y: {
const float rad[2] = {0.4f * size[0], 0.2f * margin[1]};
imm_draw_point_aspect_2d(pos, 0.f, r->ymin, rad[0], rad[1], solid);
imm_draw_point_aspect_2d(pos, 0.f, r->ymax, rad[0], rad[1], solid);
break;
}
}
immUnbindProgram();
}
/** \} */
static void gizmo_cage2d_draw_intern(wmGizmo *gz,
@ -665,15 +704,15 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
else {
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE) {
int scale_parts[] = {
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X,
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X,
ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y,
ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y,
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y,
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y,
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y,
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y,
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X,
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X,
ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y,
ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y,
};
for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) {
GPU_select_load_id(select_id | scale_parts[i]);
@ -754,9 +793,15 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
cage2d_draw_rect_wire(&r, margin, black, transform_flag, draw_options, outline_line_width);
cage2d_draw_rect_wire(&r, margin, color, transform_flag, draw_options, gz->line_width);
/* Corner gizmos. */
cage2d_draw_rect_handles(&r, margin, black, transform_flag, false);
cage2d_draw_rect_handles(&r, margin, color, transform_flag, true);
/* Edge handles. */
cage2d_draw_rect_edge_handles(&r, gz->highlight_part, size_real, margin, color, true);
cage2d_draw_rect_edge_handles(&r, gz->highlight_part, size_real, margin, black, false);
/* Corner handles. */
cage2d_draw_rect_corner_handles(
&r, gz->highlight_part, margin, color, transform_flag, true);
cage2d_draw_rect_corner_handles(
&r, gz->highlight_part, margin, black, transform_flag, false);
}
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
cage2d_draw_circle_wire(black, size_real, margin, outline_line_width);

View File

@ -252,6 +252,7 @@ void ED_gpencil_trace_data_to_strokes(Main *bmain,
float start_point[2], last[2];
start_point[0] = c[n - 1][2].x;
start_point[1] = c[n - 1][2].y;
zero_v2(last);
for (int32_t i = 0; i < n; i++) {
switch (tag[i]) {

View File

@ -170,7 +170,6 @@ static void createTransTrackingCurvesData(bContext *C, TransInfo *t)
static void createTransTrackingCurves(bContext *C, TransInfo *t)
{
ARegion *region = CTX_wm_region(C);
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
int width, height;
@ -190,7 +189,7 @@ static void createTransTrackingCurves(bContext *C, TransInfo *t)
}
/* transformation was called from graph editor */
BLI_assert(region->regiontype == RGN_TYPE_PREVIEW);
BLI_assert(CTX_wm_region(C)->regiontype == RGN_TYPE_PREVIEW);
createTransTrackingCurvesData(C, t);
}

View File

@ -552,6 +552,7 @@ enum {
V3D_OVERLAY_SCULPT_SHOW_MASK = (1 << 14),
V3D_OVERLAY_SCULPT_SHOW_FACE_SETS = (1 << 15),
V3D_OVERLAY_SCULPT_CURVES_CAGE = (1 << 16),
V3D_OVERLAY_SHOW_LIGHT_COLORS = (1 << 17),
};
/** #View3DOverlay.edit_flag */

View File

@ -4407,6 +4407,11 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
prop, "Extras", "Object details, including empty wire, cameras and other visual guides");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "show_light_colors", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_SHOW_LIGHT_COLORS);
RNA_def_property_ui_text(prop, "Light Colors", "Show light colors");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "show_bones", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_HIDE_BONES);
RNA_def_property_ui_text(