Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2021-04-28 21:55:09 +02:00
commit ce0b4e6681
44 changed files with 541 additions and 275 deletions

View File

@ -1088,6 +1088,8 @@ static int generate_file(AreaOrtho *ortho, AreaDiag *diag, const char *path, boo
return 1;
}
// fprintf(stderr, "Generating %s\n", path);
if (tga)
write_tga(ortho, diag, fp, subsampling);
else if (raw)

View File

@ -94,13 +94,11 @@ class ExportHelper:
if check_extension is not None:
filepath = self.filepath
if os.path.basename(filepath):
filepath = bpy.path.ensure_ext(
filepath,
self.filename_ext
if check_extension
else "",
)
if check_extension:
filepath = bpy.path.ensure_ext(
os.path.splitext(filepath)[0],
self.filename_ext,
)
if filepath != self.filepath:
self.filepath = filepath
change_ext = True

View File

@ -178,6 +178,7 @@ void BKE_armature_where_is_bone(struct Bone *bone,
void BKE_pose_clear_pointers(struct bPose *pose);
void BKE_pose_remap_bone_pointers(struct bArmature *armature, struct bPose *pose);
void BKE_pchan_rebuild_bbone_handles(struct bPose *pose, struct bPoseChannel *pchan);
void BKE_pose_channels_clear_with_null_bone(struct bPose *pose, const bool do_id_user);
void BKE_pose_rebuild(struct Main *bmain,
struct Object *ob,
struct bArmature *arm,

View File

@ -1603,6 +1603,12 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
/* This geometry set contains the non-mesh data that might be generated by modifiers. */
GeometrySet geometry_set_final;
/* Add the initial mesh component, with a copy of the vertex group names from the object,
* since they need to be stored in the geometry set for evaluation. */
MeshComponent &initial_mesh_component =
geometry_set_final.get_component_for_write<MeshComponent>();
initial_mesh_component.copy_vertex_group_names_from_object(*ob);
/* Deformed vertex locations array. Deform only modifier need this type of
* float array rather than MVert*. Tracked along with mesh_final as an
* optimization to avoid copying coordinates back and forth if there are

View File

@ -2515,6 +2515,17 @@ void BKE_pchan_rebuild_bbone_handles(bPose *pose, bPoseChannel *pchan)
pchan->bbone_next = pose_channel_find_bone(pose, pchan->bone->bbone_next);
}
void BKE_pose_channels_clear_with_null_bone(bPose *pose, const bool do_id_user)
{
LISTBASE_FOREACH_MUTABLE (bPoseChannel *, pchan, &pose->chanbase) {
if (pchan->bone == NULL) {
BKE_pose_channel_free_ex(pchan, do_id_user);
BKE_pose_channels_hash_free(pose);
BLI_freelinkN(&pose->chanbase, pchan);
}
}
}
/**
* Only after leave editmode, duplicating, validating older files, library syncing.
*
@ -2526,7 +2537,7 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
{
Bone *bone;
bPose *pose;
bPoseChannel *pchan, *next;
bPoseChannel *pchan;
int counter = 0;
/* only done here */
@ -2549,14 +2560,7 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
}
/* and a check for garbage */
for (pchan = pose->chanbase.first; pchan; pchan = next) {
next = pchan->next;
if (pchan->bone == NULL) {
BKE_pose_channel_free_ex(pchan, do_id_user);
BKE_pose_channels_hash_free(pose);
BLI_freelinkN(&pose->chanbase, pchan);
}
}
BKE_pose_channels_clear_with_null_bone(pose, do_id_user);
BKE_pose_channels_hash_make(pose);

View File

@ -1050,8 +1050,21 @@ void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
normalize_v3(locx);
normalize_v3(locy);
/* Calculcate last point first. */
const bGPDspoint *pt_last = &points[totpoints - 1];
float tmp[3];
sub_v3_v3v3(tmp, &pt_last->x, &pt0->x);
points2d[totpoints - 1][0] = dot_v3v3(tmp, locx);
points2d[totpoints - 1][1] = dot_v3v3(tmp, locy);
/* Calculate the scalar cross product of the 2d points. */
float cross = 0.0f;
float *co_curr;
float *co_prev = (float *)&points2d[totpoints - 1];
/* Get all points in local space */
for (int i = 0; i < totpoints; i++) {
for (int i = 0; i < totpoints - 1; i++) {
const bGPDspoint *pt = &points[i];
float loc[3];
@ -1060,10 +1073,15 @@ void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
points2d[i][0] = dot_v3v3(loc, locx);
points2d[i][1] = dot_v3v3(loc, locy);
/* Calculate cross product. */
co_curr = (float *)&points2d[i][0];
cross += (co_curr[0] - co_prev[0]) * (co_curr[1] + co_prev[1]);
co_prev = (float *)&points2d[i][0];
}
/* Concave (-1), Convex (1), or Auto-detect (0)? */
*r_direction = (int)locy[2];
/* Concave (-1), Convex (1) */
*r_direction = (cross >= 0.0f) ? 1 : -1;
}
/**

View File

@ -187,10 +187,10 @@ int BB_widest_axis(const BB *bb);
void pbvh_grow_nodes(PBVH *bvh, int totnode);
bool ray_face_intersection_quad(const float ray_start[3],
struct IsectRayPrecalc *isect_precalc,
const float *t0,
const float *t1,
const float *t2,
const float *t3,
const float t0[3],
const float t1[3],
const float t2[3],
const float t3[3],
float *depth);
bool ray_face_intersection_tri(const float ray_start[3],
struct IsectRayPrecalc *isect_precalc,
@ -201,17 +201,17 @@ bool ray_face_intersection_tri(const float ray_start[3],
bool ray_face_nearest_quad(const float ray_start[3],
const float ray_normal[3],
const float *t0,
const float *t1,
const float *t2,
const float *t3,
const float t0[3],
const float t1[3],
const float t2[3],
const float t3[3],
float *r_depth,
float *r_dist_sq);
bool ray_face_nearest_tri(const float ray_start[3],
const float ray_normal[3],
const float *t0,
const float *t1,
const float *t2,
const float t0[3],
const float t1[3],
const float t2[3],
float *r_depth,
float *r_dist_sq);

View File

@ -105,8 +105,8 @@ int constrain_rgb(float *r, float *g, float *b);
void minmax_rgb(short c[3]);
void hsv_clamp_v(float hsv[3], float v_max);
void rgb_float_set_hue_float_offset(float *rgb, float hue_offset);
void rgb_byte_set_hue_float_offset(unsigned char *rgb, float hue_offset);
void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset);
void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset);
void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3]);
void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4]);

View File

@ -778,7 +778,7 @@ MINLINE float dot_shsh(const float a[9], const float b[9]);
MINLINE float eval_shv3(float r[9], const float v[3]);
MINLINE float diffuse_shv3(float r[9], const float v[3]);
MINLINE void vec_fac_to_sh(float r[9], const float v[3], const float f);
MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f);
MINLINE void madd_sh_shfl(float r[9], const float sh[9], const float f);
/********************************* Form Factor *******************************/

View File

@ -362,7 +362,7 @@ void loc_quat_size_to_mat4(float R[4][4],
const float size[3]);
void loc_axisangle_size_to_mat4(float R[4][4],
const float loc[3],
const float axis[4],
const float axis[3],
const float angle,
const float size[3]);

View File

@ -146,7 +146,7 @@ MINLINE void mul_v3_v3(float r[3], const float a[3]);
MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void mul_v4_fl(float r[4], float f);
MINLINE void mul_v4_v4(float r[4], const float a[4]);
MINLINE void mul_v4_v4fl(float r[3], const float a[4], float f);
MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f);
MINLINE void mul_v2_v2_cw(float r[2], const float mat[2], const float vec[2]);
MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2]);
MINLINE float mul_project_m4_v3_zfac(const float mat[4][4],
@ -177,7 +177,7 @@ MINLINE void negate_v2_v2(float r[2], const float a[2]);
MINLINE void negate_v3(float r[3]);
MINLINE void negate_v3_v3(float r[3], const float a[3]);
MINLINE void negate_v4(float r[4]);
MINLINE void negate_v4_v4(float r[4], const float a[3]);
MINLINE void negate_v4_v4(float r[4], const float a[4]);
MINLINE void negate_v3_short(short r[3]);
MINLINE void negate_v3_db(double r[3]);
@ -323,11 +323,11 @@ void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2]);
/********************************* Comparison ********************************/
MINLINE bool is_zero_v2(const float a[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE bool is_zero_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE bool is_zero_v4(const float a[4]) ATTR_WARN_UNUSED_RESULT;
bool is_finite_v2(const float a[3]) ATTR_WARN_UNUSED_RESULT;
bool is_finite_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT;
bool is_finite_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT;
bool is_finite_v4(const float a[4]) ATTR_WARN_UNUSED_RESULT;

View File

@ -740,11 +740,12 @@ class Vector {
BLI_assert(index >= 0);
BLI_assert(index < this->size());
T *element_to_remove = begin_ + index;
if (element_to_remove < end_) {
*element_to_remove = std::move(*(end_ - 1));
T *last_element = end_ - 1;
if (element_to_remove < last_element) {
*element_to_remove = std::move(*last_element);
}
end_--;
end_->~T();
end_ = last_element;
last_element->~T();
UPDATE_VECTOR_SIZE(this);
}

View File

@ -134,7 +134,7 @@ void BLI_uvproject_from_view(float target[2],
/* 'rotmat' can be `obedit->obmat` when uv project is used.
* 'winx' and 'winy' can be from `scene->r.xsch/ysch` */
ProjCameraInfo *BLI_uvproject_camera_info(Object *ob, float (*rotmat)[4], float winx, float winy)
ProjCameraInfo *BLI_uvproject_camera_info(Object *ob, float rotmat[4][4], float winx, float winy)
{
ProjCameraInfo uci;
Camera *camera = ob->data;

View File

@ -55,7 +55,6 @@ constexpr int COM_DATA_TYPE_COLOR_CHANNELS = COM_data_type_num_channels(DataType
// configurable items
// chunk size determination
// #define COM_DEBUG
// chunk order
/**

View File

@ -42,8 +42,6 @@ extern "C" {
namespace blender::compositor {
#ifdef COM_DEBUG
int DebugInfo::m_file_index = 0;
DebugInfo::NodeNameMap DebugInfo::m_node_names;
DebugInfo::OpNameMap DebugInfo::m_op_names;
@ -69,50 +67,6 @@ std::string DebugInfo::operation_name(const NodeOperation *op)
return "";
}
void DebugInfo::convert_started()
{
m_op_names.clear();
}
void DebugInfo::execute_started(const ExecutionSystem *system)
{
m_file_index = 1;
m_group_states.clear();
for (ExecutionGroup *execution_group : system->m_groups) {
m_group_states[execution_group] = EG_WAIT;
}
}
void DebugInfo::node_added(const Node *node)
{
m_node_names[node] = std::string(node->getbNode() ? node->getbNode()->name : "");
}
void DebugInfo::node_to_operations(const Node *node)
{
m_current_node_name = m_node_names[node];
}
void DebugInfo::operation_added(const NodeOperation *operation)
{
m_op_names[operation] = m_current_node_name;
}
void DebugInfo::operation_read_write_buffer(const NodeOperation *operation)
{
m_current_op_name = m_op_names[operation];
}
void DebugInfo::execution_group_started(const ExecutionGroup *group)
{
m_group_states[group] = EG_RUNNING;
}
void DebugInfo::execution_group_finished(const ExecutionGroup *group)
{
m_group_states[group] = EG_FINISHED;
}
int DebugInfo::graphviz_operation(const ExecutionSystem *system,
NodeOperation *operation,
const ExecutionGroup *group,
@ -442,6 +396,9 @@ bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int ma
void DebugInfo::graphviz(const ExecutionSystem *system)
{
if (!COM_EXPORT_GRAPHVIZ) {
return;
}
char str[1000000];
if (graphviz_system(system, str, sizeof(str) - 1)) {
char basename[FILE_MAX];
@ -459,44 +416,4 @@ void DebugInfo::graphviz(const ExecutionSystem *system)
}
}
#else
std::string DebugInfo::node_name(const Node * /*node*/)
{
return "";
}
std::string DebugInfo::operation_name(const NodeOperation * /*op*/)
{
return "";
}
void DebugInfo::convert_started()
{
}
void DebugInfo::execute_started(const ExecutionSystem * /*system*/)
{
}
void DebugInfo::node_added(const Node * /*node*/)
{
}
void DebugInfo::node_to_operations(const Node * /*node*/)
{
}
void DebugInfo::operation_added(const NodeOperation * /*operation*/)
{
}
void DebugInfo::operation_read_write_buffer(const NodeOperation * /*operation*/)
{
}
void DebugInfo::execution_group_started(const ExecutionGroup * /*group*/)
{
}
void DebugInfo::execution_group_finished(const ExecutionGroup * /*group*/)
{
}
void DebugInfo::graphviz(const ExecutionSystem * /*system*/)
{
}
#endif
} // namespace blender::compositor

View File

@ -21,11 +21,13 @@
#include <map>
#include <string>
#include "COM_ExecutionSystem.h"
#include "COM_NodeOperation.h"
#include "COM_defines.h"
namespace blender::compositor {
static constexpr bool COM_EXPORT_GRAPHVIZ = false;
class Node;
class ExecutionSystem;
class ExecutionGroup;
@ -41,20 +43,81 @@ class DebugInfo {
static std::string node_name(const Node *node);
static std::string operation_name(const NodeOperation *op);
static void convert_started();
static void execute_started(const ExecutionSystem *system);
private:
static int m_file_index;
/** Map nodes to usable names for debug output. */
static NodeNameMap m_node_names;
/** Map operations to usable names for debug output. */
static OpNameMap m_op_names;
/** Base name for all operations added by a node. */
static std::string m_current_node_name;
/** Base name for automatic sub-operations. */
static std::string m_current_op_name;
/** For visualizing group states. */
static GroupStateMap m_group_states;
static void node_added(const Node *node);
static void node_to_operations(const Node *node);
static void operation_added(const NodeOperation *operation);
static void operation_read_write_buffer(const NodeOperation *operation);
public:
static void convert_started()
{
if (COM_EXPORT_GRAPHVIZ) {
m_op_names.clear();
}
}
static void execution_group_started(const ExecutionGroup *group);
static void execution_group_finished(const ExecutionGroup *group);
static void execute_started(const ExecutionSystem *system)
{
if (COM_EXPORT_GRAPHVIZ) {
m_file_index = 1;
m_group_states.clear();
for (ExecutionGroup *execution_group : system->m_groups) {
m_group_states[execution_group] = EG_WAIT;
}
}
};
static void node_added(const Node *node)
{
if (COM_EXPORT_GRAPHVIZ) {
m_node_names[node] = std::string(node->getbNode() ? node->getbNode()->name : "");
}
}
static void node_to_operations(const Node *node)
{
if (COM_EXPORT_GRAPHVIZ) {
m_current_node_name = m_node_names[node];
}
}
static void operation_added(const NodeOperation *operation)
{
if (COM_EXPORT_GRAPHVIZ) {
m_op_names[operation] = m_current_node_name;
}
};
static void operation_read_write_buffer(const NodeOperation *operation)
{
if (COM_EXPORT_GRAPHVIZ) {
m_current_op_name = m_op_names[operation];
}
};
static void execution_group_started(const ExecutionGroup *group)
{
if (COM_EXPORT_GRAPHVIZ) {
m_group_states[group] = EG_RUNNING;
}
};
static void execution_group_finished(const ExecutionGroup *group)
{
if (COM_EXPORT_GRAPHVIZ) {
m_group_states[group] = EG_FINISHED;
}
};
static void graphviz(const ExecutionSystem *system);
#ifdef COM_DEBUG
protected:
static int graphviz_operation(const ExecutionSystem *system,
NodeOperation *operation,
@ -68,20 +131,6 @@ class DebugInfo {
const char *name, const char *color, const char *style, char *str, int maxlen);
static int graphviz_legend(char *str, int maxlen);
static bool graphviz_system(const ExecutionSystem *system, char *str, int maxlen);
private:
static int m_file_index;
/** Map nodes to usable names for debug output. */
static NodeNameMap m_node_names;
/** Map operations to usable names for debug output. */
static OpNameMap m_op_names;
/** Base name for all operations added by a node. */
static std::string m_current_node_name;
/** Base name for automatic sub-operations. */
static std::string m_current_op_name;
/** For visualizing group states. */
static GroupStateMap m_group_states;
#endif
};
} // namespace blender::compositor

View File

@ -397,7 +397,6 @@ static void threading_model_task_execute(TaskPool *__restrict UNUSED(pool), void
CPUDevice device(BLI_task_parallel_thread_id(nullptr));
BLI_thread_local_set(g_thread_device, &device);
device.execute(package);
delete package;
}
static void threading_model_task_schedule(WorkPackage *package)

View File

@ -35,24 +35,28 @@ SequenceBackup::SequenceBackup(const Depsgraph * /*depsgraph*/)
void SequenceBackup::reset()
{
scene_sound = nullptr;
BLI_listbase_clear(&anims);
}
void SequenceBackup::init_from_sequence(Sequence *sequence)
{
scene_sound = sequence->scene_sound;
anims = sequence->anims;
sequence->scene_sound = nullptr;
BLI_listbase_clear(&sequence->anims);
}
void SequenceBackup::restore_to_sequence(Sequence *sequence)
{
sequence->scene_sound = scene_sound;
sequence->anims = anims;
reset();
}
bool SequenceBackup::isEmpty() const
{
return (scene_sound == nullptr);
return (scene_sound == nullptr) && BLI_listbase_is_empty(&anims);
}
} // namespace blender::deg

View File

@ -23,6 +23,8 @@
#pragma once
#include "BLI_listbase.h"
struct Sequence;
namespace blender {
@ -43,6 +45,7 @@ class SequenceBackup {
bool isEmpty() const;
void *scene_sound;
ListBase anims;
};
} // namespace deg

View File

@ -494,12 +494,7 @@ static void eevee_render_to_image(void *vedata,
/* Previous motion step. */
if (do_motion_blur_fx) {
if (i > 0) {
/* The previous step of this iteration N is exactly the next step of iteration N - 1.
* So we just swap the resources to avoid too much re-evaluation. */
EEVEE_motion_blur_swap_data(vedata);
}
else {
if (i == 0) {
EEVEE_motion_blur_step_set(ved, MB_PREV);
DRW_render_set_time(engine, depsgraph, floorf(time_prev), fractf(time_prev));
EEVEE_render_modules_init(vedata, engine, depsgraph);
@ -570,6 +565,14 @@ static void eevee_render_to_image(void *vedata,
DRW_cache_restart();
}
}
if (do_motion_blur_fx) {
/* The previous step of next iteration N is exactly the next step of this iteration N - 1.
* So we just swap the resources to avoid too much re-evaluation.
* Note that this also clears the VBO references from the GPUBatches of deformed
* geometries. */
EEVEE_motion_blur_swap_data(vedata);
}
}
EEVEE_volumes_free_smoke_textures();

View File

@ -162,7 +162,7 @@ void ED_area_tag_redraw_no_rebuild(ScrArea *area);
void ED_area_tag_redraw_regiontype(ScrArea *area, int type);
void ED_area_tag_refresh(ScrArea *area);
void ED_area_do_refresh(struct bContext *C, ScrArea *area);
struct AZone *ED_area_azones_update(ScrArea *area, const int mouse_xy[]);
struct AZone *ED_area_azones_update(ScrArea *area, const int mouse_xy[2]);
void ED_area_status_text(ScrArea *area, const char *str);
void ED_area_newspace(struct bContext *C, ScrArea *area, int type, const bool skip_region_exit);
void ED_area_prevspace(struct bContext *C, ScrArea *area);

View File

@ -2137,7 +2137,7 @@ void uiTemplateComponentMenu(uiLayout *layout,
struct PointerRNA *ptr,
const char *propname,
const char *name);
void uiTemplateNodeSocket(uiLayout *layout, struct bContext *C, float *color);
void uiTemplateNodeSocket(uiLayout *layout, struct bContext *C, float color[4]);
void uiTemplateCacheFile(uiLayout *layout,
const struct bContext *C,
struct PointerRNA *ptr,

View File

@ -451,7 +451,7 @@ int UI_ThemeMenuShadowWidth(void);
/* only for buttons in theme editor! */
const unsigned char *UI_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid);
void UI_make_axis_color(const unsigned char *src_col, unsigned char *dst_col, const char axis);
void UI_make_axis_color(const unsigned char src_col[3], unsigned char dst_col[3], const char axis);
#ifdef __cplusplus
}

View File

@ -677,8 +677,7 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
}
/* The previous menu item draws the active selection. */
ui_draw_menu_item(
&data->fstyle, &rect, name_sep, icon, state & ~UI_ACTIVE, separator_type, NULL);
ui_draw_menu_item(&data->fstyle, &rect, name_sep, icon, state, separator_type, NULL);
}
}
/* indicate more */

View File

@ -7192,7 +7192,7 @@ void uiTemplateComponentMenu(uiLayout *layout,
/** \name Node Socket Icon Template
* \{ */
void uiTemplateNodeSocket(uiLayout *layout, bContext *UNUSED(C), float *color)
void uiTemplateNodeSocket(uiLayout *layout, bContext *UNUSED(C), float color[4])
{
uiBlock *block = uiLayoutGetBlock(layout);
UI_block_align_begin(block);

View File

@ -55,6 +55,7 @@
#include "IMB_imbuf_types.h"
#include "BKE_anim_visualization.h"
#include "BKE_armature.h"
#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
@ -578,6 +579,14 @@ static bool ED_object_editmode_load_free_ex(Main *bmain,
if (free_data) {
ED_armature_edit_free(obedit->data);
if (load_data == false) {
/* Don't keep unused pose channels created by duplicating bones
* which may have been deleted/undone, see: T87631. */
if (obedit->pose != NULL) {
BKE_pose_channels_clear_with_null_bone(obedit->pose, true);
}
}
}
/* TODO(sergey): Pose channels might have been changed, so need
* to inform dependency graph about this. But is it really the

View File

@ -404,6 +404,7 @@ static void spreadsheet_main_region_listener(const wmRegionListenerParams *param
}
break;
}
case NC_TEXTURE:
case NC_GEOM: {
ED_region_tag_redraw(region);
break;

View File

@ -261,7 +261,7 @@ void InstancesDataSource::foreach_default_column_ids(
SpreadsheetColumnID column_id;
column_id.name = (char *)"Name";
fn(column_id);
for (const char *name : {"Position", "Rotation", "Scale"}) {
for (const char *name : {"Position", "Rotation", "Scale", "ID"}) {
column_id.name = (char *)name;
fn(column_id);
}
@ -322,6 +322,15 @@ std::unique_ptr<ColumnValues> InstancesDataSource::get_column_values(
},
default_float3_column_width);
}
Span<int> ids = component_->ids();
if (STREQ(column_id.name, "ID")) {
/* Make the column a bit wider by default, since the IDs tend to be large numbers. */
return column_values_from_function(
column_id.name,
size,
[ids](int index, CellValue &r_cell_value) { r_cell_value.value_int = ids[index]; },
5.5f);
}
return {};
}

View File

@ -2507,7 +2507,7 @@ static void view_dolly_to_vector_3d(ARegion *region,
madd_v3_v3v3fl(rv3d->ofs, orig_ofs, dvec, -(1.0f - dfac));
}
static void viewdolly_apply(ViewOpsData *vod, const int xy[2], const short zoom_invert)
static void viewdolly_apply(ViewOpsData *vod, const int xy[2], const bool zoom_invert)
{
float zfac = 1.0;

View File

@ -74,7 +74,7 @@
static void drawTransformApply(const struct bContext *C, ARegion *region, void *arg);
static void initSnapSpatial(TransInfo *t, float r_snap[3]);
static void initSnapSpatial(TransInfo *t, float r_snap[2]);
bool transdata_check_local_islands(TransInfo *t, short around)
{

View File

@ -78,14 +78,12 @@ static short get_bezt_sel_triple_flag(BezTriple *bezt, const bool handles_visibl
flag = ((bezt->f1 & SELECT) ? SEL_F1 : 0) | ((bezt->f2 & SELECT) ? SEL_F2 : 0) |
((bezt->f3 & SELECT) ? SEL_F3 : 0);
}
else {
if (bezt->f2 & SELECT) {
flag = SEL_ALL;
}
else if (bezt->f2 & SELECT) {
flag = SEL_ALL;
}
/* Special case for auto & aligned handles */
if (flag != SEL_ALL && flag & SEL_F2) {
if ((flag != SEL_ALL) && (flag & SEL_F2)) {
if (ELEM(bezt->h1, HD_AUTO, HD_ALIGN) && ELEM(bezt->h2, HD_AUTO, HD_ALIGN)) {
flag = SEL_ALL;
}
@ -316,7 +314,7 @@ static void createTransGPencil_curves(bContext *C,
}
}
else if (handles_visible) {
if (BEZT_ISSEL_IDX(bezt, j)) {
if (sel) {
td->flag = TD_SELECTED;
}
else {

View File

@ -203,6 +203,21 @@ void gpencil_modifier_curve_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiTemplateCurveMapping(layout, ptr, "curve", 0, false, false, false, false);
}
void gpencil_modifier_fading_draw(const bContext *UNUSED(C), Panel *panel)
{
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
uiLayout *layout = panel->layout;
uiLayoutSetPropSep(layout, true);
bool fading_enabled = RNA_boolean_get(ptr, "use_fading");
uiItemR(layout, ptr, "object", 0, NULL, ICON_CUBE);
uiLayout *sub = uiLayoutColumn(layout, true);
uiItemR(sub, ptr, "fading_start", 0, NULL, ICON_NONE);
uiItemR(sub, ptr, "fading_end", 0, IFACE_("End"), ICON_NONE);
uiItemR(layout, ptr, "fading_end_factor", 0, NULL, ICON_NONE);
}
/**
* Draw modifier error message.
*/

View File

@ -37,6 +37,8 @@ void gpencil_modifier_masking_panel_draw(Panel *panel, bool use_material, bool u
void gpencil_modifier_curve_header_draw(const bContext *C, Panel *panel);
void gpencil_modifier_curve_panel_draw(const bContext *C, Panel *panel);
void gpencil_modifier_fading_draw(const bContext *UNUSED(C), Panel *panel);
void gpencil_modifier_panel_end(struct uiLayout *layout, PointerRNA *ptr);
struct PointerRNA *gpencil_modifier_panel_get_property_pointers(struct Panel *panel,

View File

@ -47,6 +47,8 @@
#include "BKE_screen.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
#include "UI_interface.h"
#include "UI_resources.h"
@ -84,6 +86,39 @@ static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
tgmd->curve_intensity = BKE_curvemapping_copy(gmd->curve_intensity);
}
static float give_opacity_fading_factor(OpacityGpencilModifierData *mmd,
Object *ob_this,
float *pos,
bool apply_obmat)
{
float factor_depth = 1.0f;
if (((mmd->flag & GP_OPACITY_FADING) == 0) || ((mmd->object) == NULL)) {
return factor_depth;
}
float gvert[3];
if (apply_obmat) {
mul_v3_m4v3(gvert, ob_this->obmat, pos);
}
float dist = len_v3v3(mmd->object->obmat[3], gvert);
float fading_max = MAX2(mmd->fading_start, mmd->fading_end);
float fading_min = MIN2(mmd->fading_start, mmd->fading_end);
/* Better with ratiof() function from line art. */
if (dist > fading_max) {
factor_depth = 0.0f;
}
else if (dist <= fading_max && dist > fading_min) {
factor_depth = (fading_max - dist) / (fading_max - fading_min);
}
else {
factor_depth = 1.0f;
}
return factor_depth;
}
/* opacity strokes */
static void deformStroke(GpencilModifierData *md,
Depsgraph *UNUSED(depsgraph),
@ -138,6 +173,9 @@ static void deformStroke(GpencilModifierData *md,
factor_curve *= BKE_curvemapping_evaluateF(mmd->curve_intensity, 0, value);
}
float factor_depth = give_opacity_fading_factor(mmd, ob, &pt->x, true);
factor_curve = interpf(factor_curve, mmd->fading_end_factor, factor_depth);
if (def_nr < 0) {
if (mmd->flag & GP_OPACITY_NORMALIZE) {
pt->strength = factor_curve;
@ -167,6 +205,10 @@ static void deformStroke(GpencilModifierData *md,
/* Fill using opacity factor. */
if (mmd->modify_color != GP_MODIFY_COLOR_STROKE) {
gps->fill_opacity_fac = mmd->factor;
float factor_depth = give_opacity_fading_factor(mmd, ob, ob->obmat[3], true);
gps->fill_opacity_fac = interpf(mmd->factor, mmd->fading_end_factor, factor_depth);
CLAMP(gps->fill_opacity_fac, 0.0f, 1.0f);
}
}
@ -201,6 +243,18 @@ static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk,
OpacityGpencilModifierData *mmd = (OpacityGpencilModifierData *)md;
walk(userData, ob, (ID **)&mmd->material, IDWALK_CB_USER);
walk(userData, ob, (ID **)&mmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(GpencilModifierData *md,
const ModifierUpdateDepsgraphContext *ctx,
const int UNUSED(mode))
{
OpacityGpencilModifierData *mmd = (OpacityGpencilModifierData *)md;
if (mmd->object != NULL) {
DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_TRANSFORM, "Opacity Modifier");
}
DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Opacity Modifier");
}
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
@ -228,6 +282,20 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
gpencil_modifier_panel_end(layout, ptr);
}
static void fading_header_draw(const bContext *UNUSED(C), Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
uiItemR(layout, ptr, "use_fading", 0, NULL, ICON_NONE);
}
static void fading_panel_draw(const bContext *C, Panel *panel)
{
gpencil_modifier_fading_draw(C, panel);
}
static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel)
{
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
@ -266,6 +334,9 @@ static void panelRegister(ARegionType *region_type)
{
PanelType *panel_type = gpencil_modifier_panel_register(
region_type, eGpencilModifierType_Opacity, panel_draw);
gpencil_modifier_subpanel_register(
region_type, "fading", "", fading_header_draw, fading_panel_draw, panel_type);
PanelType *mask_panel_type = gpencil_modifier_subpanel_register(
region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type);
gpencil_modifier_subpanel_register(
@ -289,7 +360,7 @@ GpencilModifierTypeInfo modifierType_Gpencil_Opacity = {
/* initData */ initData,
/* freeData */ freeData,
/* isDisabled */ NULL,
/* updateDepsgraph */ NULL,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,

View File

@ -43,6 +43,8 @@
#include "BKE_screen.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
#include "UI_interface.h"
#include "UI_resources.h"
@ -128,6 +130,30 @@ static void deformStroke(GpencilModifierData *md,
}
float curvef = 1.0f;
float factor_depth = 1.0f;
if (mmd->flag & GP_THICK_FADING) {
if (mmd->object) {
float gvert[3];
mul_v3_m4v3(gvert, ob->obmat, &pt->x);
float dist = len_v3v3(mmd->object->obmat[3], gvert);
float fading_max = MAX2(mmd->fading_start, mmd->fading_end);
float fading_min = MIN2(mmd->fading_start, mmd->fading_end);
/* Better with ratiof() function from line art. */
if (dist > fading_max) {
factor_depth = 0.0f;
}
else if (dist <= fading_max && dist > fading_min) {
factor_depth = (fading_max - dist) / (fading_max - fading_min);
}
else {
factor_depth = 1.0f;
}
}
}
if ((mmd->flag & GP_THICK_CUSTOM_CURVE) && (mmd->curve_thickness)) {
/* Normalize value to evaluate curve. */
float value = (float)i / (gps->totpoints - 1);
@ -144,6 +170,9 @@ static void deformStroke(GpencilModifierData *md,
weight *= curvef;
}
float fac_begin = mmd->flag & GP_THICK_NORMALIZE ? 1 : mmd->thickness_fac;
target *= interpf(fac_begin, mmd->fading_end_factor, factor_depth);
pt->pressure = interpf(target, pt->pressure, weight);
CLAMP_MIN(pt->pressure, 0.0f);
@ -171,6 +200,32 @@ static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk,
ThickGpencilModifierData *mmd = (ThickGpencilModifierData *)md;
walk(userData, ob, (ID **)&mmd->material, IDWALK_CB_USER);
walk(userData, ob, (ID **)&mmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(GpencilModifierData *md,
const ModifierUpdateDepsgraphContext *ctx,
const int UNUSED(mode))
{
ThickGpencilModifierData *mmd = (ThickGpencilModifierData *)md;
if (mmd->object != NULL) {
DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_TRANSFORM, "Thickness Modifier");
}
DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Thickness Modifier");
}
static void fading_header_draw(const bContext *UNUSED(C), Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
uiItemR(layout, ptr, "use_fading", 0, NULL, ICON_NONE);
}
static void fading_panel_draw(const bContext *C, Panel *panel)
{
gpencil_modifier_fading_draw(C, panel);
}
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
@ -202,6 +257,8 @@ static void panelRegister(ARegionType *region_type)
{
PanelType *panel_type = gpencil_modifier_panel_register(
region_type, eGpencilModifierType_Thick, panel_draw);
gpencil_modifier_subpanel_register(
region_type, "fading", "", fading_header_draw, fading_panel_draw, panel_type);
PanelType *mask_panel_type = gpencil_modifier_subpanel_register(
region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type);
gpencil_modifier_subpanel_register(region_type,
@ -229,7 +286,7 @@ GpencilModifierTypeInfo modifierType_Gpencil_Thick = {
/* initData */ initData,
/* freeData */ freeData,
/* isDisabled */ NULL,
/* updateDepsgraph */ NULL,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,

View File

@ -1289,7 +1289,7 @@ static const char *nsvg__parseNumber(const char *s, char *it, const int size)
return s;
}
static const char *nsvg__getNextPathItem(const char *s, char *it)
static const char *nsvg__getNextPathItem(const char *s, char *it, char cmd, int nargs)
{
it[0] = '\0';
// Skip white spaces and commas
@ -1297,6 +1297,15 @@ static const char *nsvg__getNextPathItem(const char *s, char *it)
s++;
if (!*s)
return s;
/* Blender: Special case for arc command's 4th and 5th arguments. */
if (ELEM(cmd, 'a', 'A') && ELEM(nargs, 3, 4)) {
it[0] = s[0];
it[1] = '\0';
s++;
return s;
}
if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) {
s = nsvg__parseNumber(s, it, 64);
}
@ -1576,8 +1585,8 @@ static int nsvg__isCoordinate(const char *s)
// optional sign
if (*s == '-' || *s == '+')
s++;
// must have at least one digit
return nsvg__isdigit(*s);
// must have at least one digit, or start by a dot
return (nsvg__isdigit(*s) || *s == '.');
}
static NSVGcoordinate nsvg__parseCoordinateRaw(const char *str)
@ -2413,7 +2422,7 @@ static void nsvg__parsePath(NSVGparser *p, const char **attr)
nargs = 0;
while (*s) {
s = nsvg__getNextPathItem(s, item);
s = nsvg__getNextPathItem(s, item, cmd, nargs);
if (!*item)
break;
if (cmd != '\0' && nsvg__isCoordinate(item)) {
@ -2740,7 +2749,7 @@ static void nsvg__parsePoly(NSVGparser *p, const char **attr, int closeFlag)
s = attr[i + 1];
nargs = 0;
while (*s) {
s = nsvg__getNextPathItem(s, item);
s = nsvg__getNextPathItem(s, item, '\0', nargs);
args[nargs++] = (float)nsvg__atof(item);
if (nargs >= 2) {
if (npts == 0)

View File

@ -184,6 +184,8 @@
.layer_pass = 0, \
.hardeness = 1.0f, \
.curve_intensity = NULL, \
.fading_end = 10.0f, \
.fading_end_factor = 0.2f, \
}
#define _DNA_DEFAULT_SimplifyGpencilModifierData \
@ -251,6 +253,8 @@
.thickness_fac = 1.0f, \
.thickness = 30, \
.layer_pass = 0, \
.fading_end = 10.0f, \
.fading_end_factor = 0.2f, \
}
#define _DNA_DEFAULT_TimeGpencilModifierData \

View File

@ -187,7 +187,12 @@ typedef struct ThickGpencilModifierData {
int thickness;
/** Custom index for passes. */
int layer_pass;
char _pad[4];
/** Start/end distances of the fading effect. */
float fading_start;
float fading_end;
float fading_end_factor;
/** Fading reference object */
struct Object *object;
struct CurveMapping *curve_thickness;
} ThickGpencilModifierData;
@ -199,6 +204,7 @@ typedef enum eThickGpencil_Flag {
GP_THICK_NORMALIZE = (1 << 4),
GP_THICK_INVERT_LAYERPASS = (1 << 5),
GP_THICK_INVERT_MATERIAL = (1 << 6),
GP_THICK_FADING = (1 << 7),
} eThickGpencil_Flag;
typedef struct TimeGpencilModifierData {
@ -291,9 +297,16 @@ typedef struct OpacityGpencilModifierData {
int flag;
/** Main Opacity factor. */
float factor;
/** Fading controlling object */
int _pad0;
struct Object *object;
/** Start/end distances of the fading effect. */
float fading_start;
float fading_end;
float fading_end_factor;
/** Modify stroke, fill or both. */
char modify_color;
char _pad[3];
char _pad1[3];
/** Custom index for passes. */
int layer_pass;
@ -309,6 +322,7 @@ typedef enum eOpacityGpencil_Flag {
GP_OPACITY_INVERT_MATERIAL = (1 << 5),
GP_OPACITY_CUSTOM_CURVE = (1 << 6),
GP_OPACITY_NORMALIZE = (1 << 7),
GP_OPACITY_FADING = (1 << 8),
} eOpacityGpencil_Flag;
typedef struct ArrayGpencilModifierData {

View File

@ -351,6 +351,8 @@ static void greasepencil_modifier_object_set(Object *self,
RNA_GP_MOD_OBJECT_SET(Armature, object, OB_ARMATURE);
RNA_GP_MOD_OBJECT_SET(Lattice, object, OB_LATTICE);
RNA_GP_MOD_OBJECT_SET(Mirror, object, OB_EMPTY);
RNA_GP_MOD_OBJECT_SET(Opacity, object, OB_EMPTY);
RNA_GP_MOD_OBJECT_SET(Thick, object, OB_EMPTY);
# undef RNA_GP_MOD_OBJECT_SET
@ -1116,6 +1118,38 @@ static void rna_def_modifier_gpencilthick(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Thickness Factor", "Factor to multiply the thickness with");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_fading", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_THICK_FADING);
RNA_def_property_ui_text(prop, "Fading", "Fading effect");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
/* Distance reference object */
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Object", "Object used as distance reference");
RNA_def_property_pointer_funcs(prop, NULL, "rna_ThickGpencilModifier_object_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
prop = RNA_def_property(srna, "fading_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fading_start");
RNA_def_property_ui_range(prop, 0, 1000.0, 1.0, 2);
RNA_def_property_ui_text(prop, "Fading Start", "Start distance of fading effect");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "fading_end", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fading_end");
RNA_def_property_ui_range(prop, 0, 1000.0, 1.0, 2);
RNA_def_property_ui_text(prop, "Fading End", "End distance of fading effect");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "fading_end_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fading_end_factor");
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0, 10.0, 0.1, 3);
RNA_def_property_ui_text(prop, "End Factor", "Fading end thickness factor");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pass_index");
RNA_def_property_range(prop, 0, 100);
@ -1625,6 +1659,38 @@ static void rna_def_modifier_gpencilopacity(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Hardness", "Factor of stroke hardness");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_fading", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OPACITY_FADING);
RNA_def_property_ui_text(prop, "Fading", "Fading effect");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
/* Distance reference object */
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Object", "Object used as distance reference");
RNA_def_property_pointer_funcs(prop, NULL, "rna_OpacityGpencilModifier_object_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
prop = RNA_def_property(srna, "fading_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fading_start");
RNA_def_property_ui_range(prop, 0, 1000.0, 1.0, 2);
RNA_def_property_ui_text(prop, "Fading Start", "Start distance of fading effect");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "fading_end", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fading_end");
RNA_def_property_ui_range(prop, 0, 1000.0, 1.0, 2);
RNA_def_property_ui_text(prop, "Fading End", "End distance of fading effect");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "fading_end_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fading_end_factor");
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0, 10.0, 0.1, 3);
RNA_def_property_ui_text(prop, "End Factor", "Fading end thickness factor");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pass_index");
RNA_def_property_range(prop, 0, 100);

View File

@ -67,7 +67,7 @@ const EnumPropertyItem rna_enum_node_socket_in_out_items[] = {
static const EnumPropertyItem node_socket_data_type_items[] = {
{SOCK_FLOAT, "FLOAT", 0, "Float", ""},
{SOCK_INT, "INT", 0, "Int", ""},
{SOCK_INT, "INT", 0, "Integer", ""},
{SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
{SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
{SOCK_STRING, "STRING", 0, "String", ""},
@ -92,7 +92,7 @@ static const EnumPropertyItem rna_enum_node_socket_display_shape_items[] = {
static const EnumPropertyItem node_socket_type_items[] = {
{SOCK_CUSTOM, "CUSTOM", 0, "Custom", ""},
{SOCK_FLOAT, "VALUE", 0, "Value", ""},
{SOCK_INT, "INT", 0, "Int", ""},
{SOCK_INT, "INT", 0, "Integer", ""},
{SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
{SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
{SOCK_STRING, "STRING", 0, "String", ""},

View File

@ -604,14 +604,22 @@ static PointerRNA rna_Operator_options_get(PointerRNA *ptr)
static PointerRNA rna_Operator_properties_get(PointerRNA *ptr)
{
wmOperator *op = (wmOperator *)ptr->data;
return rna_pointer_inherit_refine(ptr, op->type->srna, op->properties);
PointerRNA result;
WM_operator_properties_create_ptr(&result, op->type);
result.data = op->properties;
return result;
}
static PointerRNA rna_OperatorMacro_properties_get(PointerRNA *ptr)
{
wmOperatorTypeMacro *otmacro = (wmOperatorTypeMacro *)ptr->data;
wmOperatorType *ot = WM_operatortype_find(otmacro->idname, true);
return rna_pointer_inherit_refine(ptr, ot->srna, otmacro->properties);
PointerRNA result;
WM_operator_properties_create_ptr(&result, ot);
result.data = otmacro->properties;
return result;
}
static const EnumPropertyItem *rna_Event_value_itemf(bContext *UNUSED(C),

View File

@ -246,8 +246,9 @@ static void join_components(Span<const InstancesComponent *> src_components, Geo
const int size = component->instances_amount();
Span<InstancedData> instanced_data = component->instanced_data();
Span<float4x4> transforms = component->transforms();
Span<int> ids = component->ids();
for (const int i : IndexRange(size)) {
dst_component.add_instance(instanced_data[i], transforms[i]);
dst_component.add_instance(instanced_data[i], transforms[i], ids[i]);
}
}
}

View File

@ -459,50 +459,81 @@ static bool seq_input_have_to_preprocess(const SeqRenderData *context,
typedef struct ImageTransformThreadInitData {
ImBuf *ibuf_source;
ImBuf *ibuf_out;
StripTransform *transform;
float scale_to_fit;
float image_scale_factor;
Sequence *seq;
float preview_scale_factor;
bool is_proxy_image;
bool for_render;
} ImageTransformThreadInitData;
typedef struct ImageTransformThreadData {
ImBuf *ibuf_source;
ImBuf *ibuf_out;
StripTransform *transform;
float scale_to_fit;
Sequence *seq;
/* image_scale_factor is used to scale proxies to correct preview size. */
float image_scale_factor;
/* Preview scale factor is needed to correct translation to match preview size. */
float preview_scale_factor;
float crop_scale_factor;
bool for_render;
int start_line;
int tot_line;
} ImageTransformThreadData;
static void sequencer_image_transform_init(void *handle_v,
int start_line,
int tot_line,
void *init_data_v)
/**
* Effect, mask and scene in strip input strips are rendered in preview resolution.
* They are already down-scaled. #input_preprocess() does not expect this to happen.
* Other strip types are rendered with original media resolution, unless proxies are
* enabled for them. With proxies `is_proxy_image` will be set correctly to true.
*/
static bool seq_need_scale_to_render_size(const Sequence *seq, bool is_proxy_image)
{
if (is_proxy_image) {
return true;
}
if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->type == SEQ_TYPE_MASK ||
seq->type == SEQ_TYPE_META ||
(seq->type == SEQ_TYPE_SCENE && ((seq->flag & SEQ_SCENE_STRIPS) != 0))) {
return true;
}
return false;
}
static void sequencer_image_crop_transform_init(void *handle_v,
int start_line,
int tot_line,
void *init_data_v)
{
ImageTransformThreadData *handle = (ImageTransformThreadData *)handle_v;
const ImageTransformThreadInitData *init_data = (ImageTransformThreadInitData *)init_data_v;
handle->ibuf_source = init_data->ibuf_source;
handle->ibuf_out = init_data->ibuf_out;
handle->transform = init_data->transform;
handle->image_scale_factor = init_data->image_scale_factor;
handle->preview_scale_factor = init_data->preview_scale_factor;
handle->for_render = init_data->for_render;
handle->seq = init_data->seq;
handle->preview_scale_factor = init_data->preview_scale_factor;
if (seq_need_scale_to_render_size(init_data->seq, init_data->is_proxy_image)) {
handle->image_scale_factor = 1.0f;
}
else {
handle->image_scale_factor = handle->preview_scale_factor;
}
/* Proxy image is smaller, so crop values must be corrected by proxy scale factor.
* Proxy scale factor always matches preview_scale_factor. */
handle->crop_scale_factor = seq_need_scale_to_render_size(init_data->seq,
init_data->is_proxy_image) ?
init_data->preview_scale_factor :
1.0f;
handle->for_render = init_data->for_render;
handle->start_line = start_line;
handle->tot_line = tot_line;
}
static void *sequencer_image_transform_do_thread(void *data_v)
static void *sequencer_image_crop_transform_do_thread(void *data_v)
{
const ImageTransformThreadData *data = (ImageTransformThreadData *)data_v;
const StripTransform *transform = data->transform;
const StripTransform *transform = data->seq->strip->transform;
const float scale_x = transform->scale_x * data->image_scale_factor;
const float scale_y = transform->scale_y * data->image_scale_factor;
const float image_center_offs_x = (data->ibuf_out->x - data->ibuf_source->x) / 2;
@ -515,8 +546,19 @@ static void *sequencer_image_transform_do_thread(void *data_v)
(const float[]){translate_x, translate_y},
transform->rotation,
(const float[]){scale_x, scale_y});
invert_m3(transform_matrix);
transform_pivot_set_m3(transform_matrix, pivot);
invert_m3(transform_matrix);
/* Image crop is done by offsetting image boundary limits. */
const StripCrop *c = data->seq->strip->crop;
const int left = c->left * data->crop_scale_factor;
const int right = c->right * data->crop_scale_factor;
const int top = c->top * data->crop_scale_factor;
const int bottom = c->bottom * data->crop_scale_factor;
const float source_pixel_range_max[2] = {data->ibuf_source->x - right,
data->ibuf_source->y - top};
const float source_pixel_range_min[2] = {left, bottom};
const int width = data->ibuf_out->x;
for (int yi = data->start_line; yi < data->start_line + data->tot_line; yi++) {
@ -524,6 +566,11 @@ static void *sequencer_image_transform_do_thread(void *data_v)
float uv[2] = {xi, yi};
mul_v2_m3v2(uv, transform_matrix, uv);
if (source_pixel_range_min[0] >= uv[0] || uv[0] >= source_pixel_range_max[0] ||
source_pixel_range_min[1] >= uv[1] || uv[1] >= source_pixel_range_max[1]) {
continue;
}
if (data->for_render) {
bilinear_interpolation(data->ibuf_source, data->ibuf_out, uv[0], uv[1], xi, yi);
}
@ -571,25 +618,6 @@ static void multibuf(ImBuf *ibuf, const float fmul)
}
}
/**
* Effect, mask and scene in strip input strips are rendered in preview resolution.
* They are already down-scaled. #input_preprocess() does not expect this to happen.
* Other strip types are rendered with original media resolution, unless proxies are
* enabled for them. With proxies `is_proxy_image` will be set correctly to true.
*/
static bool seq_need_scale_to_render_size(const Sequence *seq, bool is_proxy_image)
{
if (is_proxy_image) {
return true;
}
if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->type == SEQ_TYPE_MASK ||
seq->type == SEQ_TYPE_META ||
(seq->type == SEQ_TYPE_SCENE && ((seq->flag & SEQ_SCENE_STRIPS) != 0))) {
return true;
}
return false;
}
static ImBuf *input_preprocess(const SeqRenderData *context,
Sequence *seq,
float timeline_frame,
@ -608,46 +636,8 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
IMB_filtery(preprocessed_ibuf);
}
/* Get scale factor if preview resolution doesn't match project resolution. */
float preview_scale_factor;
if (context->preview_render_size == SEQ_RENDER_SIZE_SCENE) {
preview_scale_factor = (float)scene->r.size / 100;
}
else {
preview_scale_factor = SEQ_rendersize_to_scale_factor(context->preview_render_size);
}
if (sequencer_use_crop(seq)) {
/* Change original image pointer to avoid another duplication in SEQ_USE_TRANSFORM. */
preprocessed_ibuf = IMB_makeSingleUser(ibuf);
ibuf = preprocessed_ibuf;
const int width = ibuf->x;
const int height = ibuf->y;
const StripCrop *c = seq->strip->crop;
/* Proxy image is smaller, so crop values must be corrected by proxy scale factor.
* Proxy scale factor always matches preview_scale_factor. */
const float crop_scale_factor = seq_need_scale_to_render_size(seq, is_proxy_image) ?
preview_scale_factor :
1.0f;
const int left = c->left * crop_scale_factor;
const int right = c->right * crop_scale_factor;
const int top = c->top * crop_scale_factor;
const int bottom = c->bottom * crop_scale_factor;
const float col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Left. */
IMB_rectfill_area_replace(preprocessed_ibuf, col, 0, 0, left, height);
/* Bottom. */
IMB_rectfill_area_replace(preprocessed_ibuf, col, left, 0, width, bottom);
/* Right. */
IMB_rectfill_area_replace(preprocessed_ibuf, col, width - right, bottom, width, height);
/* Top. */
IMB_rectfill_area_replace(preprocessed_ibuf, col, left, height - top, width - right, height);
}
if (sequencer_use_transform(seq) || context->rectx != ibuf->x || context->recty != ibuf->y) {
if (sequencer_use_crop(seq) || sequencer_use_transform(seq) || context->rectx != ibuf->x ||
context->recty != ibuf->y) {
const int x = context->rectx;
const int y = context->recty;
preprocessed_ibuf = IMB_allocImBuf(x, y, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
@ -655,20 +645,24 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
ImageTransformThreadInitData init_data = {NULL};
init_data.ibuf_source = ibuf;
init_data.ibuf_out = preprocessed_ibuf;
init_data.transform = seq->strip->transform;
if (seq_need_scale_to_render_size(seq, is_proxy_image)) {
init_data.image_scale_factor = 1.0f;
init_data.seq = seq;
init_data.is_proxy_image = is_proxy_image;
/* Get scale factor if preview resolution doesn't match project resolution. */
if (context->preview_render_size == SEQ_RENDER_SIZE_SCENE) {
init_data.preview_scale_factor = (float)scene->r.size / 100;
}
else {
init_data.image_scale_factor = preview_scale_factor;
init_data.preview_scale_factor = SEQ_rendersize_to_scale_factor(
context->preview_render_size);
}
init_data.preview_scale_factor = preview_scale_factor;
init_data.for_render = context->for_render;
IMB_processor_apply_threaded(context->recty,
sizeof(ImageTransformThreadData),
&init_data,
sequencer_image_transform_init,
sequencer_image_transform_do_thread);
sequencer_image_crop_transform_init,
sequencer_image_crop_transform_do_thread);
seq_imbuf_assign_spaces(scene, preprocessed_ibuf);
IMB_metadata_copy(preprocessed_ibuf, ibuf);
IMB_freeImBuf(ibuf);

View File

@ -4478,16 +4478,21 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
event.prevtype = event.type;
event.prevval = event.val;
/* Ensure the event state is correct, any deviation from this may cause bugs. */
/* Ensure the event state is correct, any deviation from this may cause bugs.
*
* NOTE: #EVENT_NONE is set when unknown keys are pressed,
* while not common, avoid a false alarm. */
#ifndef NDEBUG
if ((event_state->type || event_state->val) && /* Ignore cleared event state. */
!(ISMOUSE_BUTTON(event_state->type) || ISKEYBOARD(event_state->type))) {
!(ISMOUSE_BUTTON(event_state->type) || ISKEYBOARD(event_state->type) ||
(event_state->type == EVENT_NONE))) {
CLOG_WARN(WM_LOG_HANDLERS,
"Non-keyboard/mouse button found in 'win->eventstate->type = %d'",
event_state->type);
}
if ((event_state->prevtype || event_state->prevval) && /* Ignore cleared event state. */
!(ISMOUSE_BUTTON(event_state->prevtype) || ISKEYBOARD(event_state->prevtype))) {
!(ISMOUSE_BUTTON(event_state->prevtype) || ISKEYBOARD(event_state->prevtype) ||
(event_state->type == EVENT_NONE))) {
CLOG_WARN(WM_LOG_HANDLERS,
"Non-keyboard/mouse button found in 'win->eventstate->prevtype = %d'",
event_state->prevtype);