Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/alembic/intern/abc_writer_curves.cc6
-rw-r--r--source/blender/alembic/intern/abc_writer_mball.cc6
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c10
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h2
-rw-r--r--source/blender/blenkernel/BKE_object.h4
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c73
-rw-r--r--source/blender/blenkernel/intern/constraint.c134
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c4
-rw-r--r--source/blender/blenkernel/intern/displist.c16
-rw-r--r--source/blender/blenkernel/intern/effect.c6
-rw-r--r--source/blender/blenkernel/intern/image.c8
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c32
-rw-r--r--source/blender/blenkernel/intern/modifier.c2
-rw-r--r--source/blender/blenkernel/intern/object.c101
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c4
-rw-r--r--source/blender/blenkernel/intern/object_update.c4
-rw-r--r--source/blender/blenkernel/intern/paint.c2
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c8
-rw-r--r--source/blender/blenlib/CMakeLists.txt6
-rw-r--r--source/blender/blenlib/intern/string.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c8
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.h2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc4
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc24
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c277
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h8
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c12
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_world_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl64
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl8
-rw-r--r--source/blender/draw/engines/overlay/shaders/motion_path_line_vert.glsl9
-rw-r--r--source/blender/draw/intern/draw_cache.c48
-rw-r--r--source/blender/draw/intern/draw_manager_data.c38
-rw-r--r--source/blender/draw/intern/shaders/common_view_lib.glsl1
-rw-r--r--source/blender/editors/animation/anim_filter.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c2
-rw-r--r--source/blender/editors/include/ED_image.h26
-rw-r--r--source/blender/editors/include/ED_transform.h1
-rw-r--r--source/blender/editors/mesh/editface.c7
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c5
-rw-r--r--source/blender/editors/object/object_add.c75
-rw-r--r--source/blender/editors/object/object_constraint.c136
-rw-r--r--source/blender/editors/physics/particle_edit.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c2
-rw-r--r--source/blender/editors/space_file/filelist.c13
-rw-r--r--source/blender/editors/space_file/fsmenu.c22
-rw-r--r--source/blender/editors/space_image/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_image/image_buttons.c2
-rw-r--r--source/blender/editors/space_image/image_ops.c274
-rw-r--r--source/blender/editors/space_image/image_sequence.c249
-rw-r--r--source/blender/editors/space_info/info_stats.c5
-rw-r--r--source/blender/editors/space_nla/space_nla.c8
-rw-r--r--source/blender/editors/space_view3d/drawobject.c9
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c8
-rw-r--r--source/blender/editors/transform/transform.c4
-rw-r--r--source/blender/editors/transform/transform_convert.c26
-rw-r--r--source/blender/editors/transform/transform_convert.h4
-rw-r--r--source/blender/editors/transform/transform_convert_action.c11
-rw-r--r--source/blender/editors/transform/transform_convert_graph.c11
-rw-r--r--source/blender/editors/transform/transform_convert_nla.c11
-rw-r--r--source/blender/editors/transform/transform_convert_sequencer.c24
-rw-r--r--source/blender/editors/transform/transform_generics.c26
-rw-r--r--source/blender/editors/transform/transform_ops.c10
-rw-r--r--source/blender/editors/transform/transform_snap_object.c303
-rw-r--r--source/blender/editors/util/ed_util.c13
-rw-r--r--source/blender/gpu/GPU_material.h19
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c411
-rw-r--r--source/blender/gpu/intern/gpu_draw.c3
-rw-r--r--source/blender/gpu/intern/gpu_material.c9
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c178
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.h52
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h4
-rw-r--r--source/blender/makesdna/DNA_object_types.h16
-rw-r--r--source/blender/makesrna/intern/rna_brush.c2
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c13
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c2
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c27
-rw-r--r--source/blender/makesrna/intern/rna_render.c4
-rw-r--r--source/blender/makesrna/intern/rna_space.c20
-rw-r--r--source/blender/nodes/shader/node_shader_util.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_attribute.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geometry.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tangent.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c14
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c32
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_sky.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_uvmap.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_displacement.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vertex_color.c2
-rw-r--r--source/blender/usd/intern/usd_writer_mesh.cc2
-rw-r--r--source/blender/windowmanager/intern/wm_keymap_utils.c2
99 files changed, 1570 insertions, 1515 deletions
diff --git a/source/blender/alembic/intern/abc_writer_curves.cc b/source/blender/alembic/intern/abc_writer_curves.cc
index bb9109dc025..3ab9b365a72 100644
--- a/source/blender/alembic/intern/abc_writer_curves.cc
+++ b/source/blender/alembic/intern/abc_writer_curves.cc
@@ -31,6 +31,7 @@ extern "C" {
#include "BKE_curve.h"
#include "BKE_mesh.h"
+#include "BKE_object.h"
}
using Alembic::AbcGeom::OCompoundProperty;
@@ -176,10 +177,11 @@ Mesh *AbcCurveMeshWriter::getEvaluatedMesh(Scene * /*scene_eval*/,
Object *ob_eval,
bool &r_needsfree)
{
- if (ob_eval->runtime.mesh_eval != NULL) {
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ if (mesh_eval != NULL) {
/* Mesh_eval only exists when generative modifiers are in use. */
r_needsfree = false;
- return ob_eval->runtime.mesh_eval;
+ return mesh_eval;
}
r_needsfree = true;
diff --git a/source/blender/alembic/intern/abc_writer_mball.cc b/source/blender/alembic/intern/abc_writer_mball.cc
index aa08146c6e2..cc0775bd537 100644
--- a/source/blender/alembic/intern/abc_writer_mball.cc
+++ b/source/blender/alembic/intern/abc_writer_mball.cc
@@ -30,6 +30,7 @@ extern "C" {
#include "BKE_lib_id.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
+#include "BKE_object.h"
#include "BLI_utildefines.h"
}
@@ -55,10 +56,11 @@ bool AbcMBallWriter::isAnimated() const
Mesh *AbcMBallWriter::getEvaluatedMesh(Scene * /*scene_eval*/, Object *ob_eval, bool &r_needsfree)
{
- if (ob_eval->runtime.mesh_eval != NULL) {
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ if (mesh_eval != NULL) {
/* Mesh_eval only exists when generative modifiers are in use. */
r_needsfree = false;
- return ob_eval->runtime.mesh_eval;
+ return mesh_eval;
}
r_needsfree = true;
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 8e88bda37a5..3ab6814c531 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -461,7 +461,7 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
return;
}
- if (!g->cached) {
+ if (g->glyph_cache == NULL) {
if (font->tex_size_max == -1) {
font->tex_size_max = GPU_max_texture_size();
}
@@ -492,7 +492,7 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
gc->bitmap_len = bitmap_len;
gc->glyphs_len_free--;
- g->cached = true;
+ g->glyph_cache = gc;
}
if (font->flags & BLF_CLIPPING) {
@@ -505,8 +505,10 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
}
}
- g_batch.glyph_cache = gc;
- BLI_assert(g->offset < gc->bitmap_len);
+ if (g_batch.glyph_cache != g->glyph_cache) {
+ blf_batch_draw();
+ g_batch.glyph_cache = g->glyph_cache;
+ }
if (font->flags & BLF_SHADOW) {
rctf rect_ofs;
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index bb1697d7860..6ea1702200f 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -131,7 +131,7 @@ typedef struct GlyphBLF {
float pos_x;
float pos_y;
- bool cached;
+ struct GlyphCacheBLF *glyph_cache;
} GlyphBLF;
typedef struct FontBufInfoBLF {
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 9f436db97ee..8963f241ca8 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -287,6 +287,7 @@ void BKE_object_eval_uber_transform(struct Depsgraph *depsgraph, struct Object *
void BKE_object_eval_uber_data(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob);
+void BKE_object_eval_assign_data(struct Object *object, struct ID *data, bool is_owned);
void BKE_object_eval_boundbox(struct Depsgraph *depsgraph, struct Object *object);
void BKE_object_synchronize_to_original(struct Depsgraph *depsgraph, struct Object *object);
@@ -326,8 +327,7 @@ int BKE_object_obdata_texspace_get(struct Object *ob,
float **r_loc,
float **r_size);
-struct Mesh *BKE_object_get_evaluated_mesh(const struct Depsgraph *depsgraph, struct Object *ob);
-struct Mesh *BKE_object_get_final_mesh(struct Object *object);
+struct Mesh *BKE_object_get_evaluated_mesh(struct Object *object);
struct Mesh *BKE_object_get_pre_modified_mesh(struct Object *object);
struct Mesh *BKE_object_get_original_mesh(struct Object *object);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 3006ab76032..148c7a6b6c0 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1719,43 +1719,12 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
}
}
-static void assign_object_mesh_eval(Object *object)
-{
- BLI_assert(object->id.tag & LIB_TAG_COPIED_ON_WRITE);
-
- Mesh *mesh = (Mesh *)object->data;
- Mesh *mesh_eval = object->runtime.mesh_eval;
-
- /* The modifier stack evaluation is storing result in mesh->runtime.mesh_eval, but this result
- * is not guaranteed to be owned by object.
- *
- * Check ownership now, since later on we can not go to a mesh owned by someone else via object's
- * runtime: this could cause access freed data on depsgraph destruction (mesh who owns the final
- * result might be freed prior to object). */
- if (mesh_eval == mesh->runtime.mesh_eval) {
- object->runtime.is_mesh_eval_owned = false;
- }
- else {
- mesh_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
- object->runtime.is_mesh_eval_owned = true;
- }
-
- /* NOTE: We are not supposed to invoke evaluation for original object, but some areas are still
- * under process of being ported, so we play safe here. */
- if (object->id.tag & LIB_TAG_COPIED_ON_WRITE) {
- object->data = mesh_eval;
- }
- else {
- /* evaluated will be available via: 'object->runtime.mesh_eval' */
- }
-}
-
-static void mesh_build_extra_data(struct Depsgraph *depsgraph, Object *ob)
+static void mesh_build_extra_data(struct Depsgraph *depsgraph, Object *ob, Mesh *mesh_eval)
{
uint32_t eval_flags = DEG_get_eval_flags_for_id(depsgraph, &ob->id);
if (eval_flags & DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY) {
- BKE_shrinkwrap_compute_boundary_data(ob->runtime.mesh_eval);
+ BKE_shrinkwrap_compute_boundary_data(mesh_eval);
}
}
@@ -1793,6 +1762,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
}
#endif
+ Mesh *mesh_eval = NULL, *mesh_deform_eval = NULL;
mesh_calc_modifiers(depsgraph,
scene,
ob,
@@ -1802,26 +1772,35 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
-1,
true,
true,
- &ob->runtime.mesh_deform_eval,
- &ob->runtime.mesh_eval);
-
- BKE_object_boundbox_calc_from_mesh(ob, ob->runtime.mesh_eval);
-
- assign_object_mesh_eval(ob);
+ &mesh_deform_eval,
+ &mesh_eval);
+ /* The modifier stack evaluation is storing result in mesh->runtime.mesh_eval, but this result
+ * is not guaranteed to be owned by object.
+ *
+ * Check ownership now, since later on we can not go to a mesh owned by someone else via
+ * object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns
+ * the final result might be freed prior to object). */
+ Mesh *mesh = ob->data;
+ const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime.mesh_eval);
+ BKE_object_eval_assign_data(ob, &mesh_eval->id, is_mesh_eval_owned);
+
+ ob->runtime.mesh_deform_eval = mesh_deform_eval;
ob->runtime.last_data_mask = *dataMask;
ob->runtime.last_need_mapping = need_mapping;
+ BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
+
if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
if (DEG_is_active(depsgraph)) {
BKE_sculpt_update_object_after_eval(depsgraph, ob);
}
}
- if (ob->runtime.mesh_eval != NULL) {
- mesh_runtime_check_normals_valid(ob->runtime.mesh_eval);
+ if (mesh_eval != NULL) {
+ mesh_runtime_check_normals_valid(mesh_eval);
}
- mesh_build_extra_data(depsgraph, ob);
+ mesh_build_extra_data(depsgraph, ob, mesh_eval);
}
static void editbmesh_build_data(struct Depsgraph *depsgraph,
@@ -1942,18 +1921,20 @@ Mesh *mesh_get_eval_final(struct Depsgraph *depsgraph,
CustomData_MeshMasks cddata_masks = *dataMask;
object_get_datamask(depsgraph, ob, &cddata_masks, &need_mapping);
- if (!ob->runtime.mesh_eval ||
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ if ((mesh_eval == NULL) ||
!CustomData_MeshMasks_are_matching(&(ob->runtime.last_data_mask), &cddata_masks) ||
(need_mapping && !ob->runtime.last_need_mapping)) {
CustomData_MeshMasks_update(&cddata_masks, &ob->runtime.last_data_mask);
mesh_build_data(
depsgraph, scene, ob, &cddata_masks, need_mapping || ob->runtime.last_need_mapping);
+ mesh_eval = BKE_object_get_evaluated_mesh(ob);
}
- if (ob->runtime.mesh_eval) {
- BLI_assert(!(ob->runtime.mesh_eval->runtime.cd_dirty_vert & CD_MASK_NORMAL));
+ if (mesh_eval != NULL) {
+ BLI_assert(!(mesh_eval->runtime.cd_dirty_vert & CD_MASK_NORMAL));
}
- return ob->runtime.mesh_eval;
+ return mesh_eval;
}
Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph,
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 8ba746e3493..3df1a84a0c9 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -368,7 +368,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
/* when not in EditMode, use the 'final' evaluated mesh, depsgraph
* ensures we build with CD_MDEFORMVERT layer
*/
- Mesh *me_eval = ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
BMEditMesh *em = BKE_editmesh_from_object(ob);
float plane[3];
float imat[3][3], tmat[3][3];
@@ -860,94 +860,88 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
}
float parmat[4][4];
-
- /* simple matrix parenting */
- if (data->flag == CHILDOF_ALL) {
-
- /* multiply target (parent matrix) by offset (parent inverse) to get
- * the effect of the parent that will be exerted on the owner
- */
- mul_m4_m4m4(parmat, ct->matrix, data->invmat);
-
- /* now multiply the parent matrix by the owner matrix to get the
- * the effect of this constraint (i.e. owner is 'parented' to parent)
- */
- mul_m4_m4m4(cob->matrix, parmat, cob->matrix);
+ /* Simple matrix parenting. */
+ if ((data->flag & CHILDOF_ALL) == CHILDOF_ALL) {
+ copy_m4_m4(parmat, ct->matrix);
}
+ /* Filter the parent matrix by channel. */
else {
- float invmat[4][4], tempmat[4][4];
float loc[3], eul[3], size[3];
- float loco[3], eulo[3], sizo[3];
-
- /* get offset (parent-inverse) matrix */
- copy_m4_m4(invmat, data->invmat);
/* extract components of both matrices */
copy_v3_v3(loc, ct->matrix[3]);
mat4_to_eulO(eul, ct->rotOrder, ct->matrix);
mat4_to_size(size, ct->matrix);
- copy_v3_v3(loco, invmat[3]);
- mat4_to_eulO(eulo, cob->rotOrder, invmat);
- mat4_to_size(sizo, invmat);
-
/* disable channels not enabled */
if (!(data->flag & CHILDOF_LOCX)) {
- loc[0] = loco[0] = 0.0f;
+ loc[0] = 0.0f;
}
if (!(data->flag & CHILDOF_LOCY)) {
- loc[1] = loco[1] = 0.0f;
+ loc[1] = 0.0f;
}
if (!(data->flag & CHILDOF_LOCZ)) {
- loc[2] = loco[2] = 0.0f;
+ loc[2] = 0.0f;
}
if (!(data->flag & CHILDOF_ROTX)) {
- eul[0] = eulo[0] = 0.0f;
+ eul[0] = 0.0f;
}
if (!(data->flag & CHILDOF_ROTY)) {
- eul[1] = eulo[1] = 0.0f;
+ eul[1] = 0.0f;
}
if (!(data->flag & CHILDOF_ROTZ)) {
- eul[2] = eulo[2] = 0.0f;
+ eul[2] = 0.0f;
}
if (!(data->flag & CHILDOF_SIZEX)) {
- size[0] = sizo[0] = 1.0f;
+ size[0] = 1.0f;
}
if (!(data->flag & CHILDOF_SIZEY)) {
- size[1] = sizo[1] = 1.0f;
+ size[1] = 1.0f;
}
if (!(data->flag & CHILDOF_SIZEZ)) {
- size[2] = sizo[2] = 1.0f;
+ size[2] = 1.0f;
}
/* make new target mat and offset mat */
- loc_eulO_size_to_mat4(ct->matrix, loc, eul, size, ct->rotOrder);
- loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder);
+ loc_eulO_size_to_mat4(parmat, loc, eul, size, ct->rotOrder);
+ }
- /* multiply target (parent matrix) by offset (parent inverse) to get
- * the effect of the parent that will be exerted on the owner
- */
- mul_m4_m4m4(parmat, ct->matrix, invmat);
+ /* Compute the inverse matrix if requested. */
+ if (data->flag & CHILDOF_SET_INVERSE) {
+ invert_m4_m4(data->invmat, parmat);
- /* now multiply the parent matrix by the owner matrix to get the
- * the effect of this constraint (i.e. owner is 'parented' to parent)
- */
- copy_m4_m4(tempmat, cob->matrix);
- mul_m4_m4m4(cob->matrix, parmat, tempmat);
+ data->flag &= ~CHILDOF_SET_INVERSE;
- /* without this, changes to scale and rotation can change location
- * of a parentless bone or a disconnected bone. Even though its set
- * to zero above. */
- if (!(data->flag & CHILDOF_LOCX)) {
- cob->matrix[3][0] = tempmat[3][0];
- }
- if (!(data->flag & CHILDOF_LOCY)) {
- cob->matrix[3][1] = tempmat[3][1];
- }
- if (!(data->flag & CHILDOF_LOCZ)) {
- cob->matrix[3][2] = tempmat[3][2];
+ /* Write the computed matrix back to the master copy if in COW evaluation. */
+ bConstraint *orig_con = constraint_find_original_for_update(cob, con);
+
+ if (orig_con != NULL) {
+ bChildOfConstraint *orig_data = orig_con->data;
+
+ copy_m4_m4(orig_data->invmat, data->invmat);
+ orig_data->flag &= ~CHILDOF_SET_INVERSE;
}
}
+
+ /* Multiply together the target (parent) matrix, parent inverse,
+ * and the owner transform matrixto get the effect of this constraint
+ * (i.e. owner is 'parented' to parent). */
+ float orig_cob_matrix[4][4];
+ copy_m4_m4(orig_cob_matrix, cob->matrix);
+ mul_m4_series(cob->matrix, parmat, data->invmat, orig_cob_matrix);
+
+ /* Without this, changes to scale and rotation can change location
+ * of a parentless bone or a disconnected bone. Even though its set
+ * to zero above. */
+ if (!(data->flag & CHILDOF_LOCX)) {
+ cob->matrix[3][0] = orig_cob_matrix[3][0];
+ }
+ if (!(data->flag & CHILDOF_LOCY)) {
+ cob->matrix[3][1] = orig_cob_matrix[3][1];
+ }
+ if (!(data->flag & CHILDOF_LOCZ)) {
+ cob->matrix[3][2] = orig_cob_matrix[3][2];
+ }
}
/* XXX note, con->flag should be CONSTRAINT_SPACEONCE for bone-childof, patched in readfile.c */
@@ -3974,7 +3968,7 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
float track_no[3] = {0.0f, 0.0f, 0.0f};
SpaceTransform transform;
- Mesh *target_eval = ct->tar->runtime.mesh_eval;
+ Mesh *target_eval = BKE_object_get_evaluated_mesh(ct->tar);
copy_m4_m4(ct->matrix, cob->matrix);
@@ -4742,7 +4736,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
if (data->depth_ob) {
Object *depth_ob = data->depth_ob;
- Mesh *target_eval = depth_ob->runtime.mesh_eval;
+ Mesh *target_eval = BKE_object_get_evaluated_mesh(depth_ob);
if (target_eval) {
BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
BVHTreeRayHit hit;
@@ -4891,23 +4885,35 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
return;
}
- float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
+ float mat[4][4], obmat[4][4], imat[4][4], parmat[4][4];
float ctime = DEG_get_ctime(depsgraph);
float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime);
- BKE_object_where_is_calc_mat4(camob, cammat);
-
BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
- invert_m4_m4(camimat, cammat);
- mul_m4_m4m4(parmat, cammat, data->invmat);
+ invert_m4_m4(imat, mat);
+ mul_m4_m4m4(parmat, camob->obmat, imat);
- copy_m4_m4(cammat, camob->obmat);
copy_m4_m4(obmat, cob->matrix);
- invert_m4_m4(imat, mat);
+ /* Recalculate the inverse matrix if requested. */
+ if (data->flag & OBJECTSOLVER_SET_INVERSE) {
+ invert_m4_m4(data->invmat, parmat);
+
+ data->flag &= ~OBJECTSOLVER_SET_INVERSE;
+
+ /* Write the computed matrix back to the master copy if in COW evaluation. */
+ bConstraint *orig_con = constraint_find_original_for_update(cob, con);
+
+ if (orig_con != NULL) {
+ bObjectSolverConstraint *orig_data = orig_con->data;
+
+ copy_m4_m4(orig_data->invmat, data->invmat);
+ orig_data->flag &= ~OBJECTSOLVER_SET_INVERSE;
+ }
+ }
- mul_m4_series(cob->matrix, cammat, imat, camimat, parmat, obmat);
+ mul_m4_series(cob->matrix, parmat, data->invmat, obmat);
}
static bConstraintTypeInfo CTI_OBJECTSOLVER = {
diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index e0abe836bf8..bdca888efcc 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -338,8 +338,8 @@ static void crazyspace_init_object_for_eval(struct Depsgraph *depsgraph,
{
Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
*object_crazy = *object_eval;
- if (object_crazy->runtime.mesh_orig != NULL) {
- object_crazy->data = object_crazy->runtime.mesh_orig;
+ if (object_crazy->runtime.data_orig != NULL) {
+ object_crazy->data = object_crazy->runtime.data_orig;
}
}
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 6d7d42b2293..6963f629798 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1772,7 +1772,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render);
}
- if (cu->flag & CU_DEFORM_FILL && !ob->runtime.mesh_eval) {
+ if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) {
curve_to_filledpoly(cu, &nubase, dispbase);
}
@@ -1800,12 +1800,11 @@ void BKE_displist_make_curveTypes(
dispbase = &(ob->runtime.curve_cache->disp);
- do_makeDispListCurveTypes(
- depsgraph, scene, ob, dispbase, for_render, for_orco, &ob->runtime.mesh_eval);
+ Mesh *mesh_eval = NULL;
+ do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, for_render, for_orco, &mesh_eval);
- if (ob->runtime.mesh_eval != NULL) {
- ob->runtime.mesh_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
- ob->runtime.is_mesh_eval_owned = true;
+ if (mesh_eval != NULL) {
+ BKE_object_eval_assign_data(ob, &mesh_eval->id, true);
}
boundbox_displist_object(ob);
@@ -1861,8 +1860,9 @@ static void boundbox_displist_object(Object *ob)
ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "boundbox");
}
- if (ob->runtime.mesh_eval) {
- BKE_object_boundbox_calc_from_mesh(ob, ob->runtime.mesh_eval);
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ if (mesh_eval) {
+ BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
}
else {
float min[3], max[3];
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 8971021329a..4a9efc7cac4 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -315,7 +315,7 @@ ListBase *BKE_effectors_create(Depsgraph *depsgraph,
else if (weights->weight[ob->pd->forcefield] == 0.0f) {
continue;
}
- else if (ob->pd->shape == PFIELD_SHAPE_POINTS && ob->runtime.mesh_eval == NULL) {
+ else if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) {
continue;
}
@@ -656,7 +656,7 @@ int get_effector_data(EffectorCache *eff,
efd->size = 0.0f;
}
else if (eff->pd && eff->pd->shape == PFIELD_SHAPE_POINTS) {
- Mesh *me_eval = eff->ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
if (me_eval != NULL) {
copy_v3_v3(efd->loc, me_eval->mvert[*efd->index].co);
normal_short_to_float_v3(efd->nor, me_eval->mvert[*efd->index].no);
@@ -769,7 +769,7 @@ static void get_effector_tot(
efd->index = p;
if (eff->pd->shape == PFIELD_SHAPE_POINTS) {
- Mesh *me_eval = eff->ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
*tot = me_eval != NULL ? me_eval->totvert : 1;
if (*tot && eff->pd->forcefield == PFIELD_HARMONIC && point->index >= 0) {
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 7868b72e9cf..5761bec98b2 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -5180,6 +5180,14 @@ void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra)
iuser->ok = 1;
}
+ if (ima) {
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ if (tile->ok == 0) {
+ tile->ok = IMA_OK;
+ }
+ }
+ }
+
iuser->flag &= ~IMA_NEED_FRAME_RECALC;
}
}
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index af5e867ac38..d8d5653730b 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -1608,6 +1608,7 @@ static void material_default_surface_init(Material *ma)
{
bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
ma->nodetree = ntree;
+ ma->use_nodes = true;
bNode *principled = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_PRINCIPLED);
bNodeSocket *base_color = nodeFindSocket(principled, SOCK_IN, "Base Color");
@@ -1633,6 +1634,7 @@ static void material_default_volume_init(Material *ma)
{
bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
ma->nodetree = ntree;
+ ma->use_nodes = true;
bNode *principled = nodeAddStaticNode(NULL, ntree, SH_NODE_VOLUME_PRINCIPLED);
bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 014ccdb913e..f0bab4c0aa2 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -582,7 +582,7 @@ void BKE_mesh_from_nurbs_displist(
Main *bmain, Object *ob, ListBase *dispbase, const char *obdata_name, bool temporary)
{
Object *ob1;
- Mesh *me_eval = ob->runtime.mesh_eval;
+ Mesh *me_eval = (Mesh *)ob->runtime.data_eval;
Mesh *me;
Curve *cu;
MVert *allvert = NULL;
@@ -644,7 +644,7 @@ void BKE_mesh_from_nurbs_displist(
me = BKE_id_new_nomain(ID_ME, obdata_name);
}
- ob->runtime.mesh_eval = NULL;
+ ob->runtime.data_eval = NULL;
BKE_mesh_nomain_to_mesh(me_eval, me, ob, &CD_MASK_MESH, true);
}
@@ -929,11 +929,9 @@ static Object *object_for_curve_to_mesh_create(Object *object)
BKE_displist_copy(&temp_object->runtime.curve_cache->disp, &object->runtime.curve_cache->disp);
}
/* Constructive modifiers will use mesh to store result. */
- if (object->runtime.mesh_eval != NULL) {
- BKE_id_copy_ex(NULL,
- &object->runtime.mesh_eval->id,
- (ID **)&temp_object->runtime.mesh_eval,
- LIB_ID_COPY_LOCALIZE);
+ if (object->runtime.data_eval != NULL) {
+ BKE_id_copy_ex(
+ NULL, object->runtime.data_eval, &temp_object->runtime.data_eval, LIB_ID_COPY_LOCALIZE);
}
/* Need to create copy of curve itself as well, it will be freed by underlying conversion
@@ -994,19 +992,15 @@ static void curve_to_mesh_eval_ensure(Object *object)
* bit of internal functions (BKE_mesh_from_nurbs_displist, BKE_mesh_nomain_to_mesh) and also
* Mesh From Curve operator.
* Brecht says hold off with that. */
- BKE_displist_make_curveTypes_forRender(NULL,
- NULL,
- &remapped_object,
- &remapped_object.runtime.curve_cache->disp,
- &remapped_object.runtime.mesh_eval,
- false);
+ Mesh *mesh_eval = NULL;
+ BKE_displist_make_curveTypes_forRender(
+ NULL, NULL, &remapped_object, &remapped_object.runtime.curve_cache->disp, &mesh_eval, false);
/* Note: this is to be consistent with `BKE_displist_make_curveTypes()`, however that is not a
* real issue currently, code here is broken in more than one way, fix(es) will be done
* separately. */
- if (remapped_object.runtime.mesh_eval != NULL) {
- remapped_object.runtime.mesh_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
- remapped_object.runtime.is_mesh_eval_owned = true;
+ if (mesh_eval != NULL) {
+ BKE_object_eval_assign_data(&remapped_object, &mesh_eval->id, true);
}
BKE_object_free_curve_cache(&bevel_object);
@@ -1104,8 +1098,8 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, Object
}
Object object_for_eval = *object;
- if (object_for_eval.runtime.mesh_orig != NULL) {
- object_for_eval.data = object_for_eval.runtime.mesh_orig;
+ if (object_for_eval.runtime.data_orig != NULL) {
+ object_for_eval.data = object_for_eval.runtime.data_orig;
}
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -1306,7 +1300,7 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
ModifierData *md_eval,
int build_shapekey_layers)
{
- Mesh *me = ob_eval->runtime.mesh_orig ? ob_eval->runtime.mesh_orig : ob_eval->data;
+ Mesh *me = ob_eval->runtime.data_orig ? ob_eval->runtime.data_orig : ob_eval->data;
const ModifierTypeInfo *mti = modifierType_getInfo(md_eval->type);
Mesh *result;
KeyBlock *kb;
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 51c70406692..381e43241ea 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -1019,7 +1019,7 @@ Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval,
if (me == NULL) {
me = (get_cage_mesh && ob_eval->runtime.mesh_deform_eval != NULL) ?
ob_eval->runtime.mesh_deform_eval :
- ob_eval->runtime.mesh_eval;
+ BKE_object_get_evaluated_mesh(ob_eval);
}
return me;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 51d397a44bc..4d7d5861a09 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -363,11 +363,11 @@ static void object_update_from_subsurf_ccg(Object *object)
* (happens on dependency graph free where order of CoW-ed IDs free is undefined).
*
* Good news is: such mesh does not have modifiers applied, so no need to worry about CCG. */
- if (!object->runtime.is_mesh_eval_owned) {
+ if (!object->runtime.is_data_eval_owned) {
return;
}
/* Object was never evaluated, so can not have CCG subdivision surface. */
- Mesh *mesh_eval = object->runtime.mesh_eval;
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(object);
if (mesh_eval == NULL) {
return;
}
@@ -410,13 +410,13 @@ static void object_update_from_subsurf_ccg(Object *object)
/* TODO(sergey): Solve this somehow, to be fully stable for threaded
* evaluation environment.
*/
- /* NOTE: runtime.mesh_orig is what was before assigning mesh_eval,
+ /* NOTE: runtime.data_orig is what was before assigning mesh_eval,
* it is orig as in what was in object_eval->data before evaluating
* modifier stack.
*
* mesh_cow is a copy-on-written version od object_orig->data.
*/
- Mesh *mesh_cow = object->runtime.mesh_orig;
+ Mesh *mesh_cow = (Mesh *)object->runtime.data_orig;
copy_ccg_data(mesh_cow, mesh_orig, CD_MDISPS);
copy_ccg_data(mesh_cow, mesh_orig, CD_GRID_PAINT_MASK);
/* Everything is now up-to-date. */
@@ -424,6 +424,33 @@ static void object_update_from_subsurf_ccg(Object *object)
subdiv_ccg->dirty.hidden = false;
}
+/* Assign data after modifier stack evaluation. */
+void BKE_object_eval_assign_data(Object *object_eval, ID *data_eval, bool is_owned)
+{
+ BLI_assert(object_eval->id.tag & LIB_TAG_COPIED_ON_WRITE);
+ BLI_assert(object_eval->runtime.data_eval == NULL);
+ BLI_assert(data_eval->tag & LIB_TAG_NO_MAIN);
+
+ if (is_owned) {
+ /* Set flag for debugging. */
+ data_eval->tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
+ }
+
+ /* Assigned evaluated data. */
+ object_eval->runtime.data_eval = data_eval;
+ object_eval->runtime.is_data_eval_owned = is_owned;
+
+ /* Overwrite data of evaluated object, if the datablock types match. */
+ ID *data = object_eval->data;
+ if (GS(data->name) == GS(data_eval->name)) {
+ /* NOTE: we are not supposed to invoke evaluation for original objects,
+ * but some areas are still being ported, so we play safe here. */
+ if (object_eval->id.tag & LIB_TAG_COPIED_ON_WRITE) {
+ object_eval->data = data_eval;
+ }
+ }
+}
+
/* free data derived from mesh, called when mesh changes or is freed */
void BKE_object_free_derived_caches(Object *ob)
{
@@ -431,17 +458,18 @@ void BKE_object_free_derived_caches(Object *ob)
object_update_from_subsurf_ccg(ob);
- /* Restore initial pointer. */
- if (ob->runtime.mesh_orig != NULL) {
- ob->data = ob->runtime.mesh_orig;
- }
-
- if (ob->runtime.mesh_eval != NULL) {
- if (ob->runtime.is_mesh_eval_owned) {
- Mesh *mesh_eval = ob->runtime.mesh_eval;
- BKE_mesh_eval_delete(mesh_eval);
+ if (ob->runtime.data_eval != NULL) {
+ if (ob->runtime.is_data_eval_owned) {
+ ID *data_eval = ob->runtime.data_eval;
+ if (GS(data_eval->name) == ID_ME) {
+ BKE_mesh_eval_delete((Mesh *)data_eval);
+ }
+ else {
+ BKE_libblock_free_datablock(data_eval, 0);
+ MEM_freeN(data_eval);
+ }
}
- ob->runtime.mesh_eval = NULL;
+ ob->runtime.data_eval = NULL;
}
if (ob->runtime.mesh_deform_eval != NULL) {
Mesh *mesh_deform_eval = ob->runtime.mesh_deform_eval;
@@ -449,6 +477,12 @@ void BKE_object_free_derived_caches(Object *ob)
ob->runtime.mesh_deform_eval = NULL;
}
+ /* Restore initial pointer for copy-on-write datablocks, object->data
+ * might be pointing to an evaluated datablock data was just freed above. */
+ if (ob->runtime.data_orig != NULL) {
+ ob->data = ob->runtime.data_orig;
+ }
+
BKE_object_to_mesh_clear(ob);
BKE_object_free_curve_cache(ob);
@@ -2308,7 +2342,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
if (par->type == OB_MESH) {
Mesh *me = par->data;
BMEditMesh *em = me->edit_mesh;
- Mesh *me_eval = (em) ? em->mesh_eval_final : par->runtime.mesh_eval;
+ Mesh *me_eval = (em) ? em->mesh_eval_final : BKE_object_get_evaluated_mesh(par);
if (me_eval) {
int count = 0;
@@ -3067,12 +3101,12 @@ void BKE_object_foreach_display_point(Object *ob,
void (*func_cb)(const float[3], void *),
void *user_data)
{
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
float co[3];
- if (ob->runtime.mesh_eval) {
- const Mesh *me = ob->runtime.mesh_eval;
- const MVert *mv = me->mvert;
- const int totvert = me->totvert;
+ if (mesh_eval != NULL) {
+ const MVert *mv = mesh_eval->mvert;
+ const int totvert = mesh_eval->totvert;
for (int i = 0; i < totvert; i++, mv++) {
mul_v3_m4v3(co, obmat, mv->co);
func_cb(co, user_data);
@@ -3342,24 +3376,11 @@ int BKE_object_obdata_texspace_get(Object *ob, short **r_texflag, float **r_loc,
return 1;
}
-/** Get evaluated mesh for given (main, original) object and depsgraph. */
-Mesh *BKE_object_get_evaluated_mesh(const Depsgraph *depsgraph, Object *ob)
+/** Get evaluated mesh for given object. */
+Mesh *BKE_object_get_evaluated_mesh(Object *object)
{
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- return ob_eval->runtime.mesh_eval;
-}
-
-/* Get object's mesh with all modifiers applied. */
-Mesh *BKE_object_get_final_mesh(Object *object)
-{
- if (object->runtime.mesh_eval != NULL) {
- BLI_assert((object->id.tag & LIB_TAG_COPIED_ON_WRITE) != 0);
- BLI_assert(object->runtime.mesh_eval == object->data);
- BLI_assert((object->runtime.mesh_eval->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) != 0);
- return object->runtime.mesh_eval;
- }
- /* Wasn't evaluated yet. */
- return object->data;
+ ID *data_eval = object->runtime.data_eval;
+ return (data_eval && GS(data_eval->name) == ID_ME) ? (Mesh *)data_eval : NULL;
}
/* Get mesh which is not affected by modifiers:
@@ -3370,11 +3391,11 @@ Mesh *BKE_object_get_final_mesh(Object *object)
*/
Mesh *BKE_object_get_pre_modified_mesh(Object *object)
{
- if (object->runtime.mesh_orig != NULL) {
+ if (object->type == OB_MESH && object->runtime.data_orig != NULL) {
BLI_assert(object->id.tag & LIB_TAG_COPIED_ON_WRITE);
BLI_assert(object->id.orig_id != NULL);
- BLI_assert(object->runtime.mesh_orig->id.orig_id == ((Object *)object->id.orig_id)->data);
- Mesh *result = object->runtime.mesh_orig;
+ BLI_assert(object->runtime.data_orig->orig_id == ((Object *)object->id.orig_id)->data);
+ Mesh *result = (Mesh *)object->runtime.data_orig;
BLI_assert((result->id.tag & LIB_TAG_COPIED_ON_WRITE) != 0);
BLI_assert((result->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
return result;
@@ -3925,7 +3946,7 @@ void BKE_object_runtime_reset(Object *object)
void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag))
{
Object_Runtime *runtime = &object->runtime;
- runtime->mesh_eval = NULL;
+ runtime->data_eval = NULL;
runtime->mesh_deform_eval = NULL;
runtime->curve_cache = NULL;
runtime->gpencil_cache = NULL;
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index c10ab3cddab..28b6e0d4e02 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -426,7 +426,7 @@ static void make_duplis_verts(const DupliContext *ctx)
vdd.me_eval = vdd.edit_mesh->mesh_eval_cage;
}
else {
- vdd.me_eval = parent->runtime.mesh_eval;
+ vdd.me_eval = BKE_object_get_evaluated_mesh(parent);
}
if (vdd.me_eval == NULL) {
@@ -702,7 +702,7 @@ static void make_duplis_faces(const DupliContext *ctx)
fdd.me_eval = em->mesh_eval_cage;
}
else {
- fdd.me_eval = parent->runtime.mesh_eval;
+ fdd.me_eval = BKE_object_get_evaluated_mesh(parent);
}
if (fdd.me_eval == NULL) {
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 366fd0950fa..c647afdd00a 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -398,8 +398,8 @@ void BKE_object_data_select_update(Depsgraph *depsgraph, ID *object_data)
void BKE_object_select_update(Depsgraph *depsgraph, Object *object)
{
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
- if (object->type == OB_MESH && !object->runtime.is_mesh_eval_owned) {
- Mesh *mesh_input = object->runtime.mesh_orig;
+ if (object->type == OB_MESH && !object->runtime.is_data_eval_owned) {
+ Mesh *mesh_input = (Mesh *)object->runtime.data_orig;
Mesh_Runtime *mesh_runtime = &mesh_input->runtime;
BLI_mutex_lock(mesh_runtime->eval_mutex);
BKE_object_data_select_update(depsgraph, object->data);
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 2cc1681d436..4da7d8d007a 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1351,7 +1351,7 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
/* Update after mesh evaluation in the dependency graph, to rebuild PBVH or
* other data when modifiers change the mesh. */
Object *ob_orig = DEG_get_original_object(ob_eval);
- Mesh *me_eval = ob_eval->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
BLI_assert(me_eval != NULL);
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index c2180e50b74..494c5e21613 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -332,22 +332,24 @@ void BKE_rigidbody_object_copy(Main *bmain, Object *ob_dst, const Object *ob_src
/* get the appropriate evaluated mesh based on rigid body mesh source */
static Mesh *rigidbody_get_mesh(Object *ob)
{
+ BLI_assert(ob->type == OB_MESH);
+
switch (ob->rigidbody_object->mesh_source) {
case RBO_MESH_DEFORM:
return ob->runtime.mesh_deform_eval;
case RBO_MESH_FINAL:
- return ob->runtime.mesh_eval;
+ return BKE_object_get_evaluated_mesh(ob);
case RBO_MESH_BASE:
/* This mesh may be used for computing looptris, which should be done
* on the original; otherwise every time the CoW is recreated it will
* have to be recomputed. */
BLI_assert(ob->rigidbody_object->mesh_source == RBO_MESH_BASE);
- return ob->runtime.mesh_orig;
+ return (Mesh *)ob->runtime.data_orig;
}
/* Just return something sensible so that at least Blender won't crash. */
BLI_assert(!"Unknown mesh source");
- return ob->runtime.mesh_eval;
+ return BKE_object_get_evaluated_mesh(ob);
}
/* create collision shape of mesh - convex hull */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 1e4e07d63b3..1de0c192a20 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -277,6 +277,12 @@ if(WIN32)
)
endif()
+if(UNIX AND NOT APPLE)
+ list(APPEND LIB
+ bf_intern_libc_compat
+ )
+endif()
+
# no need to compile object files for inline headers.
set_source_files_properties(
intern/math_base_inline.c
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 7f5b1e7ea65..99db2f0a290 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -818,7 +818,7 @@ void BLI_str_toupper_ascii(char *str, const size_t len)
*/
void BLI_str_rstrip(char *str)
{
- for (int i = (int)strlen(str) - 1; i > 0; i--) {
+ for (int i = (int)strlen(str) - 1; i >= 0; i--) {
if (isspace(str[i])) {
str[i] = '\0';
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index d8c2057bb56..0ff89aa3127 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -7145,7 +7145,7 @@ static void bevel_limit_offset(BevelParams *bp, BMesh *bm)
void BM_mesh_bevel(BMesh *bm,
const float offset,
const int offset_type,
- const float segments,
+ const int segments,
const float profile,
const bool vertex_only,
const bool use_weights,
@@ -7176,7 +7176,7 @@ void BM_mesh_bevel(BMesh *bm,
bp.offset = offset;
bp.offset_type = offset_type;
- bp.seg = (int)segments;
+ bp.seg = segments;
bp.profile = profile;
bp.pro_super_r = -logf(2.0) / logf(sqrtf(profile)); /* Convert to superellipse exponent. */
bp.vertex_only = vertex_only;
@@ -7207,6 +7207,10 @@ void BM_mesh_bevel(BMesh *bm,
bp.miter_inner = BEVEL_MITER_SHARP;
}
+ if (bp.seg <= 1) {
+ bp.seg = 1;
+ }
+
if (profile >= 0.950f) { /* r ~ 692, so PRO_SQUARE_R is 1e4 */
bp.pro_super_r = PRO_SQUARE_R;
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h
index 45bebbb33ce..479a8a3f6d6 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.h
+++ b/source/blender/bmesh/tools/bmesh_bevel.h
@@ -27,7 +27,7 @@ struct MDeformVert;
void BM_mesh_bevel(BMesh *bm,
const float offset,
const int offset_type,
- const float segments,
+ const int segments,
const float profile,
const bool vertex_only,
const bool use_weights,
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index edb02ee331f..95521ee9e47 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -781,9 +781,7 @@ void update_id_after_copy(const Depsgraph *depsgraph,
const Object *object_orig = (const Object *)id_orig;
object_cow->mode = object_orig->mode;
object_cow->sculpt = object_orig->sculpt;
- if (object_cow->type == OB_MESH) {
- object_cow->runtime.mesh_orig = (Mesh *)object_cow->data;
- }
+ object_cow->runtime.data_orig = (ID *)object_cow->data;
if (object_cow->type == OB_ARMATURE) {
const bArmature *armature_orig = (bArmature *)object_orig->data;
bArmature *armature_cow = (bArmature *)object_cow->data;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
index df7338e1076..acbcd4d551d 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
@@ -44,7 +44,6 @@ ObjectRuntimeBackup::ObjectRuntimeBackup(const Depsgraph * /*depsgraph*/)
void ObjectRuntimeBackup::init_from_object(Object *object)
{
/* Store evaluated mesh and curve_cache, and make sure we don't free it. */
- Mesh *mesh_eval = object->runtime.mesh_eval;
runtime = object->runtime;
BKE_object_runtime_reset(object);
/* Keep bbox (for now at least). */
@@ -52,9 +51,7 @@ void ObjectRuntimeBackup::init_from_object(Object *object)
/* Object update will override actual object->data to an evaluated version.
* Need to make sure we don't have data set to evaluated one before free
* anything. */
- if (mesh_eval != nullptr && object->data == mesh_eval) {
- object->data = runtime.mesh_orig;
- }
+ object->data = runtime.data_orig;
/* Make a backup of base flags. */
base_flag = object->base_flag;
base_local_view_bits = object->base_local_view_bits;
@@ -98,12 +95,13 @@ void ObjectRuntimeBackup::backup_pose_channel_runtime_data(Object *object)
void ObjectRuntimeBackup::restore_to_object(Object *object)
{
- Mesh *mesh_orig = object->runtime.mesh_orig;
+ ID *data_orig = object->runtime.data_orig;
+ ID *data_eval = object->runtime.data_eval;
BoundBox *bb = object->runtime.bb;
object->runtime = runtime;
- object->runtime.mesh_orig = mesh_orig;
+ object->runtime.data_orig = data_orig;
object->runtime.bb = bb;
- if (object->type == OB_MESH && object->runtime.mesh_eval != nullptr) {
+ if (object->type == OB_MESH && data_eval != nullptr) {
if (object->id.recalc & ID_RECALC_GEOMETRY) {
/* If geometry is tagged for update it means, that part of
* evaluated mesh are not valid anymore. In this case we can not
@@ -111,20 +109,24 @@ void ObjectRuntimeBackup::restore_to_object(Object *object)
*
* We restore object's data datablock to an original copy of
* that datablock. */
- object->data = mesh_orig;
+ object->data = data_orig;
/* After that, immediately free the invalidated caches. */
BKE_object_free_derived_caches(object);
}
else {
- Mesh *mesh_eval = object->runtime.mesh_eval;
/* Do same thing as object update: override actual object data
* pointer with evaluated datablock. */
- object->data = mesh_eval;
+ object->data = data_eval;
+
/* Evaluated mesh simply copied edit_mesh pointer from
* original mesh during update, need to make sure no dead
* pointers are left behind. */
- mesh_eval->edit_mesh = mesh_orig->edit_mesh;
+ if (object->type == OB_MESH) {
+ Mesh *mesh_eval = (Mesh *)data_eval;
+ Mesh *mesh_orig = (Mesh *)data_orig;
+ mesh_eval->edit_mesh = mesh_orig->edit_mesh;
+ }
}
}
object->base_flag = base_flag;
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 6480847092b..a886fa26589 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -120,7 +120,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
bool cast_shadow = false;
if (ob_visibility & OB_VISIBLE_PARTICLES) {
- EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
+ EEVEE_particle_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
}
if (DRW_object_is_renderable(ob) && (ob_visibility & OB_VISIBLE_SELF)) {
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 7661dfb41a5..89e45148ee8 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1728,6 +1728,144 @@ BLI_INLINE Material *eevee_object_material_get(Object *ob, int slot)
return ma;
}
+static void eevee_hair_cache_populate(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
+ Object *ob,
+ ParticleSystem *psys,
+ ModifierData *md,
+ int matnr,
+ bool *cast_shadow)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+
+ DRWShadingGroup *shgrp = NULL;
+ Material *ma = eevee_object_material_get(ob, matnr - 1);
+
+ float *color_p = &ma->r;
+ float *metal_p = &ma->metallic;
+ float *spec_p = &ma->spec;
+ float *rough_p = &ma->roughness;
+
+ bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
+ const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
+
+ shgrp = DRW_shgroup_hair_create(ob, psys, md, psl->depth_pass, e_data.default_hair_prepass_sh);
+
+ shgrp = DRW_shgroup_hair_create(
+ ob, psys, md, psl->depth_pass_clip, e_data.default_hair_prepass_clip_sh);
+
+ shgrp = NULL;
+
+ if (ma->use_nodes && ma->nodetree && !holdout) {
+ static int ssr_id;
+ ssr_id = (use_ssr) ? 1 : -1;
+ static float half = 0.5f;
+ static float error_col[3] = {1.0f, 0.0f, 1.0f};
+ static float compile_col[3] = {0.5f, 0.5f, 0.5f};
+ struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma);
+
+ switch (GPU_material_status(gpumat)) {
+ case GPU_MAT_SUCCESS: {
+ bool use_diffuse = GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE);
+ bool use_glossy = GPU_material_flag_get(gpumat, GPU_MATFLAG_GLOSSY);
+ bool use_refract = GPU_material_flag_get(gpumat, GPU_MATFLAG_REFRACT);
+
+ shgrp = DRW_shgroup_material_hair_create(ob, psys, md, psl->material_pass, gpumat);
+
+ if (!use_diffuse && !use_glossy && !use_refract) {
+ /* HACK: Small hack to avoid issue when utilTex is needed for
+ * world_normals_get and none of the bsdfs are present.
+ * This binds utilTex even if not needed. */
+ DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
+ }
+
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ use_diffuse,
+ use_glossy,
+ use_refract,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
+
+ /* Add the hair to all the render_passes that are enabled */
+ RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
+ shgrp = DRW_shgroup_material_hair_create(
+ ob, psys, md, psl->material_accum_pass[render_pass_index], gpumat);
+ if (!use_diffuse && !use_glossy && !use_refract) {
+ /* Small hack to avoid issue when utilTex is needed for
+ * world_normals_get and none of the bsdfs that need it are present.
+ * This binds `utilTex` even if not needed. */
+ DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
+ }
+
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ use_diffuse,
+ use_glossy,
+ use_refract,
+ false,
+ false,
+ render_pass_flag);
+ RENDER_PASS_ITER_END(render_pass_index)
+
+ break;
+ }
+ case GPU_MAT_QUEUED: {
+ stl->g_data->queued_shaders_count++;
+ color_p = compile_col;
+ metal_p = spec_p = rough_p = &half;
+ break;
+ }
+ case GPU_MAT_FAILED:
+ default:
+ color_p = error_col;
+ metal_p = spec_p = rough_p = &half;
+ break;
+ }
+ }
+
+ /* Fallback to default shader */
+ if (shgrp == NULL) {
+ shgrp = EEVEE_default_shading_group_get(sldata, vedata, ob, psys, md, true, holdout, use_ssr);
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+
+ RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
+ shgrp = EEVEE_default_hair_render_pass_shading_group_get(
+ sldata,
+ vedata,
+ ob,
+ psys,
+ md,
+ holdout,
+ use_ssr,
+ psl->material_accum_pass[render_pass_index],
+ render_pass_flag);
+
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+ RENDER_PASS_ITER_END(render_pass_index)
+ }
+
+ /* Shadows */
+ DRW_shgroup_hair_create(ob, psys, md, psl->shadow_pass, e_data.default_hair_prepass_sh);
+ *cast_shadow = true;
+}
+
void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
@@ -1906,18 +2044,12 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
}
}
-void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
- EEVEE_ViewLayerData *sldata,
- Object *ob,
- bool *cast_shadow)
+void EEVEE_particle_hair_cache_populate(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
+ Object *ob,
+ bool *cast_shadow)
{
- EEVEE_PassList *psl = vedata->psl;
- EEVEE_StorageList *stl = vedata->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
-
- bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
- const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
if (ob->type == OB_MESH) {
if (ob != draw_ctx->object_edit) {
@@ -1934,130 +2066,7 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
if (draw_as != PART_DRAW_PATH) {
continue;
}
-
- DRWShadingGroup *shgrp = NULL;
- Material *ma = eevee_object_material_get(ob, part->omat - 1);
-
- float *color_p = &ma->r;
- float *metal_p = &ma->metallic;
- float *spec_p = &ma->spec;
- float *rough_p = &ma->roughness;
-
- shgrp = DRW_shgroup_hair_create(
- ob, psys, md, psl->depth_pass, e_data.default_hair_prepass_sh);
-
- shgrp = DRW_shgroup_hair_create(
- ob, psys, md, psl->depth_pass_clip, e_data.default_hair_prepass_clip_sh);
-
- shgrp = NULL;
-
- if (ma->use_nodes && ma->nodetree && !holdout) {
- static int ssr_id;
- ssr_id = (use_ssr) ? 1 : -1;
- static float half = 0.5f;
- static float error_col[3] = {1.0f, 0.0f, 1.0f};
- static float compile_col[3] = {0.5f, 0.5f, 0.5f};
- struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma);
-
- switch (GPU_material_status(gpumat)) {
- case GPU_MAT_SUCCESS: {
- bool use_diffuse = GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE);
- bool use_glossy = GPU_material_flag_get(gpumat, GPU_MATFLAG_GLOSSY);
- bool use_refract = GPU_material_flag_get(gpumat, GPU_MATFLAG_REFRACT);
-
- shgrp = DRW_shgroup_material_hair_create(ob, psys, md, psl->material_pass, gpumat);
-
- if (!use_diffuse && !use_glossy && !use_refract) {
- /* HACK: Small hack to avoid issue when utilTex is needed for
- * world_normals_get and none of the bsdfs are present.
- * This binds utilTex even if not needed. */
- DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
- }
-
- add_standard_uniforms(shgrp,
- sldata,
- vedata,
- &ssr_id,
- NULL,
- use_diffuse,
- use_glossy,
- use_refract,
- false,
- false,
- DEFAULT_RENDER_PASS_FLAG);
-
- /* Add the hair to all the render_passes that are enabled */
- RENDER_PASS_ITER_BEGIN(
- stl->g_data->render_passes, render_pass_index, render_pass_flag)
- shgrp = DRW_shgroup_material_hair_create(
- ob, psys, md, psl->material_accum_pass[render_pass_index], gpumat);
- if (!use_diffuse && !use_glossy && !use_refract) {
- /* Small hack to avoid issue when utilTex is needed for
- * world_normals_get and none of the bsdfs that need it are present.
- * This binds `utilTex` even if not needed. */
- DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
- }
-
- add_standard_uniforms(shgrp,
- sldata,
- vedata,
- &ssr_id,
- NULL,
- use_diffuse,
- use_glossy,
- use_refract,
- false,
- false,
- render_pass_flag);
- RENDER_PASS_ITER_END(render_pass_index)
-
- break;
- }
- case GPU_MAT_QUEUED: {
- stl->g_data->queued_shaders_count++;
- color_p = compile_col;
- metal_p = spec_p = rough_p = &half;
- break;
- }
- case GPU_MAT_FAILED:
- default:
- color_p = error_col;
- metal_p = spec_p = rough_p = &half;
- break;
- }
- }
-
- /* Fallback to default shader */
- if (shgrp == NULL) {
- shgrp = EEVEE_default_shading_group_get(
- sldata, vedata, ob, psys, md, true, holdout, use_ssr);
- DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
- DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
- DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
- DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
-
- RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
- shgrp = EEVEE_default_hair_render_pass_shading_group_get(
- sldata,
- vedata,
- ob,
- psys,
- md,
- holdout,
- use_ssr,
- psl->material_accum_pass[render_pass_index],
- render_pass_flag);
-
- DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
- DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
- DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
- DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
- RENDER_PASS_ITER_END(render_pass_index)
- }
-
- /* Shadows */
- DRW_shgroup_hair_create(ob, psys, md, psl->shadow_pass, e_data.default_hair_prepass_sh);
- *cast_shadow = true;
+ eevee_hair_cache_populate(vedata, sldata, ob, psys, md, part->omat, cast_shadow);
}
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index a2ed0a16d89..9a8b2cb793a 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -897,10 +897,10 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
bool *cast_shadow);
-void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
- EEVEE_ViewLayerData *sldata,
- Object *ob,
- bool *cast_shadow);
+void EEVEE_particle_hair_cache_populate(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
+ Object *ob,
+ bool *cast_shadow);
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, struct World *wo);
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, struct World *wo);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 3a5d9e96b80..ed81665bcfb 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -204,7 +204,7 @@ void EEVEE_render_cache(void *vedata,
const int ob_visibility = DRW_object_visibility_in_active_context(ob);
if (ob_visibility & OB_VISIBLE_PARTICLES) {
- EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
+ EEVEE_particle_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
}
if (ob_visibility & OB_VISIBLE_SELF) {
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index 2f9e8f3d555..e9dcb6376bb 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -88,7 +88,17 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata)
View3D *v3d = draw_ctx->v3d;
if (v3d) {
- g_data->render_passes = v3d->shading.render_pass;
+ const Scene *scene = draw_ctx->scene;
+ eViewLayerEEVEEPassType render_pass = v3d->shading.render_pass;
+ if (render_pass == EEVEE_RENDER_PASS_AO &&
+ ((scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0)) {
+ render_pass = EEVEE_RENDER_PASS_COMBINED;
+ }
+ else if (render_pass == EEVEE_RENDER_PASS_BLOOM &&
+ ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
+ render_pass = EEVEE_RENDER_PASS_COMBINED;
+ }
+ g_data->render_passes = render_pass;
}
else {
eViewLayerEEVEEPassType enabled_render_passes = view_layer->eevee.render_passes;
diff --git a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
index 1faa02fd354..8c876cf582c 100644
--- a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
@@ -12,7 +12,9 @@ uniform float studioLightIntensity = 1.0;
uniform float studioLightBlur = 0.0;
in vec3 viewPosition;
-# define M_PI 3.14159265358979323846
+# ifndef M_PI
+# define M_PI 3.14159265358979323846
+# endif
vec3 background_transform_to_world(vec3 viewvec)
{
diff --git a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
index 18f92c0dd33..489e87e9a7d 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
@@ -202,9 +202,9 @@ vec4 step_resolve(void)
#else
vec3 blur = upsample_filter(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
#endif
- vec3 base = bloomAddBase ? textureLod(baseBuffer, uvcoordsvar.xy, 0.0).rgb : vec3(0.0);
- vec3 cout = base + blur * bloomColor;
- return vec4(cout, 1.0);
+ vec4 base = bloomAddBase ? textureLod(baseBuffer, uvcoordsvar.xy, 0.0) : vec4(0.0);
+ vec3 cout = base.rgb + blur * bloomColor;
+ return vec4(cout, base.a);
}
void main(void)
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
index 5214301bc03..03520c55a85 100644
--- a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
@@ -15,6 +15,38 @@ uniform sampler2D inputColorBuffer;
out vec4 fragColor;
+vec3 safe_divide_even_color(vec3 a, vec3 b)
+{
+ vec3 result = vec3((b.r != 0.0) ? a.r / b.r : 0.0,
+ (b.g != 0.0) ? a.g / b.g : 0.0,
+ (b.b != 0.0) ? a.b / b.b : 0.0);
+ /* try to get gray even if b is zero */
+ if (b.r == 0.0) {
+ if (b.g == 0.0) {
+ result = result.bbb;
+ }
+ else if (b.b == 0.0) {
+ result = result.ggg;
+ }
+ else {
+ result.r = 0.5 * (result.g + result.b);
+ }
+ }
+ else if (b.g == 0.0) {
+ if (b.b == 0.0) {
+ result = result.rrr;
+ }
+ else {
+ result.g = 0.5 * (result.r + result.b);
+ }
+ }
+ else if (b.b == 0.0) {
+ result.b = 0.5 * (result.r + result.g);
+ }
+
+ return result;
+}
+
void main()
{
ivec2 texel = ivec2(gl_FragCoord.xy);
@@ -58,41 +90,13 @@ void main()
else if (postProcessType == PASS_POST_ACCUMULATED_LIGHT) {
vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb;
vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
-
- /* Fix INF in the case a color component is 0.0 */
- if (accumulated_color.r == 0.0) {
- accumulated_color.r = 1.0;
- accumulated_light.r = 0.0;
- }
- if (accumulated_color.g == 0.0) {
- accumulated_color.g = 1.0;
- accumulated_light.g = 0.0;
- }
- if (accumulated_color.b == 0.0) {
- accumulated_color.b = 1.0;
- accumulated_light.b = 0.0;
- }
- fragColor = vec4(accumulated_light / accumulated_color, 1.0);
+ fragColor = vec4(safe_divide_even_color(accumulated_light, accumulated_color), 1.0);
}
else if (postProcessType == PASS_POST_TWO_LIGHT_BUFFERS) {
vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb +
texelFetch(inputSecondLightBuffer, texel, 0).rgb;
vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
-
- /* Fix INF in the case a color component is 0.0 */
- if (accumulated_color.r == 0.0) {
- accumulated_color.r = 1.0;
- accumulated_light.r = 0.0;
- }
- if (accumulated_color.g == 0.0) {
- accumulated_color.g = 1.0;
- accumulated_light.g = 0.0;
- }
- if (accumulated_color.b == 0.0) {
- accumulated_color.b = 1.0;
- accumulated_light.b = 0.0;
- }
- fragColor = vec4(accumulated_light / accumulated_color, 1.0);
+ fragColor = vec4(safe_divide_even_color(accumulated_light, accumulated_color), 1.0);
}
else {
/* Output error color: Unknown how to post process this pass. */
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
index fa02bee45b7..5778f02f692 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
@@ -11,7 +11,7 @@ void main()
{
if (laNumLight == 0) {
/* Early exit: No lights in scene */
- fragColor.r = 0.0;
+ fragColor.r = 1.0;
return;
}
@@ -19,7 +19,7 @@ void main()
float depth = texelFetch(depthBuffer, texel, 0).r;
if (depth == 1.0f) {
/* Early exit background does not receive shadows */
- fragColor.r = 1.0;
+ fragColor.r = 0.0;
return;
}
@@ -40,6 +40,7 @@ void main()
vec3 worldPosition = transform_point(ViewMatrixInverse, viewPosition);
vec3 true_normal = normalize(cross(dFdx(viewPosition), dFdy(viewPosition)));
+ vec3 N = normal_view_to_world(true_normal);
for (int i = 0; i < MAX_LIGHT && i < laNumLight; i++) {
LightData ld = lights_data[i];
@@ -48,8 +49,9 @@ void main()
l_vector.xyz = ld.l_position - worldPosition;
l_vector.w = length(l_vector.xyz);
+ float light_input = smoothstep(0.2, -0.2, -dot(N, normalize(l_vector.xyz)));
float l_vis = light_shadowing(
- ld, worldPosition, viewPosition, tracing_depth, true_normal, rand.x, true, 1.0);
+ ld, worldPosition, viewPosition, tracing_depth, true_normal, rand.x, true, light_input);
accum_light += l_vis;
}
diff --git a/source/blender/draw/engines/overlay/shaders/motion_path_line_vert.glsl b/source/blender/draw/engines/overlay/shaders/motion_path_line_vert.glsl
index 6d7f673731e..7486f287a79 100644
--- a/source/blender/draw/engines/overlay/shaders/motion_path_line_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/motion_path_line_vert.glsl
@@ -32,7 +32,7 @@ void main()
float intensity; /* how faint */
- vec3 blend_base = (abs(frame - frameCurrent) == 1) ?
+ vec3 blend_base = (abs(frame - frameCurrent) == 0) ?
colorCurrentFrame.rgb :
colorBackground.rgb; /* "bleed" cframe color to ease color blending */
bool use_custom_color = customColor.x >= 0.0;
@@ -78,13 +78,12 @@ void main()
else {
/* green - on frameCurrent */
if (selected) {
- intensity = 0.5f;
+ intensity = 0.92f;
}
else {
- intensity = 0.99f;
+ intensity = 0.75f;
}
- finalColor_geom.rgb = clamp(
- mix(colorCurrentFrame.rgb, colorBackground.rgb, intensity) - 0.1, 0.0, 0.1);
+ finalColor_geom.rgb = mix(colorBackground.rgb, blend_base, intensity);
}
}
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 8057d167e2f..f37e5b14d83 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -836,12 +836,12 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob)
int DRW_cache_object_material_count_get(struct Object *ob)
{
- Mesh *me = (ob->runtime.mesh_eval != NULL) ? ob->runtime.mesh_eval : (Mesh *)ob->data;
- short type = (ob->runtime.mesh_eval != NULL) ? OB_MESH : ob->type;
+ Mesh *me = BKE_object_get_evaluated_mesh(ob);
+ short type = (me != NULL) ? OB_MESH : ob->type;
switch (type) {
case OB_MESH:
- return DRW_mesh_material_count_get(me);
+ return DRW_mesh_material_count_get((me != NULL) ? me : ob->data);
case OB_CURVE:
case OB_SURF:
case OB_FONT:
@@ -2807,7 +2807,7 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob)
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
@@ -2845,7 +2845,7 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob)
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface(mesh_eval);
}
@@ -2859,7 +2859,7 @@ GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob)
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
@@ -2875,7 +2875,7 @@ GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob)
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
}
@@ -2888,7 +2888,7 @@ GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold)
{
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
}
@@ -2905,7 +2905,7 @@ GPUBatch **DRW_cache_curve_surface_shaded_get(Object *ob,
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
}
@@ -2957,7 +2957,7 @@ GPUBatch *DRW_cache_text_edge_wire_get(Object *ob)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
const bool has_surface = (cu->flag & (CU_FRONT | CU_BACK)) || cu->ext1 != 0.0f ||
cu->ext2 != 0.0f;
if (!has_surface) {
@@ -2975,7 +2975,7 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (cu->editfont && (cu->flag & CU_FAST)) {
return NULL;
}
@@ -2991,7 +2991,7 @@ GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (cu->editfont && (cu->flag & CU_FAST)) {
return NULL;
}
@@ -3007,7 +3007,7 @@ GPUBatch *DRW_cache_text_loose_edges_get(Object *ob)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (cu->editfont && (cu->flag & CU_FAST)) {
return NULL;
}
@@ -3024,7 +3024,7 @@ GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (cu->editfont && (cu->flag & CU_FAST)) {
return NULL;
}
@@ -3042,7 +3042,7 @@ GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob,
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (cu->editfont && (cu->flag & CU_FAST)) {
return NULL;
}
@@ -3065,7 +3065,7 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob)
BLI_assert(ob->type == OB_SURF);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface(mesh_eval);
}
@@ -3079,7 +3079,7 @@ GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob)
BLI_assert(ob->type == OB_SURF);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
@@ -3093,7 +3093,7 @@ GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob)
BLI_assert(ob->type == OB_SURF);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
}
@@ -3106,7 +3106,7 @@ GPUBatch *DRW_cache_surf_edge_detection_get(Object *ob, bool *r_is_manifold)
{
BLI_assert(ob->type == OB_SURF);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
}
@@ -3120,7 +3120,7 @@ GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob)
BLI_assert(ob->type == OB_SURF);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
@@ -3139,7 +3139,7 @@ GPUBatch **DRW_cache_surf_surface_shaded_get(Object *ob,
BLI_assert(ob->type == OB_SURF);
struct Curve *cu = ob->data;
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
}
@@ -3398,7 +3398,7 @@ GPUBatch *DRW_cache_cursor_get(bool crosshair_lines)
void drw_batch_cache_validate(Object *ob)
{
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
switch (ob->type) {
case OB_MESH:
DRW_mesh_batch_cache_validate((Mesh *)ob->data);
@@ -3436,7 +3436,7 @@ void drw_batch_cache_generate_requested(Object *ob)
DRW_object_use_hide_faces(ob)) ||
((mode == CTX_MODE_EDIT_MESH) && DRW_object_is_in_edit_mode(ob))));
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
switch (ob->type) {
case OB_MESH:
DRW_mesh_batch_cache_create_requested(ob, (Mesh *)ob->data, scene, is_paint_mode, use_hide);
@@ -3457,7 +3457,7 @@ void drw_batch_cache_generate_requested(Object *ob)
void DRW_batch_cache_free_old(Object *ob, int ctime)
{
- struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
switch (ob->type) {
case OB_MESH:
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index fbdabb44b15..43e8e2a4733 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -1203,6 +1203,19 @@ static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass
return grp;
}
+static void drw_shgroup_material_texture(DRWShadingGroup *grp,
+ GPUMaterialTexture *tex,
+ const char *name,
+ int textarget)
+{
+ GPUTexture *gputex = GPU_texture_from_blender(tex->ima, tex->iuser, NULL, textarget);
+ DRW_shgroup_uniform_texture(grp, name, gputex);
+
+ GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images);
+ *gputex_ref = gputex;
+ GPU_texture_ref(gputex);
+}
+
static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp,
struct GPUMaterial *material)
{
@@ -1210,35 +1223,20 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp,
/* Bind all textures needed by the material. */
for (GPUMaterialTexture *tex = textures.first; tex; tex = tex->next) {
- GPUTexture *gputex;
-
if (tex->ima) {
/* Image */
- GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images);
-
- int textarget;
- if (tex->type == GPU_TEX2D_ARRAY) {
- textarget = GL_TEXTURE_2D_ARRAY;
- }
- else if (tex->type == GPU_TEX1D_ARRAY) {
- textarget = GL_TEXTURE_1D_ARRAY;
+ if (tex->tiled_mapping_name[0]) {
+ drw_shgroup_material_texture(grp, tex, tex->sampler_name, GL_TEXTURE_2D_ARRAY);
+ drw_shgroup_material_texture(grp, tex, tex->tiled_mapping_name, GL_TEXTURE_1D_ARRAY);
}
else {
- textarget = GL_TEXTURE_2D;
+ drw_shgroup_material_texture(grp, tex, tex->sampler_name, GL_TEXTURE_2D);
}
- *gputex_ref = gputex = GPU_texture_from_blender(tex->ima, tex->iuser, NULL, textarget);
-
- GPU_texture_ref(gputex);
}
else if (tex->colorband) {
/* Color Ramp */
- gputex = *tex->colorband;
+ DRW_shgroup_uniform_texture(grp, tex->sampler_name, *tex->colorband);
}
- else {
- continue;
- }
-
- DRW_shgroup_uniform_texture(grp, tex->shadername, gputex);
}
GPUUniformBuffer *ubo = GPU_material_uniform_buffer_get(material);
diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl
index 6605e1165d4..cfe79cb3ee0 100644
--- a/source/blender/draw/intern/shaders/common_view_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_view_lib.glsl
@@ -164,6 +164,7 @@ uniform mat4 ModelMatrixInverse;
#define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n)
#define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n)
#define normal_world_to_view(n) (mat3(ViewMatrix) * n)
+#define normal_view_to_world(n) (mat3(ViewMatrixInverse) * n)
#define point_object_to_ndc(p) (ViewProjectionMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0))
#define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz)
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index a9ddc53e5bb..5a0e60f8d58 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -2996,7 +2996,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m
*/
if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
/* layer visibility - we check both object and base, since these may not be in sync yet */
- if ((base->flag & BASE_VISIBLE_DEPSGRAPH) == 0) {
+ if ((base->flag & BASE_VISIBLE_DEPSGRAPH) == 0 || (base->flag & BASE_VISIBLE_VIEWLAYER) == 0) {
return false;
}
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
index 5ff76d886c2..4490892695f 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
@@ -91,7 +91,7 @@ static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], f
static bool gizmo_calc_rect_view_margin(const wmGizmo *gz, const float dims[2], float margin[2])
{
float handle_size;
- handle_size = 0.15f;
+ handle_size = 10.0f;
handle_size *= gz->scale_final;
float scale_xy[2];
if (!gizmo_calc_rect_view_scale(gz, dims, scale_xy)) {
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index e6d8684a8b2..d78c2620253 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -24,15 +24,21 @@
#ifndef __ED_IMAGE_H__
#define __ED_IMAGE_H__
+#include "DNA_listBase.h"
+#include "DNA_space_types.h"
+
struct ARegion;
struct ImBuf;
struct Image;
struct ImageUser;
+struct LinkNodePair;
+struct Main;
struct ReportList;
struct Scene;
struct SpaceImage;
struct ViewLayer;
struct bContext;
+struct wmOperator;
struct wmWindowManager;
/* image_edit.c, exported for transform */
@@ -116,4 +122,24 @@ bool ED_image_should_save_modified(const struct bContext *C);
int ED_image_save_all_modified_info(const struct bContext *C, struct ReportList *reports);
bool ED_image_save_all_modified(const struct bContext *C, struct ReportList *reports);
+/* image_sequence.c */
+typedef struct ImageFrameRange {
+ struct ImageFrameRange *next, *prev;
+
+ /** Absolute file path of the first file in the range. */
+ char filepath[FILE_MAX];
+ /* Sequence parameters. */
+ int length;
+ int offset;
+ /* UDIM tiles. */
+ ListBase udim_tiles;
+
+ /* Temporary data. */
+ ListBase frames;
+} ImageFrameRange;
+
+ListBase ED_image_filesel_detect_sequences(struct Main *bmain,
+ struct wmOperator *op,
+ const bool detect_udim);
+
#endif /* __ED_IMAGE_H__ */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index c66967a9365..d53ad7c4229 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -153,7 +153,6 @@ int BIF_countTransformOrientation(const struct bContext *C);
#define P_GPENCIL_EDIT (1 << 13)
#define P_CURSOR_EDIT (1 << 14)
#define P_CLNOR_INVALIDATE (1 << 15)
-#define P_MOUSE (1 << 16)
void Transform_Properties(struct wmOperatorType *ot, int flags);
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 5c9fb866df7..5f948595a22 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -35,6 +35,7 @@
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_object.h"
#include "ED_mesh.h"
#include "ED_screen.h"
@@ -80,8 +81,8 @@ void paintface_flush_flags(struct bContext *C, Object *ob, short flag)
return;
}
- Mesh *me_orig = ob_eval->runtime.mesh_orig;
- Mesh *me_eval = ob_eval->runtime.mesh_eval;
+ Mesh *me_orig = (Mesh *)ob_eval->runtime.data_orig;
+ Mesh *me_eval = (Mesh *)ob_eval->runtime.data_eval;
bool updated = false;
if (me_orig != NULL && me_eval != NULL && me_orig->totpoly == me->totpoly) {
@@ -443,7 +444,7 @@ bool paintface_mouse_select(
void paintvert_flush_flags(Object *ob)
{
Mesh *me = BKE_mesh_from_object(ob);
- Mesh *me_eval = ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
MVert *mvert_eval, *mv;
const int *index_array = NULL;
int totvert;
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index 8d5c1469694..21de89d33dd 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -33,6 +33,7 @@
#include "BKE_curve.h"
#include "BKE_editmesh.h"
#include "BKE_mesh_runtime.h"
+#include "BKE_object.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
@@ -61,9 +62,9 @@ static LinkNode *knifeproject_poly_from_object(const bContext *C,
struct Mesh *me_eval;
bool me_eval_needs_free;
- if (ob->type == OB_MESH || ob->runtime.mesh_eval) {
+ if (ob->type == OB_MESH || ob->runtime.data_eval) {
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- me_eval = ob_eval->runtime.mesh_eval;
+ me_eval = BKE_object_get_evaluated_mesh(ob_eval);
if (me_eval == NULL) {
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);
me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 7891f59a62e..a8eaa663285 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -410,45 +410,54 @@ bool ED_object_add_generic_get_opts(bContext *C,
rot = _rot;
}
- prop = RNA_struct_find_property(op->ptr, "align");
- int alignment = RNA_property_enum_get(op->ptr, prop);
- bool alignment_set = RNA_property_is_set(op->ptr, prop);
-
if (RNA_struct_property_is_set(op->ptr, "rotation")) {
+ /* If rotation is set, always use it. Alignment (and corresponding user preference)
+ * can be ignored since this is in world space anyways.
+ * To not confuse (e.g. on redo), dont set it to ALIGN_WORLD in the op UI though. */
*is_view_aligned = false;
- RNA_property_enum_set(op->ptr, prop, ALIGN_WORLD);
- alignment = ALIGN_WORLD;
- }
- else if (alignment_set) {
- *is_view_aligned = alignment == ALIGN_VIEW;
+ RNA_float_get_array(op->ptr, "rotation", rot);
}
else {
- *is_view_aligned = (U.flag & USER_ADD_VIEWALIGNED) != 0;
- if (*is_view_aligned) {
- RNA_property_enum_set(op->ptr, prop, ALIGN_VIEW);
- alignment = ALIGN_VIEW;
+ int alignment = ALIGN_WORLD;
+ prop = RNA_struct_find_property(op->ptr, "align");
+
+ if (RNA_property_is_set(op->ptr, prop)) {
+ /* If alignment is set, always use it. */
+ *is_view_aligned = alignment == ALIGN_VIEW;
+ alignment = RNA_property_enum_get(op->ptr, prop);
}
- else if (U.flag & USER_ADD_CURSORALIGNED) {
- RNA_property_enum_set(op->ptr, prop, ALIGN_CURSOR);
- alignment = ALIGN_CURSOR;
+ else {
+ /* If alignment is not set, use User Preferences. */
+ *is_view_aligned = (U.flag & USER_ADD_VIEWALIGNED) != 0;
+ if (*is_view_aligned) {
+ RNA_property_enum_set(op->ptr, prop, ALIGN_VIEW);
+ alignment = ALIGN_VIEW;
+ }
+ else if ((U.flag & USER_ADD_CURSORALIGNED) != 0) {
+ RNA_property_enum_set(op->ptr, prop, ALIGN_CURSOR);
+ alignment = ALIGN_CURSOR;
+ }
+ else {
+ RNA_property_enum_set(op->ptr, prop, ALIGN_WORLD);
+ alignment = ALIGN_WORLD;
+ }
}
- }
-
- switch (alignment) {
- case ALIGN_WORLD:
- RNA_float_get_array(op->ptr, "rotation", rot);
- break;
- case ALIGN_VIEW:
- ED_object_rotation_from_view(C, rot, view_align_axis);
- RNA_float_set_array(op->ptr, "rotation", rot);
- break;
- case ALIGN_CURSOR: {
- const Scene *scene = CTX_data_scene(C);
- float tmat[3][3];
- BKE_scene_cursor_rot_to_mat3(&scene->cursor, tmat);
- mat3_normalized_to_eul(rot, tmat);
- RNA_float_set_array(op->ptr, "rotation", rot);
- break;
+ switch (alignment) {
+ case ALIGN_WORLD:
+ RNA_float_get_array(op->ptr, "rotation", rot);
+ break;
+ case ALIGN_VIEW:
+ ED_object_rotation_from_view(C, rot, view_align_axis);
+ RNA_float_set_array(op->ptr, "rotation", rot);
+ break;
+ case ALIGN_CURSOR: {
+ const Scene *scene = CTX_data_scene(C);
+ float tmat[3][3];
+ BKE_scene_cursor_rot_to_mat3(&scene->cursor, tmat);
+ mat3_normalized_to_eul(rot, tmat);
+ RNA_float_set_array(op->ptr, "rotation", rot);
+ break;
+ }
}
}
}
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 906a9e44870..bfff36bb83a 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -871,118 +871,31 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot)
/* ------------- Child-Of Constraint ------------------ */
-static void child_get_inverse_matrix_owner_bone(
- Depsgraph *depsgraph, wmOperator *op, Scene *scene, Object *ob, float invmat[4][4])
+/* Force evaluation so that the 'set inverse' flag is handled.
+ * No-op when the constraint is enabled, as in such cases the evaluation will happen anyway.
+ */
+static void force_evaluation_if_constraint_disabled(bContext *C, Object *ob, bConstraint *con)
{
- /* For bone owner we want to do this in evaluated domain.
- * BKE_pose_where_is / BKE_pose_where_is_bone relies on (re)evaluating parts of the scene
- * and copying new evaluated stuff back to original.
- */
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- bConstraint *con_eval = edit_constraint_property_get(op, ob_eval, CONSTRAINT_TYPE_CHILDOF);
-
- /* nullify inverse matrix first */
- unit_m4(invmat);
-
- bPoseChannel *pchan_eval = BKE_pose_channel_active(ob_eval);
-
- /* try to find a pose channel - assume that this is the constraint owner */
- /* TODO: get from context instead? */
- if (ob_eval && ob_eval->pose && pchan_eval) {
- bConstraint *con_last;
-
- /* calculate/set inverse matrix:
- * We just calculate all transform-stack eval up to but not including this constraint.
- * This is because inverse should just inverse correct for just the constraint's influence
- * when it gets applied; that is, at the time of application, we don't know anything about
- * what follows.
- */
- float imat[4][4], tmat[4][4];
- float pmat[4][4];
-
- /* make sure we passed the correct constraint */
- BLI_assert(BLI_findindex(&pchan_eval->constraints, con_eval) != -1);
-
- /* 1. calculate posemat where inverse doesn't exist yet (inverse was cleared above),
- * to use as baseline ("pmat") to derive delta from. This extra calc saves users
- * from having pressing "Clear Inverse" first
- */
- BKE_pose_where_is(depsgraph, scene, ob_eval);
- copy_m4_m4(pmat, pchan_eval->pose_mat);
-
- /* 2. knock out constraints starting from this one */
- con_last = pchan_eval->constraints.last;
- pchan_eval->constraints.last = con_eval->prev;
-
- if (con_eval->prev) {
- /* new end must not point to this one, else this chain cutting is useless */
- con_eval->prev->next = NULL;
- }
- else {
- /* constraint was first */
- pchan_eval->constraints.first = NULL;
- }
-
- /* 3. solve pose without disabled constraints */
- BKE_pose_where_is(depsgraph, scene, ob_eval);
-
- /* 4. determine effect of constraint by removing the newly calculated
- * pchan->pose_mat from the original pchan->pose_mat, thus determining
- * the effect of the constraint
- */
- invert_m4_m4(imat, pchan_eval->pose_mat);
- mul_m4_m4m4(tmat, pmat, imat);
- invert_m4_m4(invmat, tmat);
-
- /* 5. restore constraints */
- pchan_eval->constraints.last = con_last;
-
- if (con_eval->prev) {
- /* hook up prev to this one again */
- con_eval->prev->next = con_eval;
- }
- else {
- /* set as first again */
- pchan_eval->constraints.first = con_eval;
- }
-
- /* 6. recalculate pose with new inv-mat applied */
- /* this one is unnecessary? (DEG seems to update correctly without)
- + if we leave this in, we have to click "Set Inverse" twice to see updates...
- BKE_pose_where_is(depsgraph, scene, ob_eval); */
+ if ((con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) == 0) {
+ return;
}
-}
-
-static void child_get_inverse_matrix_owner_object(
- Depsgraph *depsgraph, Scene *scene, Object *ob, bConstraint *con, float invmat[4][4])
-{
- /* nullify inverse matrix first */
- unit_m4(invmat);
-
- if (ob) {
- Object workob;
-
- /* make sure we passed the correct constraint */
- BLI_assert(BLI_findindex(&ob->constraints, con) != -1);
- UNUSED_VARS_NDEBUG(con);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
- /* use BKE_object_workob_calc_parent to find inverse - just like for normal parenting */
- BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- invert_m4_m4(invmat, workob.obmat);
- }
+ short flag_backup = con->flag;
+ con->flag &= ~(CONSTRAINT_DISABLE | CONSTRAINT_OFF);
+ BKE_object_eval_constraints(depsgraph, scene, ob);
+ con->flag = flag_backup;
}
/* ChildOf Constraint - set inverse callback */
static int childof_set_inverse_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF);
bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL;
- const int owner = RNA_enum_get(op->ptr, "owner");
/* despite 3 layers of checks, we may still not be able to find a constraint */
if (data == NULL) {
@@ -991,12 +904,11 @@ static int childof_set_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (owner == EDIT_CONSTRAINT_OWNER_OBJECT) {
- child_get_inverse_matrix_owner_object(depsgraph, scene, ob, con, data->invmat);
- }
- else if (owner == EDIT_CONSTRAINT_OWNER_BONE) {
- child_get_inverse_matrix_owner_bone(depsgraph, op, scene, ob, data->invmat);
- }
+ /* Set a flag to request recalculation on next update. */
+ data->flag |= CHILDOF_SET_INVERSE;
+
+ /* Force constraint to run, it will perform the recalculation. */
+ force_evaluation_if_constraint_disabled(C, ob, con);
ED_object_constraint_update(bmain, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
@@ -1231,12 +1143,9 @@ void CONSTRAINT_OT_followpath_path_animate(wmOperatorType *ot)
static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER);
bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL;
- const int owner = RNA_enum_get(op->ptr, "owner");
/* despite 3 layers of checks, we may still not be able to find a constraint */
if (data == NULL) {
@@ -1246,12 +1155,11 @@ static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (owner == EDIT_CONSTRAINT_OWNER_OBJECT) {
- child_get_inverse_matrix_owner_object(depsgraph, scene, ob, con, data->invmat);
- }
- else if (owner == EDIT_CONSTRAINT_OWNER_BONE) {
- child_get_inverse_matrix_owner_bone(depsgraph, op, scene, ob, data->invmat);
- }
+ /* Set a flag to request recalculation on next update. */
+ data->flag |= OBJECTSOLVER_SET_INVERSE;
+
+ /* Force constraint to run, it will perform the recalculation. */
+ force_evaluation_if_constraint_disabled(C, ob, con);
ED_object_constraint_update(bmain, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 92e76ab31fa..49b6acc9003 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -488,7 +488,8 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
static bool PE_create_shape_tree(PEData *data, Object *shapeob)
{
- Mesh *mesh = BKE_object_get_evaluated_mesh(data->depsgraph, shapeob);
+ Object *shapeob_eval = DEG_get_evaluated_object(data->depsgraph, shapeob);
+ Mesh *mesh = BKE_object_get_evaluated_mesh(shapeob_eval);
memset(&data->shape_bvh, 0, sizeof(data->shape_bvh));
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 8c8fc412663..e58183bfc0f 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -1062,7 +1062,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
keymap->poll = weight_paint_mode_poll;
/*Weight paint's Vertex Selection Mode */
- keymap = WM_keymap_ensure(keyconf, "Weight Paint Vertex Selection", 0, 0);
+ keymap = WM_keymap_ensure(keyconf, "Paint Vertex Selection (Weight, Vertex)", 0, 0);
keymap->poll = vert_paint_poll;
/* Image/Texture Paint mode */
@@ -1070,7 +1070,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
keymap->poll = image_texture_paint_poll;
/* face-mask mode */
- keymap = WM_keymap_ensure(keyconf, "Face Mask", 0, 0);
+ keymap = WM_keymap_ensure(keyconf, "Paint Face Mask (Weight, Vertex, Texture)", 0, 0);
keymap->poll = facemask_paint_poll;
/* paint stroke */
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 7372ea6d44a..6971182e5b8 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -181,7 +181,7 @@ static MDeformVert *defweight_prev_init(MDeformVert *dvert_prev,
* (without evaluating modifiers) */
static bool vertex_paint_use_fast_update_check(Object *ob)
{
- Mesh *me_eval = ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
if (me_eval != NULL) {
Mesh *me = BKE_mesh_from_object(ob);
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 28e6d95beb3..9defff74c6f 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -2181,8 +2181,17 @@ int ED_path_extension_type(const char *path)
else if (BLI_path_extension_check(path, ".py")) {
return FILE_TYPE_PYSCRIPT;
}
- else if (BLI_path_extension_check_n(
- path, ".txt", ".glsl", ".osl", ".data", ".pov", ".ini", ".mcr", ".inc", NULL)) {
+ else if (BLI_path_extension_check_n(path,
+ ".txt",
+ ".glsl",
+ ".osl",
+ ".data",
+ ".pov",
+ ".ini",
+ ".mcr",
+ ".inc",
+ ".fountain",
+ NULL)) {
return FILE_TYPE_TEXT;
}
else if (BLI_path_extension_check_n(path, ".ttf", ".ttc", ".pfb", ".otf", ".otc", NULL)) {
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 94747e79c84..dcd348706d6 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -115,8 +115,9 @@ struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory
*/
static GHash *fsmenu_xdg_user_dirs_parse(const char *home)
{
- size_t data_len;
- char *data;
+ /* Add to the default for variable, equals & quotes. */
+ char l[128 + FILE_MAXDIR];
+ FILE *fp;
/* Check if the config file exists. */
{
@@ -128,17 +129,14 @@ static GHash *fsmenu_xdg_user_dirs_parse(const char *home)
else {
BLI_path_join(filepath, sizeof(filepath), home, ".config", "user-dirs.dirs", NULL);
}
- data = BLI_file_read_text_as_mem_with_newline_as_nil(filepath, true, 1, &data_len);
- if (data == NULL) {
+ fp = BLI_fopen(filepath, "r");
+ if (!fp) {
return NULL;
}
}
/* By default there are 8 paths. */
GHash *xdg_map = BLI_ghash_str_new_ex(__func__, 8);
- char *data_end = data + data_len;
- uint l_len;
- for (char *l = data; l != data_end; l += l_len + 1) {
- l_len = strlen(l);
+ while (fgets(l, sizeof(l), fp) != NULL) { /* read a line */
/* Avoid inserting invalid values. */
if (STRPREFIX(l, "XDG_")) {
@@ -146,9 +144,12 @@ static GHash *fsmenu_xdg_user_dirs_parse(const char *home)
if (l_value != NULL) {
*l_value = '\0';
l_value++;
- if (*l_value == '"' && l[l_len - 1] == '"') {
+
+ BLI_str_rstrip(l_value);
+ const uint l_value_len = strlen(l_value);
+ if ((l_value[0] == '"') && (l_value_len > 0) && (l_value[l_value_len - 1] == '"')) {
l_value++;
- l[l_len - 1] = '\0';
+ l_value[l_value_len - 1] = '\0';
char l_value_expanded[FILE_MAX];
char *l_value_final = l_value;
@@ -166,7 +167,6 @@ static GHash *fsmenu_xdg_user_dirs_parse(const char *home)
}
}
}
- MEM_freeN(data);
return xdg_map;
}
diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt
index 5abcff436f1..12de74c6ae7 100644
--- a/source/blender/editors/space_image/CMakeLists.txt
+++ b/source/blender/editors/space_image/CMakeLists.txt
@@ -43,6 +43,7 @@ set(SRC
image_draw.c
image_edit.c
image_ops.c
+ image_sequence.c
image_undo.c
space_image.c
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index f4688ce17fd..54bd2f37f3a 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -985,7 +985,7 @@ void uiTemplateImage(uiLayout *layout,
void *lock;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
- if (ibuf->rect_float && (ibuf->flags & IB_halffloat) == 0) {
+ if (ibuf && ibuf->rect_float && (ibuf->flags & IB_halffloat) == 0) {
uiItemR(col, &imaptr, "use_half_precision", 0, NULL, ICON_NONE);
}
BKE_image_release_ibuf(ima, ibuf, lock);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index a3fa03b18b7..fe1cb1ead9e 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1207,18 +1207,6 @@ typedef struct ImageOpenData {
ImageFormatData im_format;
} ImageOpenData;
-typedef struct ImageFrameRange {
- struct ImageFrameRange *next, *prev;
- ListBase frames;
- /** The full path of the first file in the list of image files */
- char filepath[FILE_MAX];
-} ImageFrameRange;
-
-typedef struct ImageFrame {
- struct ImageFrame *next, *prev;
- int framenr;
-} ImageFrame;
-
static void image_open_init(bContext *C, wmOperator *op)
{
ImageOpenData *iod;
@@ -1233,179 +1221,18 @@ static void image_open_cancel(bContext *UNUSED(C), wmOperator *op)
op->customdata = NULL;
}
-/**
- * Get a list of frames from the list of image files matching the first file name sequence pattern.
- * \param ptr[in]: The RNA pointer containing the "directory" entry and "files" collection.
- * \param frames_all[out]: the list of frame numbers found in the files matching
- * the first one by name.
- */
-static void image_sequence_get_frame_ranges(PointerRNA *ptr, ListBase *frames_all)
-{
- char dir[FILE_MAXDIR];
- const bool do_frame_range = RNA_boolean_get(ptr, "use_sequence_detection");
- ImageFrameRange *frame_range = NULL;
-
- RNA_string_get(ptr, "directory", dir);
- RNA_BEGIN (ptr, itemptr, "files") {
- char base_head[FILE_MAX], base_tail[FILE_MAX];
- char head[FILE_MAX], tail[FILE_MAX];
- unsigned short digits;
- char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
- ImageFrame *frame = MEM_callocN(sizeof(ImageFrame), "image_frame");
-
- /* use the first file in the list as base filename */
- frame->framenr = BLI_stringdec(filename, head, tail, &digits);
-
- /* still in the same sequence */
- if (do_frame_range && (frame_range != NULL) && (STREQLEN(base_head, head, FILE_MAX)) &&
- (STREQLEN(base_tail, tail, FILE_MAX))) {
- /* pass */
- }
- else {
- /* start a new frame range */
- frame_range = MEM_callocN(sizeof(*frame_range), __func__);
- BLI_join_dirfile(frame_range->filepath, sizeof(frame_range->filepath), dir, filename);
- BLI_addtail(frames_all, frame_range);
-
- BLI_strncpy(base_head, head, sizeof(base_head));
- BLI_strncpy(base_tail, tail, sizeof(base_tail));
- }
-
- BLI_addtail(&frame_range->frames, frame);
- MEM_freeN(filename);
- }
- RNA_END;
-}
-
-static int image_cmp_frame(const void *a, const void *b)
-{
- const ImageFrame *frame_a = a;
- const ImageFrame *frame_b = b;
-
- if (frame_a->framenr < frame_b->framenr) {
- return -1;
- }
- if (frame_a->framenr > frame_b->framenr) {
- return 1;
- }
- return 0;
-}
-
-/* Checks whether the given filepath refers to a UDIM texture.
- * If yes, the range from 1001 to the highest tile is returned, otherwise 0.
- *
- * If the result is positive, the filepath will be overwritten with that of
- * the 1001 tile.
- * udim_tiles may get filled even if the result ultimately is false! */
-static int image_get_udim(char *filepath, LinkNodePair *udim_tiles)
-{
- char filename[FILE_MAX], dirname[FILE_MAXDIR];
- BLI_split_dirfile(filepath, dirname, filename, sizeof(dirname), sizeof(filename));
-
- unsigned short digits;
- char base_head[FILE_MAX], base_tail[FILE_MAX];
- int id = BLI_stringdec(filename, base_head, base_tail, &digits);
-
- if (id < 1001 || id >= IMA_UDIM_MAX) {
- return 0;
- }
-
- bool is_udim = true;
- bool has_primary = false;
- int max_udim = 0;
-
- struct direntry *dir;
- uint totfile = BLI_filelist_dir_contents(dirname, &dir);
- for (int i = 0; i < totfile; i++) {
- if (!(dir[i].type & S_IFREG)) {
- continue;
- }
- char head[FILE_MAX], tail[FILE_MAX];
- id = BLI_stringdec(dir[i].relname, head, tail, &digits);
-
- if (digits > 4 || !(STREQLEN(base_head, head, FILE_MAX)) ||
- !(STREQLEN(base_tail, tail, FILE_MAX))) {
- continue;
- }
-
- if (id < 1001 || id >= IMA_UDIM_MAX) {
- is_udim = false;
- break;
- }
- if (id == 1001) {
- has_primary = true;
- }
-
- BLI_linklist_append(udim_tiles, POINTER_FROM_INT(id));
- max_udim = max_ii(max_udim, id);
- }
- BLI_filelist_free(dir, totfile);
-
- if (is_udim && has_primary) {
- char primary_filename[FILE_MAX];
- BLI_stringenc(primary_filename, base_head, base_tail, digits, 1001);
- BLI_join_dirfile(filepath, FILE_MAX, dirname, primary_filename);
- return max_udim - 1000;
- }
- return 0;
-}
-
-/**
- * Return the start (offset) and the length of the sequence of
- * continuous frames in the list of frames.
- *
- * \param frames: [in] the list of frame numbers, as a side-effect the list is sorted.
- * \param ofs: [out] offset the first frame number in the sequence.
- * \return the number of contiguous frames in the sequence
- */
-static int image_sequence_get_len(ImageFrameRange *frame_range,
- int *ofs,
- char *filepath_range,
- LinkNodePair *udim_tiles)
-{
- ImageFrame *frame;
-
- BLI_listbase_sort(&frame_range->frames, image_cmp_frame);
- BLI_strncpy(filepath_range, frame_range->filepath, FILE_MAX);
-
- frame = frame_range->frames.first;
- if (frame != NULL) {
- int frame_curr = frame->framenr;
- (*ofs) = frame_curr;
-
- if (udim_tiles != NULL) {
- int len_udim = image_get_udim(filepath_range, udim_tiles);
- if (len_udim > 0) {
- *ofs = 1001;
- return len_udim;
- }
- }
-
- while (frame != NULL && (frame->framenr == frame_curr)) {
- frame_curr++;
- frame = frame->next;
- }
- return frame_curr - (*ofs);
- }
- *ofs = 0;
- return 0;
-}
-
static Image *image_open_single(Main *bmain,
wmOperator *op,
- const char *filepath,
+ ImageFrameRange *range,
const char *relbase,
bool is_relative_path,
- bool use_multiview,
- int frame_seq_len,
- int frame_seq_ofs,
- LinkNodePair *udim_tiles)
+ bool use_multiview)
{
bool exists = false;
Image *ima = NULL;
errno = 0;
- ima = BKE_image_load_exists_ex(bmain, filepath, &exists);
+ ima = BKE_image_load_exists_ex(bmain, range->filepath, &exists);
if (!ima) {
if (op->customdata) {
@@ -1414,7 +1241,7 @@ static Image *image_open_single(Main *bmain,
BKE_reportf(op->reports,
RPT_ERROR,
"Cannot read '%s': %s",
- filepath,
+ range->filepath,
errno ? strerror(errno) : TIP_("unsupported image format"));
return NULL;
}
@@ -1439,11 +1266,11 @@ static Image *image_open_single(Main *bmain,
BKE_image_free_views(ima);
}
- if ((frame_seq_len > 1) && (ima->source == IMA_SRC_FILE)) {
- if (udim_tiles && frame_seq_ofs == 1001) {
+ if ((range->length > 1) && (ima->source == IMA_SRC_FILE)) {
+ if (range->udim_tiles.first && range->offset == 1001) {
ima->source = IMA_SRC_TILED;
- for (LinkNode *node = udim_tiles->list; node; node = node->next) {
- BKE_image_add_tile(ima, POINTER_AS_INT(node->link), NULL);
+ for (LinkData *node = range->udim_tiles.first; node; node = node->next) {
+ BKE_image_add_tile(ima, POINTER_AS_INT(node->data), NULL);
}
}
else {
@@ -1464,7 +1291,6 @@ static int image_open_exec(bContext *C, wmOperator *op)
ImageUser *iuser = NULL;
ImageOpenData *iod = op->customdata;
Image *ima = NULL;
- char filepath[FILE_MAX];
int frame_seq_len = 0;
int frame_ofs = 1;
@@ -1476,83 +1302,21 @@ static int image_open_exec(bContext *C, wmOperator *op)
image_open_init(C, op);
}
- RNA_string_get(op->ptr, "filepath", filepath);
-
- if (RNA_struct_property_is_set(op->ptr, "directory") &&
- RNA_struct_property_is_set(op->ptr, "files")) {
- bool was_relative = BLI_path_is_rel(filepath);
- ListBase frame_ranges_all;
-
- BLI_listbase_clear(&frame_ranges_all);
- image_sequence_get_frame_ranges(op->ptr, &frame_ranges_all);
- for (ImageFrameRange *frame_range = frame_ranges_all.first; frame_range;
- frame_range = frame_range->next) {
- int frame_range_ofs;
-
- LinkNodePair udim_tiles = {NULL};
- LinkNodePair *udim_tiles_ptr = use_udim ? (&udim_tiles) : NULL;
-
- char filepath_range[FILE_MAX];
- int frame_range_seq_len = image_sequence_get_len(
- frame_range, &frame_range_ofs, filepath_range, udim_tiles_ptr);
- BLI_freelistN(&frame_range->frames);
-
- if (was_relative) {
- BLI_path_rel(filepath_range, BKE_main_blendfile_path(bmain));
- }
-
- Image *ima_range = image_open_single(bmain,
- op,
- filepath_range,
- BKE_main_blendfile_path(bmain),
- is_relative_path,
- use_multiview,
- frame_range_seq_len,
- frame_range_ofs,
- udim_tiles_ptr);
-
- /* take the first image */
- if ((ima == NULL) && ima_range) {
- ima = ima_range;
- frame_seq_len = frame_range_seq_len;
- frame_ofs = frame_range_ofs;
- }
+ ListBase ranges = ED_image_filesel_detect_sequences(bmain, op, use_udim);
+ for (ImageFrameRange *range = ranges.first; range; range = range->next) {
+ Image *ima_range = image_open_single(
+ bmain, op, range, BKE_main_blendfile_path(bmain), is_relative_path, use_multiview);
- BLI_linklist_free(udim_tiles.list, NULL);
+ /* take the first image */
+ if ((ima == NULL) && ima_range) {
+ ima = ima_range;
+ frame_seq_len = range->length;
+ frame_ofs = range->offset;
}
- BLI_freelistN(&frame_ranges_all);
- }
- else {
- /* for drag & drop etc. */
-
- LinkNodePair udim_tiles = {NULL};
- frame_seq_len = 1;
- char filepath_range[FILE_MAX];
- BLI_strncpy(filepath_range, filepath, FILE_MAX);
-
- if (use_udim > 0) {
- /* Try to find UDIM tiles corresponding to the image */
- int udim_len = image_get_udim(filepath_range, &udim_tiles);
-
- /* If we found something, mark the image as tiled. */
- if (udim_len) {
- frame_seq_len = udim_len;
- frame_ofs = 1001;
- }
- }
-
- ima = image_open_single(bmain,
- op,
- filepath_range,
- BKE_main_blendfile_path(bmain),
- is_relative_path,
- use_multiview,
- frame_seq_len,
- frame_ofs,
- &udim_tiles);
- BLI_linklist_free(udim_tiles.list, NULL);
+ BLI_freelistN(&range->udim_tiles);
}
+ BLI_freelistN(&ranges);
if (ima == NULL) {
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_image/image_sequence.c b/source/blender/editors/space_image/image_sequence.c
new file mode 100644
index 00000000000..09e717621d8
--- /dev/null
+++ b/source/blender/editors/space_image/image_sequence.c
@@ -0,0 +1,249 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup spimage
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_fileops.h"
+#include "BLI_fileops_types.h"
+#include "BLI_linklist.h"
+#include "BLI_listbase.h"
+#include "BLI_math_base.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_image_types.h"
+#include "DNA_space_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "RNA_access.h"
+
+#include "BKE_image.h"
+#include "BKE_main.h"
+
+#include "ED_image.h"
+
+#include "WM_types.h"
+
+typedef struct ImageFrame {
+ struct ImageFrame *next, *prev;
+ int framenr;
+} ImageFrame;
+
+/**
+ * Get a list of frames from the list of image files matching the first file
+ * name sequence pattern. The files and directory are read from standard
+ * fileselect operator properties.
+ *
+ * The output is a list of frame ranges, each containg a list of frames with
+ * matching names.
+ */
+static void image_sequence_get_frame_ranges(wmOperator *op, ListBase *ranges)
+{
+ char dir[FILE_MAXDIR];
+ const bool do_frame_range = RNA_boolean_get(op->ptr, "use_sequence_detection");
+ ImageFrameRange *range = NULL;
+
+ RNA_string_get(op->ptr, "directory", dir);
+ RNA_BEGIN (op->ptr, itemptr, "files") {
+ char base_head[FILE_MAX], base_tail[FILE_MAX];
+ char head[FILE_MAX], tail[FILE_MAX];
+ unsigned short digits;
+ char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
+ ImageFrame *frame = MEM_callocN(sizeof(ImageFrame), "image_frame");
+
+ /* use the first file in the list as base filename */
+ frame->framenr = BLI_stringdec(filename, head, tail, &digits);
+
+ /* still in the same sequence */
+ if (do_frame_range && (range != NULL) && (STREQLEN(base_head, head, FILE_MAX)) &&
+ (STREQLEN(base_tail, tail, FILE_MAX))) {
+ /* pass */
+ }
+ else {
+ /* start a new frame range */
+ range = MEM_callocN(sizeof(*range), __func__);
+ BLI_join_dirfile(range->filepath, sizeof(range->filepath), dir, filename);
+ BLI_addtail(ranges, range);
+
+ BLI_strncpy(base_head, head, sizeof(base_head));
+ BLI_strncpy(base_tail, tail, sizeof(base_tail));
+ }
+
+ BLI_addtail(&range->frames, frame);
+ MEM_freeN(filename);
+ }
+ RNA_END;
+}
+
+static int image_cmp_frame(const void *a, const void *b)
+{
+ const ImageFrame *frame_a = a;
+ const ImageFrame *frame_b = b;
+
+ if (frame_a->framenr < frame_b->framenr) {
+ return -1;
+ }
+ if (frame_a->framenr > frame_b->framenr) {
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Checks whether the given filepath refers to a UDIM texture.
+ * If yes, the range from 1001 to the highest tile is returned, otherwise 0.
+ *
+ * If the result is positive, the filepath will be overwritten with that of
+ * the 1001 tile.
+ *
+ * udim_tiles may get filled even if the result ultimately is false!
+ */
+static int image_get_udim(char *filepath, ListBase *udim_tiles)
+{
+ char filename[FILE_MAX], dirname[FILE_MAXDIR];
+ BLI_split_dirfile(filepath, dirname, filename, sizeof(dirname), sizeof(filename));
+
+ unsigned short digits;
+ char base_head[FILE_MAX], base_tail[FILE_MAX];
+ int id = BLI_stringdec(filename, base_head, base_tail, &digits);
+
+ if (id < 1001 || id >= IMA_UDIM_MAX) {
+ return 0;
+ }
+
+ bool is_udim = true;
+ bool has_primary = false;
+ int max_udim = 0;
+
+ struct direntry *dir;
+ uint totfile = BLI_filelist_dir_contents(dirname, &dir);
+ for (int i = 0; i < totfile; i++) {
+ if (!(dir[i].type & S_IFREG)) {
+ continue;
+ }
+ char head[FILE_MAX], tail[FILE_MAX];
+ id = BLI_stringdec(dir[i].relname, head, tail, &digits);
+
+ if (digits > 4 || !(STREQLEN(base_head, head, FILE_MAX)) ||
+ !(STREQLEN(base_tail, tail, FILE_MAX))) {
+ continue;
+ }
+
+ if (id < 1001 || id >= IMA_UDIM_MAX) {
+ is_udim = false;
+ break;
+ }
+ if (id == 1001) {
+ has_primary = true;
+ }
+
+ BLI_addtail(udim_tiles, BLI_genericNodeN(POINTER_FROM_INT(id)));
+ max_udim = max_ii(max_udim, id);
+ }
+ BLI_filelist_free(dir, totfile);
+
+ if (is_udim && has_primary) {
+ char primary_filename[FILE_MAX];
+ BLI_stringenc(primary_filename, base_head, base_tail, digits, 1001);
+ BLI_join_dirfile(filepath, FILE_MAX, dirname, primary_filename);
+ return max_udim - 1000;
+ }
+ return 0;
+}
+
+/**
+ * From a list of frames, compute the start (offset) and length of the sequence
+ * of contiguous frames. If UDIM is detect, it will return UDIM tiles as well.
+ */
+static void image_detect_frame_range(ImageFrameRange *range, const bool detect_udim)
+{
+ /* UDIM */
+ if (detect_udim) {
+ int len_udim = image_get_udim(range->filepath, &range->udim_tiles);
+
+ if (len_udim > 0) {
+ range->offset = 1001;
+ range->length = len_udim;
+ return;
+ }
+ }
+
+ /* Image Sequence */
+ BLI_listbase_sort(&range->frames, image_cmp_frame);
+
+ ImageFrame *frame = range->frames.first;
+ if (frame != NULL) {
+ int frame_curr = frame->framenr;
+ range->offset = frame_curr;
+
+ while (frame != NULL && (frame->framenr == frame_curr)) {
+ frame_curr++;
+ frame = frame->next;
+ }
+
+ range->length = frame_curr - range->offset;
+ }
+ else {
+ range->length = 1;
+ range->offset = 0;
+ }
+}
+
+/* Used for both images and volume file loading. */
+ListBase ED_image_filesel_detect_sequences(Main *bmain, wmOperator *op, const bool detect_udim)
+{
+ ListBase ranges;
+ BLI_listbase_clear(&ranges);
+
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
+
+ /* File browser. */
+ if (RNA_struct_property_is_set(op->ptr, "directory") &&
+ RNA_struct_property_is_set(op->ptr, "files")) {
+ const bool was_relative = BLI_path_is_rel(filepath);
+
+ image_sequence_get_frame_ranges(op, &ranges);
+ for (ImageFrameRange *range = ranges.first; range; range = range->next) {
+ image_detect_frame_range(range, detect_udim);
+ BLI_freelistN(&range->frames);
+
+ if (was_relative) {
+ BLI_path_rel(range->filepath, BKE_main_blendfile_path(bmain));
+ }
+ }
+ }
+ /* Filepath property for drag & drop etc. */
+ else {
+ ImageFrameRange *range = MEM_callocN(sizeof(*range), __func__);
+ BLI_addtail(&ranges, range);
+
+ BLI_strncpy(range->filepath, filepath, FILE_MAX);
+ image_detect_frame_range(range, detect_udim);
+ }
+
+ return ranges;
+}
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 225ca72a7d0..d00083d343b 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -137,7 +137,7 @@ static void stats_object(Object *ob, SceneStats *stats, GSet *objects_gset)
switch (ob->type) {
case OB_MESH: {
/* we assume evaluated mesh is already built, this strictly does stats now. */
- Mesh *me_eval = ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
if (!BLI_gset_add(objects_gset, me_eval)) {
break;
}
@@ -153,8 +153,7 @@ static void stats_object(Object *ob, SceneStats *stats, GSet *objects_gset)
case OB_SURF:
case OB_CURVE:
case OB_FONT: {
- Mesh *me_eval = ob->runtime.mesh_eval;
-
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
if ((me_eval != NULL) && !BLI_gset_add(objects_gset, me_eval)) {
break;
}
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 5cd2a86adf8..e5f6b25ee25 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -340,6 +340,8 @@ static void nla_region_listener(wmWindow *UNUSED(win),
case ND_OB_ACTIVE:
case ND_FRAME:
case ND_MARKERS:
+ case ND_LAYER_CONTENT:
+ case ND_OB_SELECT:
ED_region_tag_redraw(ar);
break;
}
@@ -349,6 +351,7 @@ static void nla_region_listener(wmWindow *UNUSED(win),
case ND_BONE_ACTIVE:
case ND_BONE_SELECT:
case ND_KEYS:
+ case ND_DRAW:
ED_region_tag_redraw(ar);
break;
}
@@ -379,6 +382,8 @@ static void nla_main_region_listener(wmWindow *UNUSED(win),
case ND_FRAME:
case ND_FRAME_RANGE:
case ND_MARKERS:
+ case ND_LAYER_CONTENT:
+ case ND_OB_SELECT:
ED_region_tag_redraw(ar);
break;
}
@@ -474,6 +479,8 @@ static void nla_channel_region_listener(wmWindow *UNUSED(win),
case NC_SCENE:
switch (wmn->data) {
case ND_OB_ACTIVE:
+ case ND_LAYER_CONTENT:
+ case ND_OB_SELECT:
ED_region_tag_redraw(ar);
break;
}
@@ -483,6 +490,7 @@ static void nla_channel_region_listener(wmWindow *UNUSED(win),
case ND_BONE_ACTIVE:
case ND_BONE_SELECT:
case ND_KEYS:
+ case ND_DRAW:
ED_region_tag_redraw(ar);
break;
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 0daa5aa53ae..00f61a4d0aa 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -28,9 +28,9 @@
#include "BLI_math.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_global.h"
-
#include "BKE_editmesh.h"
+#include "BKE_global.h"
+#include "BKE_object.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@@ -120,8 +120,9 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
Mesh *me = ob->data;
{
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- if (ob_eval->runtime.mesh_eval) {
- me = ob_eval->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ if (me_eval != NULL) {
+ me = me_eval;
}
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 9d84309d222..df743415fec 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -361,10 +361,10 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
/* object ops. */
/* important to be before Pose keymap since they can both be enabled at once */
- keymap = WM_keymap_ensure(wm->defaultconf, "Face Mask", 0, 0);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Paint Face Mask (Weight, Vertex, Texture)", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Weight Paint Vertex Selection", 0, 0);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Paint Vertex Selection (Weight, Vertex)", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
/* Before 'Pose' so weight paint menus aren't overridden by pose menus. */
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 06a4147e34d..4ff8a9a3884 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -98,7 +98,7 @@
#include "view3d_intern.h" /* own include */
-#define M_GOLDEN_RATION_CONJUGATE 0.618033988749895f
+#define M_GOLDEN_RATIO_CONJUGATE 0.618033988749895f
/* -------------------------------------------------------------------- */
/** \name General Functions
@@ -452,7 +452,7 @@ static void drawviewborder_triangle(
if (w > h) {
if (golden) {
- ofs = w * (1.0f - (1.0f / M_GOLDEN_RATION_CONJUGATE));
+ ofs = w * (1.0f - M_GOLDEN_RATIO_CONJUGATE);
}
else {
ofs = h * (h / w);
@@ -472,7 +472,7 @@ static void drawviewborder_triangle(
}
else {
if (golden) {
- ofs = h * (1.0f - (1.0f / M_GOLDEN_RATION_CONJUGATE));
+ ofs = h * (1.0f - M_GOLDEN_RATIO_CONJUGATE);
}
else {
ofs = w * (w / h);
@@ -662,7 +662,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View
}
if (ca->dtx & CAM_DTX_GOLDEN) {
- drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f - (1.0f / M_GOLDEN_RATION_CONJUGATE));
+ drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f - M_GOLDEN_RATIO_CONJUGATE);
}
if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index bc81817647e..ed42a0e35f3 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1635,9 +1635,9 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
}
- if ((prop = RNA_struct_find_property(op->ptr, "mouse_coordinate_override"))) {
+ if ((prop = RNA_struct_find_property(op->ptr, "center_override"))) {
/* Important for redo operations. */
- RNA_property_int_set_array(op->ptr, prop, t->mouse.imval);
+ RNA_property_float_set_array(op->ptr, prop, t->center_global);
}
if (t->flag & T_PROP_EDIT_ALL) {
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 027ae04795a..c2e3c8ef508 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -69,6 +69,8 @@
#include "ED_clip.h"
#include "ED_mask.h"
+#include "UI_view2d.h"
+
#include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */
#include "WM_types.h"
@@ -787,6 +789,28 @@ void clipUVData(TransInfo *t)
/* ********************* ANIMATION EDITORS (GENERAL) ************************* */
+/**
+ * For modal operation: `t->center_global` may not have been set yet.
+ */
+void transform_convert_center_global_v2(TransInfo *t, float r_center[2])
+{
+ if (t->flag & T_MODAL) {
+ UI_view2d_region_to_view(
+ (View2D *)t->view, t->mouse.imval[0], t->mouse.imval[1], &r_center[0], &r_center[1]);
+ }
+ else {
+ copy_v2_v2(r_center, t->center_global);
+ }
+}
+
+void transform_convert_center_global_v2_int(TransInfo *t, int r_center[2])
+{
+ float center[2];
+ transform_convert_center_global_v2(t, center);
+ r_center[0] = round_fl_to_int(center[0]);
+ r_center[1] = round_fl_to_int(center[1]);
+}
+
/* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
bool FrameOnMouseSide(char side, float frame, float cframe)
{
@@ -2514,7 +2538,7 @@ void createTransData(bContext *C, TransInfo *t)
t->obedit_type = -1;
t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point trasnform */
- createTransSeqData(C, t);
+ createTransSeqData(t);
countAndCleanTransDataContainer(t);
}
else if (t->spacetype == SPACE_GRAPH) {
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index 075bf0a5a4b..d616f24ba86 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -104,6 +104,8 @@ void transform_around_single_fallback(TransInfo *t);
bool constraints_list_needinv(TransInfo *t, ListBase *list);
void calc_distanceCurveVerts(TransData *head, TransData *tail);
struct TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTriple *bezt);
+void transform_convert_center_global_v2(TransInfo *t, float r_center[2]);
+void transform_convert_center_global_v2_int(TransInfo *t, int r_center[2]);
bool FrameOnMouseSide(char side, float frame, float cframe);
/* transform_convert_action.c */
@@ -162,7 +164,7 @@ void createTransParticleVerts(bContext *C, TransInfo *t);
void createTransSculpt(TransInfo *t);
/* transform_convert_sequence.c */
-void createTransSeqData(bContext *C, TransInfo *t);
+void createTransSeqData(TransInfo *t);
/* transform_convert_tracking.c */
void createTransTrackingData(bContext *C, TransInfo *t);
diff --git a/source/blender/editors/transform/transform_convert_action.c b/source/blender/editors/transform/transform_convert_action.c
index 0b1d2757435..42e8523d4cb 100644
--- a/source/blender/editors/transform/transform_convert_action.c
+++ b/source/blender/editors/transform/transform_convert_action.c
@@ -36,8 +36,6 @@
#include "ED_anim_api.h"
-#include "UI_view2d.h"
-
#include "transform.h"
#include "transform_convert.h"
@@ -333,11 +331,10 @@ void createTransActionData(bContext *C, TransInfo *t)
/* which side of the current frame should be allowed */
if (t->mode == TFM_TIME_EXTEND) {
- /* only side on which mouse is gets transformed */
- float xmouse, ymouse;
-
- UI_view2d_region_to_view(&ac.ar->v2d, t->mouse.imval[0], t->mouse.imval[1], &xmouse, &ymouse);
- t->frame_side = (xmouse > CFRA) ? 'R' : 'L'; // XXX use t->frame_side
+ /* only side on which center is gets transformed */
+ float center[2];
+ transform_convert_center_global_v2(t, center);
+ t->frame_side = (center[0] > CFRA) ? 'R' : 'L';
}
else {
/* normal transform - both sides of current frame are considered */
diff --git a/source/blender/editors/transform/transform_convert_graph.c b/source/blender/editors/transform/transform_convert_graph.c
index f6f982e854a..502679efedf 100644
--- a/source/blender/editors/transform/transform_convert_graph.c
+++ b/source/blender/editors/transform/transform_convert_graph.c
@@ -1,4 +1,4 @@
-/*
+/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@@ -261,11 +261,10 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
/* which side of the current frame should be allowed */
// XXX we still want this mode, but how to get this using standard transform too?
if (t->mode == TFM_TIME_EXTEND) {
- /* only side on which mouse is gets transformed */
- float xmouse, ymouse;
-
- UI_view2d_region_to_view(v2d, t->mouse.imval[0], t->mouse.imval[1], &xmouse, &ymouse);
- t->frame_side = (xmouse > CFRA) ? 'R' : 'L'; // XXX use t->frame_side
+ /* only side on which center is gets transformed */
+ float center[2];
+ transform_convert_center_global_v2(t, center);
+ t->frame_side = (center[0] > CFRA) ? 'R' : 'L';
}
else {
/* normal transform - both sides of current frame are considered */
diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c
index 114968ec83f..7c34c583210 100644
--- a/source/blender/editors/transform/transform_convert_nla.c
+++ b/source/blender/editors/transform/transform_convert_nla.c
@@ -35,8 +35,6 @@
#include "ED_anim_api.h"
-#include "UI_view2d.h"
-
#include "transform.h"
#include "transform_convert.h"
@@ -73,11 +71,10 @@ void createTransNlaData(bContext *C, TransInfo *t)
/* which side of the current frame should be allowed */
if (t->mode == TFM_TIME_EXTEND) {
- /* only side on which mouse is gets transformed */
- float xmouse, ymouse;
-
- UI_view2d_region_to_view(&ac.ar->v2d, t->mouse.imval[0], t->mouse.imval[1], &xmouse, &ymouse);
- t->frame_side = (xmouse > CFRA) ? 'R' : 'L';
+ /* only side on which center is gets transformed */
+ float center[2];
+ transform_convert_center_global_v2(t, center);
+ t->frame_side = (center[0] > CFRA) ? 'R' : 'L';
}
else {
/* normal transform - both sides of current frame are considered */
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index 4baf0e8a3cb..a35c814ee23 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -31,8 +31,6 @@
#include "BKE_sequencer.h"
#include "BKE_report.h"
-#include "UI_view2d.h"
-
#include "transform.h"
#include "transform_convert.h"
@@ -522,18 +520,16 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c
DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS);
}
-void createTransSeqData(bContext *C, TransInfo *t)
+void createTransSeqData(TransInfo *t)
{
#define XXX_DURIAN_ANIM_TX_HACK
- View2D *v2d = UI_view2d_fromcontext(C);
Scene *scene = t->scene;
Editing *ed = BKE_sequencer_editing_get(t->scene, false);
TransData *td = NULL;
TransData2D *td2d = NULL;
TransDataSeq *tdsq = NULL;
TransSeq *ts = NULL;
- int xmouse;
int count = 0;
@@ -545,18 +541,10 @@ void createTransSeqData(bContext *C, TransInfo *t)
}
tc->custom.type.free_cb = freeSeqData;
-
- xmouse = (int)UI_view2d_region_to_view_x(v2d, t->mouse.imval[0]);
-
- /* which side of the current frame should be allowed */
- if (t->mode == TFM_TIME_EXTEND) {
- /* only side on which mouse is gets transformed */
- t->frame_side = (xmouse > CFRA) ? 'R' : 'L';
- }
- else {
- /* normal transform - both sides of current frame are considered */
- t->frame_side = 'B';
- }
+ /* only side on which center is gets transformed */
+ int center[2];
+ transform_convert_center_global_v2_int(t, center);
+ t->frame_side = (center[0] > CFRA) ? 'R' : 'L';
#ifdef XXX_DURIAN_ANIM_TX_HACK
{
@@ -599,7 +587,7 @@ void createTransSeqData(bContext *C, TransInfo *t)
SeqTransDataBounds(t, ed->seqbasep, ts);
/* set the snap mode based on how close the mouse is at the end/start points */
- if (abs(xmouse - ts->max) > abs(xmouse - ts->min)) {
+ if (abs(center[0] - ts->max) > abs(center[0] - ts->min)) {
ts->snap_left = true;
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index c925f5c9a8e..7d9a122f802 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1374,17 +1374,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
bGPdata *gpd = CTX_data_gpencil_data(C);
PropertyRNA *prop;
- if (op && (prop = RNA_struct_find_property(op->ptr, "mouse_coordinate_override")) &&
- RNA_property_is_set(op->ptr, prop)) {
- RNA_property_int_get_array(op->ptr, prop, t->mval);
- }
- else if (event) {
- copy_v2_v2_int(t->mval, event->mval);
- }
- else {
- zero_v2_int(t->mval);
- }
-
t->depsgraph = CTX_data_depsgraph_pointer(C);
t->scene = sce;
t->view_layer = view_layer;
@@ -1413,11 +1402,16 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->redraw = TREDRAW_HARD; /* redraw first time */
- t->mouse.imval[0] = t->mval[0];
- t->mouse.imval[1] = t->mval[1];
-
- t->con.imval[0] = t->mouse.imval[0];
- t->con.imval[1] = t->mouse.imval[1];
+ int mval[2];
+ if (event) {
+ copy_v2_v2_int(mval, event->mval);
+ }
+ else {
+ zero_v2_int(mval);
+ }
+ copy_v2_v2_int(t->mval, mval);
+ copy_v2_v2_int(t->mouse.imval, mval);
+ copy_v2_v2_int(t->con.imval, mval);
t->transform = NULL;
t->handleEvent = NULL;
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index d3d5d785eac..39f6f24eb8d 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -694,14 +694,6 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
RNA_def_property_ui_text(prop, "Center Override", "Force using this center value (when set)");
}
- if (flags & P_MOUSE) {
- prop = RNA_def_property(ot->srna, "mouse_coordinate_override", PROP_INT, PROP_XYZ);
- RNA_def_property_array(prop, 2);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- RNA_def_property_ui_text(
- prop, "Mouse Coordinate Override", "Force using this mouse value (when set)");
- }
-
if ((flags & P_NO_DEFAULTS) == 0) {
prop = RNA_def_boolean(ot->srna,
"release_confirm",
@@ -1247,7 +1239,7 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot)
Transform_Properties(ot,
P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR |
- P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER | P_MOUSE);
+ P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER);
}
static int transform_from_gizmo_invoke(bContext *C,
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index c4358168adb..ecd267d6f2a 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -19,9 +19,6 @@
*/
#include <stdlib.h>
-#include <math.h>
-#include <float.h>
-#include <stdio.h>
#include "MEM_guardedalloc.h"
@@ -34,10 +31,10 @@
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
@@ -50,19 +47,16 @@
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_tracking.h"
-#include "BKE_context.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
-#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
-#include "ED_transform.h"
#include "ED_transform_snap_object_context.h"
#include "ED_view3d.h"
#include "ED_armature.h"
-#include "transform.h"
+#include "ED_transform.h"
/* -------------------------------------------------------------------- */
/** \name Internal Data Types
@@ -92,25 +86,27 @@ typedef struct SnapObjectData {
SNAP_MESH = 1,
SNAP_EDIT_MESH,
} type;
-} SnapObjectData;
-
-typedef struct SnapObjectData_Mesh {
- SnapObjectData sd;
- BVHTreeFromMesh treedata;
- const struct MPoly *poly;
- BVHTree *bvhtree[2]; /* from loose verts and from loose edges */
- uint has_looptris : 1;
- uint has_loose_edge : 1;
- uint has_loose_vert : 1;
-} SnapObjectData_Mesh;
+ BVHTree *bvhtree[2]; /* MESH: loose edges, loose verts
+ * EDIT_MESH: verts, edges. */
+ bool cached[2];
-typedef struct SnapObjectData_EditMesh {
- SnapObjectData sd;
- BVHTreeFromEditMesh *bvh_trees[3];
- float min[3], max[3];
-
-} SnapObjectData_EditMesh;
+ union {
+ struct {
+ /* SNAP_MESH */
+ BVHTreeFromMesh treedata_mesh;
+ const struct MPoly *poly;
+ uint has_looptris : 1;
+ uint has_loose_edge : 1;
+ uint has_loose_vert : 1;
+ };
+ struct {
+ /* SNAP_EDIT_MESH */
+ BVHTreeFromEditMesh treedata_editmesh;
+ float min[3], max[3];
+ };
+ };
+} SnapObjectData;
struct SnapObjectContext {
Main *bmain;
@@ -149,7 +145,7 @@ struct SnapObjectContext {
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Common Utilities
+/** \name Snap Object Data
* \{ */
/**
@@ -166,6 +162,45 @@ static void bm_mesh_minmax(BMesh *bm, float r_min[3], float r_max[3])
}
}
+static void snap_object_data_mesh_clear(SnapObjectData *sod)
+{
+ BLI_assert(sod->type == SNAP_MESH);
+ for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) {
+ if (!sod->cached[i]) {
+ BLI_bvhtree_free(sod->bvhtree[i]);
+ }
+ sod->bvhtree[i] = NULL;
+ }
+ free_bvhtree_from_mesh(&sod->treedata_mesh);
+}
+
+static void snap_object_data_editmesh_clear(SnapObjectData *sod)
+{
+ BLI_assert(sod->type == SNAP_EDIT_MESH);
+ for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) {
+ if (!sod->cached[i]) {
+ BLI_bvhtree_free(sod->bvhtree[i]);
+ }
+ sod->bvhtree[i] = NULL;
+ }
+ free_bvhtree_from_editmesh(&sod->treedata_editmesh);
+}
+
+static void snap_object_data_clear(SnapObjectData *sod)
+{
+ switch (sod->type) {
+ case SNAP_MESH: {
+ snap_object_data_mesh_clear(sod);
+ break;
+ }
+ case SNAP_EDIT_MESH: {
+ snap_object_data_editmesh_clear(sod);
+ break;
+ }
+ }
+ memset(&sod->type, 0x0, sizeof(*sod) - offsetof(SnapObjectData, type));
+}
+
static SnapObjectData *snap_object_data_lookup(SnapObjectContext *sctx, Object *ob)
{
SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob);
@@ -181,15 +216,17 @@ static SnapObjectData *snap_object_data_lookup(SnapObjectContext *sctx, Object *
return sod;
}
-static SnapObjectData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, Object *ob)
+static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx, Object *ob)
{
void **sod_p;
if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
BLI_assert(((SnapObjectData *)*sod_p)->type == SNAP_MESH);
}
else {
- SnapObjectData_Mesh *sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_MESH;
+ SnapObjectData *sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+
+ /* Init. */
+ sod->type = SNAP_MESH;
/* start assuming that it has each of these element types */
sod->has_looptris = true;
sod->has_loose_edge = true;
@@ -199,9 +236,9 @@ static SnapObjectData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, O
return *sod_p;
}
-static SnapObjectData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
- Object *ob,
- BMEditMesh *em)
+static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
+ Object *ob,
+ BMEditMesh *em)
{
void **sod_p;
@@ -224,15 +261,23 @@ static SnapObjectData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext
BLI_assert(((SnapObjectData *)*sod_p)->type == SNAP_EDIT_MESH);
}
else {
- SnapObjectData_EditMesh *sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena,
- sizeof(*sod));
- sod->sd.type = SNAP_EDIT_MESH;
+ SnapObjectData *sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+
+ /* Init. */
+ sod->type = SNAP_EDIT_MESH;
+ sod->treedata_editmesh.em = em;
bm_mesh_minmax(em->bm, sod->min, sod->max);
}
return *sod_p;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Iterator
+ * \{ */
+
typedef void (*IterSnapObjsCallback)(SnapObjectContext *sctx,
bool is_obedit,
bool use_backface_culling,
@@ -516,9 +561,9 @@ static bool raycastMesh(SnapObjectContext *sctx,
len_diff = 0.0f;
}
- SnapObjectData_Mesh *sod = snap_object_data_mesh_get(sctx, ob);
+ SnapObjectData *sod = snap_object_data_mesh_get(sctx, ob);
- BVHTreeFromMesh *treedata = &sod->treedata;
+ BVHTreeFromMesh *treedata = &sod->treedata_mesh;
/* The tree is owned by the Mesh and may have been freed since we last used. */
if (treedata->tree) {
@@ -668,7 +713,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
local_depth *= local_scale;
}
- SnapObjectData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob, em);
+ SnapObjectData *sod = snap_object_data_editmesh_get(sctx, ob, em);
/* Test BoundBox */
@@ -690,24 +735,21 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
len_diff = 0.0f;
}
- if (sod->bvh_trees[2] == NULL) {
- sod->bvh_trees[2] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(BVHTreeFromEditMesh));
- }
-
- BVHTreeFromEditMesh *treedata = sod->bvh_trees[2];
+ BVHTreeFromEditMesh *treedata = &sod->treedata_editmesh;
BVHCache **em_bvh_cache = &((Mesh *)ob->data)->runtime.bvh_cache;
- if (sctx->callbacks.edit_mesh.test_face_fn == NULL) {
+ if (treedata->tree && treedata->cached) {
/* The tree is owned by the Mesh and may have been freed since we last used! */
- if (treedata->tree && !bvhcache_has_tree(*em_bvh_cache, treedata->tree)) {
- free_bvhtree_from_editmesh(treedata);
+ if (!bvhcache_has_tree(*em_bvh_cache, treedata->tree)) {
+ treedata->tree = NULL;
}
}
if (treedata->tree == NULL) {
/* Get original version of the edit_mesh. */
- BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob));
+ BLI_assert(sod->treedata_editmesh.em == BKE_editmesh_from_object(DEG_get_original_object(ob)));
+ BMEditMesh *em_orig = sod->treedata_editmesh.em;
if (sctx->callbacks.edit_mesh.test_face_fn) {
BMesh *bm = em_orig->bm;
@@ -796,7 +838,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
if (r_index) {
/* Get original version of the edit_mesh. */
- BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob));
+ BMEditMesh *em_orig = sod->treedata_editmesh.em;
*r_index = BM_elem_index_get(em_orig->looptris[hit.index][0]->f);
}
@@ -850,7 +892,10 @@ static bool raycastObj(SnapObjectContext *sctx,
Mesh *me = ob->data;
bool use_hide = false;
if (BKE_object_is_in_editmode(ob)) {
- BMEditMesh *em = BKE_editmesh_from_object(ob);
+ /* Strange, sometimes the `em` of the evaluated object has
+ * uninitialized memory. Need to be investigated.
+ * Use the `em` of the original object then. */
+ BMEditMesh *em = BKE_editmesh_from_object(DEG_get_original_object(ob));
if (use_obedit) {
retval = raycastEditMesh(sctx,
ray_start,
@@ -891,12 +936,13 @@ static bool raycastObj(SnapObjectContext *sctx,
case OB_CURVE:
case OB_SURF:
case OB_FONT: {
- if (ob->runtime.mesh_eval) {
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ if (mesh_eval) {
retval = raycastMesh(sctx,
ray_start,
ray_dir,
ob,
- ob->runtime.mesh_eval,
+ mesh_eval,
obmat,
ob_index,
false,
@@ -1400,14 +1446,14 @@ static short snap_mesh_polygon(SnapObjectContext *sctx,
BLI_assert(sod != NULL);
if (sod->type == SNAP_MESH) {
- BVHTreeFromMesh *treedata = &((SnapObjectData_Mesh *)sod)->treedata;
+ BVHTreeFromMesh *treedata = &sod->treedata_mesh;
nearest2d.userdata = treedata;
nearest2d.get_vert_co = (Nearest2DGetVertCoCallback)cb_mvert_co_get;
nearest2d.get_edge_verts_index = (Nearest2DGetEdgeVertsCallback)cb_medge_verts_get;
nearest2d.copy_vert_no = (Nearest2DCopyVertNoCallback)cb_mvert_no_copy;
- const MPoly *mp = &((SnapObjectData_Mesh *)sod)->poly[*r_index];
+ const MPoly *mp = &sod->poly[*r_index];
const MLoop *ml = &treedata->loop[mp->loopstart];
if (snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE) {
elem = SCE_SNAP_MODE_EDGE;
@@ -1435,7 +1481,7 @@ static short snap_mesh_polygon(SnapObjectContext *sctx,
}
else {
BLI_assert(sod->type == SNAP_EDIT_MESH);
- BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMEditMesh *em = sod->treedata_editmesh.em;
nearest2d.userdata = em;
nearest2d.get_vert_co = (Nearest2DGetVertCoCallback)cb_bvert_co_get;
@@ -1525,14 +1571,14 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
nearest2d.is_persp = snapdata->view_proj == VIEW_PROJ_PERSP;
nearest2d.use_backface_culling = use_backface_culling;
if (sod->type == SNAP_MESH) {
- nearest2d.userdata = &((SnapObjectData_Mesh *)sod)->treedata;
+ nearest2d.userdata = &sod->treedata_mesh;
nearest2d.get_vert_co = (Nearest2DGetVertCoCallback)cb_mvert_co_get;
nearest2d.get_edge_verts_index = (Nearest2DGetEdgeVertsCallback)cb_medge_verts_get;
nearest2d.copy_vert_no = (Nearest2DCopyVertNoCallback)cb_mvert_no_copy;
}
else {
BLI_assert(sod->type == SNAP_EDIT_MESH);
- nearest2d.userdata = BKE_editmesh_from_object(ob);
+ nearest2d.userdata = sod->treedata_editmesh.em;
nearest2d.get_vert_co = (Nearest2DGetVertCoCallback)cb_bvert_co_get;
nearest2d.get_edge_verts_index = (Nearest2DGetEdgeVertsCallback)cb_bedge_verts_get;
nearest2d.copy_vert_no = (Nearest2DCopyVertNoCallback)cb_bvert_no_copy;
@@ -2160,27 +2206,23 @@ static short snapMesh(SnapObjectContext *sctx,
return 0;
}
- SnapObjectData_Mesh *sod = snap_object_data_mesh_get(sctx, ob);
+ SnapObjectData *sod = snap_object_data_mesh_get(sctx, ob);
BVHTreeFromMesh *treedata, dummy_treedata;
- BVHTree **bvhtree;
- treedata = &sod->treedata;
- bvhtree = sod->bvhtree;
+ treedata = &sod->treedata_mesh;
/* The tree is owned by the Mesh and may have been freed since we last used! */
- if ((sod->has_looptris && treedata->tree &&
- !bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) ||
- (sod->has_loose_edge && bvhtree[0] &&
- !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[0])) ||
- (sod->has_loose_vert && bvhtree[1] &&
- !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[1]))) {
- BLI_assert(!treedata->tree || !bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree));
- BLI_assert(!bvhtree[0] || !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[0]));
- BLI_assert(!bvhtree[1] || !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[1]));
-
+ if (treedata->cached && treedata->tree &&
+ !bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) {
free_bvhtree_from_mesh(treedata);
- bvhtree[0] = NULL;
- bvhtree[1] = NULL;
+ }
+ if (sod->cached[0] && sod->bvhtree[0] &&
+ !bvhcache_has_tree(me->runtime.bvh_cache, sod->bvhtree[0])) {
+ sod->bvhtree[0] = NULL;
+ }
+ if (sod->cached[1] && sod->bvhtree[1] &&
+ !bvhcache_has_tree(me->runtime.bvh_cache, sod->bvhtree[1])) {
+ sod->bvhtree[1] = NULL;
}
if (sod->has_looptris && treedata->tree == NULL) {
@@ -2191,9 +2233,10 @@ static short snapMesh(SnapObjectContext *sctx,
treedata->edge = me->medge; /* CustomData_get_layer(&me->edata, CD_MEDGE);? */
}
}
- if (sod->has_loose_edge && bvhtree[0] == NULL) {
- bvhtree[0] = BKE_bvhtree_from_mesh_get(&dummy_treedata, me, BVHTREE_FROM_LOOSEEDGES, 2);
- sod->has_loose_edge = bvhtree[0] != NULL;
+ if (sod->has_loose_edge && sod->bvhtree[0] == NULL) {
+ sod->bvhtree[0] = BKE_bvhtree_from_mesh_get(&dummy_treedata, me, BVHTREE_FROM_LOOSEEDGES, 2);
+ sod->has_loose_edge = sod->bvhtree[0] != NULL;
+ sod->cached[0] = dummy_treedata.cached;
if (sod->has_loose_edge) {
BLI_assert(treedata->vert_allocated == false);
@@ -2206,9 +2249,10 @@ static short snapMesh(SnapObjectContext *sctx,
}
}
if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) {
- if (sod->has_loose_vert && bvhtree[1] == NULL) {
- bvhtree[1] = BKE_bvhtree_from_mesh_get(&dummy_treedata, me, BVHTREE_FROM_LOOSEVERTS, 2);
- sod->has_loose_vert = bvhtree[1] != NULL;
+ if (sod->has_loose_vert && sod->bvhtree[1] == NULL) {
+ sod->bvhtree[1] = BKE_bvhtree_from_mesh_get(&dummy_treedata, me, BVHTREE_FROM_LOOSEVERTS, 2);
+ sod->has_loose_vert = sod->bvhtree[1] != NULL;
+ sod->cached[1] = dummy_treedata.cached;
if (sod->has_loose_vert) {
BLI_assert(treedata->vert_allocated == false);
@@ -2226,7 +2270,7 @@ static short snapMesh(SnapObjectContext *sctx,
if (treedata->vert_allocated == false) {
treedata->vert = me->mvert; /* CustomData_get_layer(&me->vdata, CD_MVERT);? */
}
- if (treedata->tree || bvhtree[0]) {
+ if (treedata->tree || sod->bvhtree[0]) {
if (treedata->edge_allocated == false) {
/* If raycast has been executed before, `treedata->edge` can be NULL. */
treedata->edge = me->medge; /* CustomData_get_layer(&me->edata, CD_MEDGE);? */
@@ -2263,9 +2307,9 @@ static short snapMesh(SnapObjectContext *sctx,
mul_v4_m4v4(clip_planes_local[i], tobmat, snapdata->clip_plane[i]);
}
- if (bvhtree[1] && (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
+ if (sod->bvhtree[1] && (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
/* snap to loose verts */
- BLI_bvhtree_find_nearest_projected(bvhtree[1],
+ BLI_bvhtree_find_nearest_projected(sod->bvhtree[1],
lpmat,
snapdata->win_size,
snapdata->mval,
@@ -2279,9 +2323,9 @@ static short snapMesh(SnapObjectContext *sctx,
}
if (snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE) {
- if (bvhtree[0]) {
+ if (sod->bvhtree[0]) {
/* snap to loose edges */
- BLI_bvhtree_find_nearest_projected(bvhtree[0],
+ BLI_bvhtree_find_nearest_projected(sod->bvhtree[0],
lpmat,
snapdata->win_size,
snapdata->mval,
@@ -2311,9 +2355,9 @@ static short snapMesh(SnapObjectContext *sctx,
}
else {
BLI_assert(snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX);
- if (bvhtree[0]) {
- /* snap to loose edges */
- BLI_bvhtree_find_nearest_projected(bvhtree[0],
+ if (sod->bvhtree[0]) {
+ /* snap to loose edge verts */
+ BLI_bvhtree_find_nearest_projected(sod->bvhtree[0],
lpmat,
snapdata->win_size,
snapdata->mval,
@@ -2325,7 +2369,7 @@ static short snapMesh(SnapObjectContext *sctx,
}
if (treedata->tree) {
- /* snap to looptris */
+ /* snap to looptri verts */
BLI_bvhtree_find_nearest_projected(treedata->tree,
lpmat,
snapdata->win_size,
@@ -2388,17 +2432,12 @@ static short snapEditMesh(SnapObjectContext *sctx,
}
}
- BVHTreeFromEditMesh *treedata_vert = NULL, *treedata_edge = NULL;
-
- BLI_assert(BKE_object_get_pre_modified_mesh(ob) == BKE_object_get_pre_modified_mesh(ob));
- UNUSED_VARS_NDEBUG(ob);
-
float lpmat[4][4];
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
float dist_px_sq = SQUARE(*dist_px);
- SnapObjectData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob, em);
+ SnapObjectData *sod = snap_object_data_editmesh_get(sctx, ob, em);
/* Test BoundBox */
@@ -2411,19 +2450,16 @@ static short snapEditMesh(SnapObjectContext *sctx,
BVHCache **em_bvh_cache = &((Mesh *)ob->data)->runtime.bvh_cache;
if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) {
- if (sod->bvh_trees[0] == NULL) {
- sod->bvh_trees[0] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees));
- }
- treedata_vert = sod->bvh_trees[0];
+ BVHTreeFromEditMesh treedata = {.tree = sod->bvhtree[0]};
- if (sctx->callbacks.edit_mesh.test_vert_fn == NULL) {
+ if (treedata.tree && sod->cached[0]) {
/* The tree is owned by the Mesh and may have been freed since we last used! */
- if (treedata_vert->tree && !bvhcache_has_tree(*em_bvh_cache, treedata_vert->tree)) {
- free_bvhtree_from_editmesh(treedata_vert);
+ if (!bvhcache_has_tree(*em_bvh_cache, treedata.tree)) {
+ treedata.tree = sod->bvhtree[0] = NULL;
}
}
- if (treedata_vert->tree == NULL) {
+ if (treedata.tree == NULL) {
BLI_bitmap *verts_mask = NULL;
int verts_num_active = -1;
if (sctx->callbacks.edit_mesh.test_vert_fn) {
@@ -2436,29 +2472,28 @@ static short snapEditMesh(SnapObjectContext *sctx,
sctx->callbacks.edit_mesh.user_data);
bvhtree_from_editmesh_verts_ex(
- treedata_vert, em, verts_mask, verts_num_active, 0.0f, 2, 6, 0, NULL);
+ &treedata, em, verts_mask, verts_num_active, 0.0f, 2, 6, 0, NULL);
MEM_freeN(verts_mask);
}
else {
- BKE_bvhtree_from_editmesh_get(treedata_vert, em, 2, BVHTREE_FROM_EM_VERTS, em_bvh_cache);
+ BKE_bvhtree_from_editmesh_get(&treedata, em, 2, BVHTREE_FROM_EM_VERTS, em_bvh_cache);
}
+ sod->bvhtree[0] = treedata.tree;
+ sod->cached[0] = treedata.cached;
}
}
if (snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE) {
- if (sod->bvh_trees[1] == NULL) {
- sod->bvh_trees[1] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees));
- }
- treedata_edge = sod->bvh_trees[1];
+ BVHTreeFromEditMesh treedata = {.tree = sod->bvhtree[1]};
- if (sctx->callbacks.edit_mesh.test_edge_fn == NULL) {
+ if (treedata.tree && sod->cached[1]) {
/* The tree is owned by the Mesh and may have been freed since we last used! */
- if (treedata_edge->tree && !bvhcache_has_tree(*em_bvh_cache, treedata_edge->tree)) {
- free_bvhtree_from_editmesh(treedata_edge);
+ if (!bvhcache_has_tree(*em_bvh_cache, treedata.tree)) {
+ treedata.tree = sod->bvhtree[1] = NULL;
}
}
- if (treedata_edge->tree == NULL) {
+ if (treedata.tree == NULL) {
BLI_bitmap *edges_mask = NULL;
int edges_num_active = -1;
if (sctx->callbacks.edit_mesh.test_edge_fn) {
@@ -2471,12 +2506,14 @@ static short snapEditMesh(SnapObjectContext *sctx,
sctx->callbacks.edit_mesh.user_data);
bvhtree_from_editmesh_edges_ex(
- treedata_edge, em, edges_mask, edges_num_active, 0.0f, 2, 6, 0, NULL);
+ &treedata, em, edges_mask, edges_num_active, 0.0f, 2, 6, 0, NULL);
MEM_freeN(edges_mask);
}
else {
- BKE_bvhtree_from_editmesh_get(treedata_edge, em, 2, BVHTREE_FROM_EM_EDGES, em_bvh_cache);
+ BKE_bvhtree_from_editmesh_get(&treedata, em, 2, BVHTREE_FROM_EM_EDGES, em_bvh_cache);
}
+ sod->bvhtree[1] = treedata.tree;
+ sod->cached[1] = treedata.cached;
}
}
@@ -2502,10 +2539,10 @@ static short snapEditMesh(SnapObjectContext *sctx,
mul_v4_m4v4(clip_planes_local[i], tobmat, snapdata->clip_plane[i]);
}
- if (treedata_vert && (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
+ if (sod->bvhtree[0] && (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
- BLI_bvhtree_find_nearest_projected(treedata_vert->tree,
+ BLI_bvhtree_find_nearest_projected(sod->bvhtree[0],
lpmat,
snapdata->win_size,
snapdata->mval,
@@ -2516,12 +2553,12 @@ static short snapEditMesh(SnapObjectContext *sctx,
&nearest2d);
}
- if (treedata_edge && (snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE)) {
+ if (sod->bvhtree[1] && (snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE)) {
int last_index = nearest.index;
nearest.index = -1;
BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT);
BM_mesh_elem_index_ensure(em->bm, BM_EDGE | BM_VERT);
- BLI_bvhtree_find_nearest_projected(treedata_edge->tree,
+ BLI_bvhtree_find_nearest_projected(sod->bvhtree[1],
lpmat,
snapdata->win_size,
snapdata->mval,
@@ -2588,7 +2625,10 @@ static short snapObject(SnapObjectContext *sctx,
case OB_MESH: {
Mesh *me = ob->data;
if (BKE_object_is_in_editmode(ob)) {
- BMEditMesh *em = BKE_editmesh_from_object(ob);
+ /* Strange, sometimes the `em` of the evaluated object has
+ * uninitialized memory. Need to be investigated.
+ * Use the `em` of the original object then. */
+ BMEditMesh *em = BKE_editmesh_from_object(DEG_get_original_object(ob));
if (use_obedit) {
retval = snapEditMesh(
sctx, snapdata, ob, em, obmat, use_backface_culling, dist_px, r_loc, r_no, r_index);
@@ -2615,11 +2655,12 @@ static short snapObject(SnapObjectContext *sctx,
break; /* Use ATTR_FALLTHROUGH if we want to snap to the generated mesh. */
case OB_SURF:
case OB_FONT: {
- if (ob->runtime.mesh_eval) {
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ if (mesh_eval) {
retval |= snapMesh(sctx,
snapdata,
ob,
- ob->runtime.mesh_eval,
+ mesh_eval,
obmat,
use_backface_culling,
dist_px,
@@ -2794,24 +2835,8 @@ SnapObjectContext *ED_transform_snap_object_context_create_view3d(Main *bmain,
static void snap_object_data_free(void *sod_v)
{
- switch (((SnapObjectData *)sod_v)->type) {
- case SNAP_MESH: {
- SnapObjectData_Mesh *sod = sod_v;
- if (sod->treedata.tree) {
- free_bvhtree_from_mesh(&sod->treedata);
- }
- break;
- }
- case SNAP_EDIT_MESH: {
- SnapObjectData_EditMesh *sod = sod_v;
- for (int i = 0; i < ARRAY_SIZE(sod->bvh_trees); i++) {
- if (sod->bvh_trees[i]) {
- free_bvhtree_from_editmesh(sod->bvh_trees[i]);
- }
- }
- break;
- }
- }
+ SnapObjectData *sod = sod_v;
+ snap_object_data_clear(sod);
}
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx)
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 43ccc1a8250..72376b977eb 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -238,15 +238,12 @@ bool ED_editors_flush_edits_for_object_ex(Main *bmain,
/* Don't allow flushing while in the middle of a stroke (frees data in use).
* Auto-save prevents this from happening but scripts
* may cause a flush on saving: T53986. */
- if ((ob->sculpt && ob->sculpt->cache) == 0) {
-
- {
- char *needs_flush_ptr = &ob->sculpt->needs_flush_to_id;
- if (check_needs_flush && (*needs_flush_ptr == 0)) {
- return false;
- }
- *needs_flush_ptr = 0;
+ if (!ELEM(NULL, ob->sculpt, ob->sculpt->cache)) {
+ char *needs_flush_ptr = &ob->sculpt->needs_flush_to_id;
+ if (check_needs_flush && (*needs_flush_ptr == 0)) {
+ return false;
}
+ *needs_flush_ptr = 0;
/* flush multires changes (for sculpt) */
multires_flush_sculpt_updates(ob);
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 800843dd851..37fe30bc96b 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -64,6 +64,7 @@ typedef enum eGPUType {
GPU_VEC4 = 4,
GPU_MAT3 = 9,
GPU_MAT4 = 16,
+ GPU_MAX_CONSTANT_DATA = GPU_MAT4,
/* Values not in GPU_DATATYPE_STR */
GPU_TEX1D_ARRAY = 1001,
@@ -137,10 +138,12 @@ typedef enum eGPUMaterialStatus {
GPU_MAT_SUCCESS,
} eGPUMaterialStatus;
-GPUNodeLink *GPU_attribute(CustomDataType type, const char *name);
-GPUNodeLink *GPU_constant(float *num);
-GPUNodeLink *GPU_uniform(float *num);
-GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser);
+GPUNodeLink *GPU_constant(const float *num);
+GPUNodeLink *GPU_uniform(const float *num);
+GPUNodeLink *GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name);
+GPUNodeLink *GPU_image(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser);
+GPUNodeLink *GPU_image_tiled(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser);
+GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser);
GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *layer);
GPUNodeLink *GPU_builtin(eGPUBuiltin builtin);
@@ -212,17 +215,19 @@ typedef struct GPUMaterialAttribute {
struct GPUMaterialAttribute *next, *prev;
int type; /* CustomDataType */
char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
+ eGPUType gputype;
int id;
+ int users;
} GPUMaterialAttribute;
typedef struct GPUMaterialTexture {
struct GPUMaterialTexture *next, *prev;
- eGPUType type;
struct Image *ima;
struct ImageUser *iuser;
struct GPUTexture **colorband;
- char shadername[32]; /* Name of sampler in GLSL. */
- int id;
+ char sampler_name[32]; /* Name of sampler in GLSL. */
+ char tiled_mapping_name[32]; /* Name of tile mapping sampler in GLSL. */
+ int users;
} GPUMaterialTexture;
ListBase GPU_material_attributes(GPUMaterial *material);
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 6c14d918816..553ecb65529 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -216,16 +216,6 @@ static void codegen_print_datatype(DynStr *ds, const eGPUType type, float *data)
}
}
-static int codegen_input_has_texture(GPUInput *input)
-{
- if (input->link) {
- return 0;
- }
- else {
- return (input->source == GPU_SOURCE_TEX);
- }
-}
-
static const char *gpu_builtin_name(eGPUBuiltin builtin)
{
if (builtin == GPU_VIEW_MATRIX) {
@@ -299,14 +289,14 @@ static const char *gpu_builtin_name(eGPUBuiltin builtin)
}
}
-static void codegen_set_unique_ids(ListBase *nodes)
+static void codegen_set_unique_ids(GPUNodeGraph *graph)
{
GPUNode *node;
GPUInput *input;
GPUOutput *output;
int id = 1;
- for (node = nodes->first; node; node = node->next) {
+ for (node = graph->nodes.first; node; node = node->next) {
for (input = node->inputs.first; input; input = input->next) {
/* set id for unique names of uniform variables */
input->id = id++;
@@ -322,7 +312,9 @@ static void codegen_set_unique_ids(ListBase *nodes)
/**
* It will create an UBO for GPUMaterial if there is any GPU_DYNAMIC_UBO.
*/
-static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, ListBase *nodes)
+static int codegen_process_uniforms_functions(GPUMaterial *material,
+ DynStr *ds,
+ GPUNodeGraph *graph)
{
GPUNode *node;
GPUInput *input;
@@ -330,27 +322,29 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds,
int builtins = 0;
ListBase ubo_inputs = {NULL, NULL};
- /* print uniforms */
- for (node = nodes->first; node; node = node->next) {
+ /* Attributes */
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ BLI_dynstr_appendf(ds, "in %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id);
+ }
+
+ /* Textures */
+ for (GPUMaterialTexture *tex = graph->textures.first; tex; tex = tex->next) {
+ if (tex->colorband) {
+ BLI_dynstr_appendf(ds, "uniform sampler1DArray %s;\n", tex->sampler_name);
+ }
+ else if (tex->tiled_mapping_name[0]) {
+ BLI_dynstr_appendf(ds, "uniform sampler2DArray %s;\n", tex->sampler_name);
+ BLI_dynstr_appendf(ds, "uniform sampler1DArray %s;\n", tex->tiled_mapping_name);
+ }
+ else {
+ BLI_dynstr_appendf(ds, "uniform sampler2D %s;\n", tex->sampler_name);
+ }
+ }
+
+ /* Print other uniforms */
+ for (node = graph->nodes.first; node; node = node->next) {
for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_TEX) {
- /* create exactly one sampler for each texture */
- if (codegen_input_has_texture(input) && input->bindtex) {
- const char *type;
- if (input->colorband || input->type == GPU_TEX1D_ARRAY) {
- type = "sampler1DArray";
- }
- else if (input->type == GPU_TEX2D_ARRAY) {
- type = "sampler2DArray";
- }
- else {
- BLI_assert(input->type == GPU_TEX2D);
- type = "sampler2D";
- }
- BLI_dynstr_appendf(ds, "uniform %s samp%d;\n", type, input->texid);
- }
- }
- else if (input->source == GPU_SOURCE_BUILTIN) {
+ if (input->source == GPU_SOURCE_BUILTIN) {
/* only define each builtin uniform/varying once */
if (!(builtins & input->builtin)) {
builtins |= input->builtin;
@@ -385,10 +379,6 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds,
codegen_print_datatype(ds, input->type, input->vec);
BLI_dynstr_append(ds, ";\n");
}
- else if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- BLI_dynstr_appendf(
- ds, "in %s var%d;\n", gpu_data_type_to_string(input->type), input->attr_id);
- }
}
}
@@ -412,12 +402,12 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds,
return builtins;
}
-static void codegen_declare_tmps(DynStr *ds, ListBase *nodes)
+static void codegen_declare_tmps(DynStr *ds, GPUNodeGraph *graph)
{
GPUNode *node;
GPUOutput *output;
- for (node = nodes->first; node; node = node->next) {
+ for (node = graph->nodes.first; node; node = node->next) {
/* declare temporary variables for node output storage */
for (output = node->outputs.first; output; output = output->next) {
if (output->type == GPU_CLOSURE) {
@@ -432,18 +422,21 @@ static void codegen_declare_tmps(DynStr *ds, ListBase *nodes)
BLI_dynstr_append(ds, "\n");
}
-static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *finaloutput)
+static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *finaloutput)
{
GPUNode *node;
GPUInput *input;
GPUOutput *output;
- for (node = nodes->first; node; node = node->next) {
+ for (node = graph->nodes.first; node; node = node->next) {
BLI_dynstr_appendf(ds, "\t%s(", node->name);
for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_TEX) {
- BLI_dynstr_appendf(ds, "samp%d", input->texid);
+ BLI_dynstr_append(ds, input->texture->sampler_name);
+ }
+ else if (input->source == GPU_SOURCE_TEX_TILED_MAPPING) {
+ BLI_dynstr_append(ds, input->texture->tiled_mapping_name);
}
else if (input->source == GPU_SOURCE_OUTPUT) {
codegen_convert_datatype(
@@ -507,7 +500,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
BLI_dynstr_appendf(ds, "cons%d", input->id);
}
else if (input->source == GPU_SOURCE_ATTR) {
- BLI_dynstr_appendf(ds, "var%d", input->attr_id);
+ BLI_dynstr_appendf(ds, "var%d", input->attr->id);
}
BLI_dynstr_append(ds, ", ");
@@ -527,7 +520,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
BLI_dynstr_append(ds, ";\n");
}
-static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUOutput *output)
+static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph)
{
DynStr *ds = BLI_dynstr_new();
char *code;
@@ -537,8 +530,8 @@ static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUO
BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);
#endif
- codegen_set_unique_ids(nodes);
- builtins = codegen_process_uniforms_functions(material, ds, nodes);
+ codegen_set_unique_ids(graph);
+ builtins = codegen_process_uniforms_functions(material, ds, graph);
if (builtins & (GPU_OBJECT_INFO | GPU_OBJECT_COLOR)) {
BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl);
@@ -614,8 +607,8 @@ static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUO
BLI_dynstr_append(ds, "\t#define viewposition viewPosition\n");
}
- codegen_declare_tmps(ds, nodes);
- codegen_call_functions(ds, nodes, output);
+ codegen_declare_tmps(ds, graph);
+ codegen_call_functions(ds, graph, graph->outlink->output);
BLI_dynstr_append(ds, "}\n");
@@ -666,7 +659,7 @@ static const char *attr_prefix_get(CustomDataType type)
}
}
-static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool use_geom)
+static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bool use_geom)
{
DynStr *ds = BLI_dynstr_new();
GPUNode *node;
@@ -682,48 +675,44 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
"#define DEFINE_ATTR(type, attr) in type attr\n"
"#endif\n");
- for (node = nodes->first; node; node = node->next) {
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ /* XXX FIXME : see notes in mesh_render_data_create() */
+ /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
+ if (attr->type == CD_ORCO) {
+ /* OPTI : orco is computed from local positions, but only if no modifier is present. */
+ BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl);
+ BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n");
+ }
+ else if (attr->name[0] == '\0') {
+ BLI_dynstr_appendf(ds,
+ "DEFINE_ATTR(%s, %s);\n",
+ gpu_data_type_to_string(attr->gputype),
+ attr_prefix_get(attr->type));
+ BLI_dynstr_appendf(ds, "#define att%d %s\n", attr->id, attr_prefix_get(attr->type));
+ }
+ else {
+ char attr_safe_name[GPU_MAX_SAFE_ATTRIB_NAME];
+ GPU_vertformat_safe_attrib_name(attr->name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
+ BLI_dynstr_appendf(ds,
+ "DEFINE_ATTR(%s, %s%s);\n",
+ gpu_data_type_to_string(attr->gputype),
+ attr_prefix_get(attr->type),
+ attr_safe_name);
+ BLI_dynstr_appendf(
+ ds, "#define att%d %s%s\n", attr->id, attr_prefix_get(attr->type), attr_safe_name);
+ }
+ BLI_dynstr_appendf(ds,
+ "out %s var%d%s;\n",
+ gpu_data_type_to_string(attr->gputype),
+ attr->id,
+ use_geom ? "g" : "");
+ }
+
+ for (node = graph->nodes.first; node; node = node->next) {
for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_BUILTIN) {
builtins |= input->builtin;
}
- if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- /* XXX FIXME : see notes in mesh_render_data_create() */
- /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
- if (input->attr_type == CD_ORCO) {
- /* OPTI : orco is computed from local positions, but only if no modifier is present. */
- BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl);
- BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n");
- }
- else if (input->attr_name[0] == '\0') {
- BLI_dynstr_appendf(ds,
- "DEFINE_ATTR(%s, %s);\n",
- gpu_data_type_to_string(input->type),
- attr_prefix_get(input->attr_type));
- BLI_dynstr_appendf(
- ds, "#define att%d %s\n", input->attr_id, attr_prefix_get(input->attr_type));
- }
- else {
- char attr_safe_name[GPU_MAX_SAFE_ATTRIB_NAME];
- GPU_vertformat_safe_attrib_name(
- input->attr_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
- BLI_dynstr_appendf(ds,
- "DEFINE_ATTR(%s, %s%s);\n",
- gpu_data_type_to_string(input->type),
- attr_prefix_get(input->attr_type),
- attr_safe_name);
- BLI_dynstr_appendf(ds,
- "#define att%d %s%s\n",
- input->attr_id,
- attr_prefix_get(input->attr_type),
- attr_safe_name);
- }
- BLI_dynstr_appendf(ds,
- "out %s var%d%s;\n",
- gpu_data_type_to_string(input->type),
- input->attr_id,
- use_geom ? "g" : "");
- }
}
}
@@ -800,30 +789,26 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
BLI_dynstr_append(ds, "\tbarycentricPosg = position;\n");
}
- for (node = nodes->first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- if (input->attr_type == CD_TANGENT) {
- /* Not supported by hairs */
- BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", input->attr_id, use_geom ? "g" : "");
- }
- else if (input->attr_type == CD_ORCO) {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = OrcoTexCoFactors[0].xyz + (ModelMatrixInverse * "
- "vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1].xyz;\n",
- input->attr_id,
- use_geom ? "g" : "");
- /* TODO: fix ORCO with modifiers. */
- }
- else {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = hair_get_customdata_%s(att%d);\n",
- input->attr_id,
- use_geom ? "g" : "",
- gpu_data_type_to_string(input->type),
- input->attr_id);
- }
- }
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ if (attr->type == CD_TANGENT) {
+ /* Not supported by hairs */
+ BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", attr->id, use_geom ? "g" : "");
+ }
+ else if (attr->type == CD_ORCO) {
+ BLI_dynstr_appendf(ds,
+ "\tvar%d%s = OrcoTexCoFactors[0].xyz + (ModelMatrixInverse * "
+ "vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1].xyz;\n",
+ attr->id,
+ use_geom ? "g" : "");
+ /* TODO: fix ORCO with modifiers. */
+ }
+ else {
+ BLI_dynstr_appendf(ds,
+ "\tvar%d%s = hair_get_customdata_%s(att%d);\n",
+ attr->id,
+ use_geom ? "g" : "",
+ gpu_data_type_to_string(attr->gputype),
+ attr->id);
}
}
@@ -837,49 +822,43 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
BLI_dynstr_append(ds, "\tbarycentricPosg = (ModelMatrix * vec4(position, 1.0)).xyz;\n");
}
- for (node = nodes->first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- if (input->attr_type == CD_TANGENT) { /* silly exception */
- BLI_dynstr_appendf(ds,
- "\tvar%d%s.xyz = transpose(mat3(ModelMatrixInverse)) * att%d.xyz;\n",
- input->attr_id,
- use_geom ? "g" : "",
- input->attr_id);
- BLI_dynstr_appendf(
- ds, "\tvar%d%s.w = att%d.w;\n", input->attr_id, use_geom ? "g" : "", input->attr_id);
- /* Normalize only if vector is not null. */
- BLI_dynstr_appendf(ds,
- "\tfloat lvar%d = dot(var%d%s.xyz, var%d%s.xyz);\n",
- input->attr_id,
- input->attr_id,
- use_geom ? "g" : "",
- input->attr_id,
- use_geom ? "g" : "");
- BLI_dynstr_appendf(ds,
- "\tvar%d%s.xyz *= (lvar%d > 0.0) ? inversesqrt(lvar%d) : 1.0;\n",
- input->attr_id,
- use_geom ? "g" : "",
- input->attr_id,
- input->attr_id);
- }
- else if (input->attr_type == CD_ORCO) {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = OrcoTexCoFactors[0].xyz + position *"
- " OrcoTexCoFactors[1].xyz;\n",
- input->attr_id,
- use_geom ? "g" : "");
- /* See mesh_create_loop_orco() for explanation. */
- BLI_dynstr_appendf(ds,
- "\tif (orco.w == 0.0) { var%d%s = orco.xyz * 0.5 + 0.5; }\n",
- input->attr_id,
- use_geom ? "g" : "");
- }
- else {
- BLI_dynstr_appendf(
- ds, "\tvar%d%s = att%d;\n", input->attr_id, use_geom ? "g" : "", input->attr_id);
- }
- }
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ if (attr->type == CD_TANGENT) { /* silly exception */
+ BLI_dynstr_appendf(ds,
+ "\tvar%d%s.xyz = transpose(mat3(ModelMatrixInverse)) * att%d.xyz;\n",
+ attr->id,
+ use_geom ? "g" : "",
+ attr->id);
+ BLI_dynstr_appendf(ds, "\tvar%d%s.w = att%d.w;\n", attr->id, use_geom ? "g" : "", attr->id);
+ /* Normalize only if vector is not null. */
+ BLI_dynstr_appendf(ds,
+ "\tfloat lvar%d = dot(var%d%s.xyz, var%d%s.xyz);\n",
+ attr->id,
+ attr->id,
+ use_geom ? "g" : "",
+ attr->id,
+ use_geom ? "g" : "");
+ BLI_dynstr_appendf(ds,
+ "\tvar%d%s.xyz *= (lvar%d > 0.0) ? inversesqrt(lvar%d) : 1.0;\n",
+ attr->id,
+ use_geom ? "g" : "",
+ attr->id,
+ attr->id);
+ }
+ else if (attr->type == CD_ORCO) {
+ BLI_dynstr_appendf(ds,
+ "\tvar%d%s = OrcoTexCoFactors[0].xyz + position *"
+ " OrcoTexCoFactors[1].xyz;\n",
+ attr->id,
+ use_geom ? "g" : "");
+ /* See mesh_create_loop_orco() for explanation. */
+ BLI_dynstr_appendf(ds,
+ "\tif (orco.w == 0.0) { var%d%s = orco.xyz * 0.5 + 0.5; }\n",
+ attr->id,
+ use_geom ? "g" : "");
+ }
+ else {
+ BLI_dynstr_appendf(ds, "\tvar%d%s = att%d;\n", attr->id, use_geom ? "g" : "", attr->id);
}
}
BLI_dynstr_append(ds, "#endif /* HAIR_SHADER */\n");
@@ -899,7 +878,9 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
return code;
}
-static char *code_generate_geometry(ListBase *nodes, const char *geom_code, const char *defines)
+static char *code_generate_geometry(GPUNodeGraph *graph,
+ const char *geom_code,
+ const char *defines)
{
DynStr *ds = BLI_dynstr_new();
GPUNode *node;
@@ -916,20 +897,19 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code, cons
BLI_dynstr_append(ds, "#define USE_ATTR\n");
/* Generate varying declarations. */
- for (node = nodes->first; node; node = node->next) {
+ for (node = graph->nodes.first; node; node = node->next) {
for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_BUILTIN) {
builtins |= input->builtin;
}
- if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- BLI_dynstr_appendf(
- ds, "in %s var%dg[];\n", gpu_data_type_to_string(input->type), input->attr_id);
- BLI_dynstr_appendf(
- ds, "out %s var%d;\n", gpu_data_type_to_string(input->type), input->attr_id);
- }
}
}
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ BLI_dynstr_appendf(ds, "in %s var%dg[];\n", gpu_data_type_to_string(attr->gputype), attr->id);
+ BLI_dynstr_appendf(ds, "out %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id);
+ }
+
if (builtins & GPU_BARYCENTRIC_TEXCO) {
BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
BLI_dynstr_append(ds, "in vec2 barycentricTexCog[];\n");
@@ -1032,13 +1012,9 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code, cons
BLI_dynstr_append(ds, "#endif\n");
}
- for (node = nodes->first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
- /* TODO let shader choose what to do depending on what the attribute is. */
- BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", input->attr_id, input->attr_id);
- }
- }
+ for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) {
+ /* TODO let shader choose what to do depending on what the attribute is. */
+ BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", attr->id, attr->id);
}
BLI_dynstr_append(ds, "}\n");
@@ -1053,94 +1029,6 @@ GPUShader *GPU_pass_shader_get(GPUPass *pass)
return pass->shader;
}
-/* Requested Attributes */
-
-static ListBase gpu_nodes_requested_attributes(ListBase *nodes)
-{
- ListBase attributes = {NULL};
- int num_attributes = 0;
-
- /* Convert attributes requested by node inputs to list, checking for
- * checking for duplicates and assigning id's starting from zero. */
- for (GPUNode *node = nodes->first; node; node = node->next) {
- for (GPUInput *input = node->inputs.first; input; input = input->next) {
- if (input->source != GPU_SOURCE_ATTR) {
- continue;
- }
-
- GPUMaterialAttribute *attr = attributes.first;
- for (; attr; attr = attr->next) {
- if (attr->type == input->attr_type && STREQ(attr->name, input->attr_name)) {
- break;
- }
- }
-
- /* Add new requested attribute if it's within GPU limits. */
- if (attr == NULL && num_attributes < GPU_MAX_ATTR) {
- attr = MEM_callocN(sizeof(*attr), __func__);
- attr->type = input->attr_type;
- STRNCPY(attr->name, input->attr_name);
- attr->id = num_attributes++;
- BLI_addtail(&attributes, attr);
-
- input->attr_id = attr->id;
- input->attr_first = true;
- }
- else if (attr != NULL) {
- input->attr_id = attr->id;
- }
- }
- }
-
- return attributes;
-}
-
-/* Requested Textures */
-
-static ListBase gpu_nodes_requested_textures(ListBase *nodes)
-{
- ListBase textures = {NULL};
- int num_textures = 0;
-
- /* Convert textures requested by node inputs to list, checking for
- * checking for duplicates and assigning id's starting from zero. */
- for (GPUNode *node = nodes->first; node; node = node->next) {
- for (GPUInput *input = node->inputs.first; input; input = input->next) {
- if (!codegen_input_has_texture(input)) {
- continue;
- }
-
- GPUMaterialTexture *tex = textures.first;
- for (; tex; tex = tex->next) {
- if (tex->ima == input->ima && tex->colorband == input->colorband &&
- tex->type == input->type) {
- break;
- }
- }
-
- if (tex == NULL) {
- tex = MEM_callocN(sizeof(*tex), __func__);
- tex->ima = input->ima;
- tex->iuser = input->iuser;
- tex->colorband = input->colorband;
- tex->id = num_textures++;
- tex->type = input->type;
- BLI_snprintf(tex->shadername, sizeof(tex->shadername), "samp%d", tex->id);
- BLI_addtail(&textures, tex);
-
- input->texid = tex->id;
- input->bindtex = true;
- }
- else {
- input->texid = tex->id;
- input->bindtex = false;
- }
- }
- }
-
- return textures;
-}
-
/* Pass create/free */
static bool gpu_pass_is_valid(GPUPass *pass)
@@ -1160,11 +1048,8 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
* generated VBOs are ready to accept the future shader. */
gpu_node_graph_prune_unused(graph);
- graph->attributes = gpu_nodes_requested_attributes(&graph->nodes);
- graph->textures = gpu_nodes_requested_textures(&graph->nodes);
-
/* generate code */
- char *fragmentgen = code_generate_fragment(material, &graph->nodes, graph->outlink->output);
+ char *fragmentgen = code_generate_fragment(material, graph);
/* Cache lookup: Reuse shaders already compiled */
uint32_t hash = gpu_pass_hash(fragmentgen, defines, &graph->attributes);
@@ -1186,8 +1071,8 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
GSet *used_libraries = gpu_material_used_libraries(material);
char *tmp = gpu_material_library_generate_code(used_libraries, frag_lib);
- char *geometrycode = code_generate_geometry(&graph->nodes, geom_code, defines);
- char *vertexcode = code_generate_vertex(&graph->nodes, vert_code, (geometrycode != NULL));
+ char *geometrycode = code_generate_geometry(graph, geom_code, defines);
+ char *vertexcode = code_generate_vertex(graph, vert_code, (geometrycode != NULL));
char *fragmentcode = BLI_strdupcat(tmp, fragmentgen);
MEM_freeN(fragmentgen);
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 62a5de7ebe6..d674f8600c2 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -1077,7 +1077,8 @@ void GPU_create_gl_tex(uint *bind,
glGenTextures(1, (GLuint *)bind);
glBindTexture(textarget, *bind);
- GLenum float_format = (!half_float && ima->flag & IMA_HIGH_BITDEPTH) ? GL_RGBA32F : GL_RGBA16F;
+ GLenum float_format = (!half_float && (ima && (ima->flag & IMA_HIGH_BITDEPTH))) ? GL_RGBA32F :
+ GL_RGBA16F;
GLenum internal_format = (frect) ? float_format : (use_srgb) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
if (textarget == GL_TEXTURE_2D) {
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index d8d3e5a2ff2..b2658839d67 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -207,11 +207,6 @@ GPUPass *GPU_material_get_pass(GPUMaterial *material)
return material->pass;
}
-ListBase *GPU_material_get_inputs(GPUMaterial *material)
-{
- return &material->graph.inputs;
-}
-
/* Return can be NULL if it's a world material. */
Material *GPU_material_get_material(GPUMaterial *material)
{
@@ -579,9 +574,9 @@ void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
}
}
-void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
+GPUNodeGraph *gpu_material_node_graph(GPUMaterial *material)
{
- BLI_addtail(&material->graph.nodes, node);
+ return &material->graph;
}
GSet *gpu_material_used_libraries(GPUMaterial *material)
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index b271ac48f75..de35b43109f 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -109,20 +109,20 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
input->link = link;
link->users++;
break;
+ case GPU_NODE_LINK_IMAGE:
+ case GPU_NODE_LINK_IMAGE_TILED:
case GPU_NODE_LINK_COLORBAND:
input->source = GPU_SOURCE_TEX;
- input->colorband = link->colorband;
+ input->texture = link->texture;
break;
- case GPU_NODE_LINK_IMAGE_BLENDER:
- case GPU_NODE_LINK_IMAGE_TILEMAP:
- input->source = GPU_SOURCE_TEX;
- input->ima = link->ima;
- input->iuser = link->iuser;
+ case GPU_NODE_LINK_IMAGE_TILED_MAPPING:
+ input->source = GPU_SOURCE_TEX_TILED_MAPPING;
+ input->texture = link->texture;
break;
case GPU_NODE_LINK_ATTR:
input->source = GPU_SOURCE_ATTR;
- input->attr_type = link->attr_type;
- BLI_strncpy(input->attr_name, link->attr_name, sizeof(input->attr_name));
+ input->attr = link->attr;
+ input->attr->gputype = type;
break;
case GPU_NODE_LINK_CONSTANT:
input->source = (type == GPU_CLOSURE) ? GPU_SOURCE_STRUCT : GPU_SOURCE_CONSTANT;
@@ -249,24 +249,97 @@ static void gpu_node_output(GPUNode *node, const eGPUType type, GPUNodeLink **li
BLI_addtail(&node->outputs, output);
}
-/* Creating Inputs */
+/* Attributes and Textures */
-GPUNodeLink *GPU_attribute(const CustomDataType type, const char *name)
+static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph,
+ CustomDataType type,
+ const char *name)
{
- GPUNodeLink *link = gpu_node_link_create();
- link->link_type = GPU_NODE_LINK_ATTR;
- link->attr_name = name;
/* Fall back to the UV layer, which matches old behavior. */
if (type == CD_AUTO_FROM_NAME && name[0] == '\0') {
- link->attr_type = CD_MTFACE;
+ type = CD_MTFACE;
}
- else {
- link->attr_type = type;
+
+ /* Find existing attribute. */
+ int num_attributes = 0;
+ GPUMaterialAttribute *attr = graph->attributes.first;
+ for (; attr; attr = attr->next) {
+ if (attr->type == type && STREQ(attr->name, name)) {
+ break;
+ }
+ num_attributes++;
+ }
+
+ /* Add new requested attribute if it's within GPU limits. */
+ if (attr == NULL && num_attributes < GPU_MAX_ATTR) {
+ attr = MEM_callocN(sizeof(*attr), __func__);
+ attr->type = type;
+ STRNCPY(attr->name, name);
+ attr->id = num_attributes;
+ BLI_addtail(&graph->attributes, attr);
+ }
+
+ if (attr != NULL) {
+ attr->users++;
+ }
+
+ return attr;
+}
+
+static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
+ Image *ima,
+ ImageUser *iuser,
+ struct GPUTexture **colorband,
+ GPUNodeLinkType link_type)
+{
+ /* Find existing texture. */
+ int num_textures = 0;
+ GPUMaterialTexture *tex = graph->textures.first;
+ for (; tex; tex = tex->next) {
+ if (tex->ima == ima && tex->colorband == colorband) {
+ break;
+ }
+ num_textures++;
}
+
+ /* Add new requested texture. */
+ if (tex == NULL) {
+ tex = MEM_callocN(sizeof(*tex), __func__);
+ tex->ima = ima;
+ tex->iuser = iuser;
+ tex->colorband = colorband;
+ BLI_snprintf(tex->sampler_name, sizeof(tex->sampler_name), "samp%d", num_textures);
+ if (ELEM(link_type, GPU_NODE_LINK_IMAGE_TILED, GPU_NODE_LINK_IMAGE_TILED_MAPPING)) {
+ BLI_snprintf(
+ tex->tiled_mapping_name, sizeof(tex->tiled_mapping_name), "tsamp%d", num_textures);
+ }
+ BLI_addtail(&graph->textures, tex);
+ }
+
+ tex->users++;
+
+ return tex;
+}
+
+/* Creating Inputs */
+
+GPUNodeLink *GPU_attribute(GPUMaterial *mat, const CustomDataType type, const char *name)
+{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, type, name);
+
+ if (attr == NULL) {
+ static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f};
+ return GPU_constant(zero_data);
+ }
+
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_ATTR;
+ link->attr = attr;
return link;
}
-GPUNodeLink *GPU_constant(float *num)
+GPUNodeLink *GPU_constant(const float *num)
{
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_CONSTANT;
@@ -274,7 +347,7 @@ GPUNodeLink *GPU_constant(float *num)
return link;
}
-GPUNodeLink *GPU_uniform(float *num)
+GPUNodeLink *GPU_uniform(const float *num)
{
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_UNIFORM;
@@ -282,21 +355,42 @@ GPUNodeLink *GPU_uniform(float *num)
return link;
}
-GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser)
+GPUNodeLink *GPU_image(GPUMaterial *mat, Image *ima, ImageUser *iuser)
{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
GPUNodeLink *link = gpu_node_link_create();
- link->link_type = GPU_NODE_LINK_IMAGE_BLENDER;
- link->ima = ima;
- link->iuser = iuser;
+ link->link_type = GPU_NODE_LINK_IMAGE;
+ link->texture = gpu_node_graph_add_texture(graph, ima, iuser, NULL, link->link_type);
+ return link;
+}
+
+GPUNodeLink *GPU_image_tiled(GPUMaterial *mat, Image *ima, ImageUser *iuser)
+{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_IMAGE_TILED;
+ link->texture = gpu_node_graph_add_texture(graph, ima, iuser, NULL, link->link_type);
+ return link;
+}
+
+GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, Image *ima, ImageUser *iuser)
+{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_IMAGE_TILED_MAPPING;
+ link->texture = gpu_node_graph_add_texture(graph, ima, iuser, NULL, link->link_type);
return link;
}
GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *row)
{
+ struct GPUTexture **colorband = gpu_material_ramp_texture_row_set(mat, size, pixels, row);
+ MEM_freeN(pixels);
+
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_COLORBAND;
- link->colorband = gpu_material_ramp_texture_row_set(mat, size, pixels, row);
- MEM_freeN(pixels);
+ link->texture = gpu_node_graph_add_texture(graph, NULL, NULL, colorband, link->link_type);
return link;
}
@@ -340,7 +434,8 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...)
}
va_end(params);
- gpu_material_add_node(mat, node);
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ BLI_addtail(&graph->nodes, node);
return true;
}
@@ -415,7 +510,8 @@ bool GPU_stack_link(GPUMaterial *material,
}
va_end(params);
- gpu_material_add_node(material, node);
+ GPUNodeGraph *graph = gpu_material_node_graph(material);
+ BLI_addtail(&graph->nodes, node);
return true;
}
@@ -435,6 +531,13 @@ static void gpu_inputs_free(ListBase *inputs)
GPUInput *input;
for (input = inputs->first; input; input = input->next) {
+ if (input->source == GPU_SOURCE_ATTR) {
+ input->attr->users--;
+ }
+ else if (ELEM(input->source, GPU_SOURCE_TEX, GPU_SOURCE_TEX_TILED_MAPPING)) {
+ input->texture->users--;
+ }
+
if (input->link) {
gpu_node_link_free(input->link);
}
@@ -469,7 +572,6 @@ void gpu_node_graph_free_nodes(GPUNodeGraph *graph)
gpu_node_free(node);
}
- gpu_inputs_free(&graph->inputs);
graph->outlink = NULL;
}
@@ -477,8 +579,8 @@ void gpu_node_graph_free_nodes(GPUNodeGraph *graph)
void gpu_node_graph_free(GPUNodeGraph *graph)
{
gpu_node_graph_free_nodes(graph);
- BLI_freelistN(&graph->attributes);
BLI_freelistN(&graph->textures);
+ BLI_freelistN(&graph->attributes);
}
/* Prune Unused Nodes */
@@ -507,15 +609,13 @@ static void gpu_nodes_tag(GPUNodeLink *link)
void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
{
- GPUNode *node, *next;
-
- for (node = graph->nodes.first; node; node = node->next) {
+ for (GPUNode *node = graph->nodes.first; node; node = node->next) {
node->tag = false;
}
gpu_nodes_tag(graph->outlink);
- for (node = graph->nodes.first; node; node = next) {
+ for (GPUNode *node = graph->nodes.first, *next = NULL; node; node = next) {
next = node->next;
if (!node->tag) {
@@ -523,4 +623,18 @@ void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
gpu_node_free(node);
}
}
+
+ for (GPUMaterialAttribute *attr = graph->attributes.first, *next = NULL; attr; attr = next) {
+ next = attr->next;
+ if (attr->users == 0) {
+ BLI_freelinkN(&graph->attributes, attr);
+ }
+ }
+
+ for (GPUMaterialTexture *tex = graph->textures.first, *next = NULL; tex; tex = next) {
+ next = tex->next;
+ if (tex->users == 0) {
+ BLI_freelinkN(&graph->textures, tex);
+ }
+ }
}
diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h
index 2ffde8dba39..9214bd7f1ba 100644
--- a/source/blender/gpu/intern/gpu_node_graph.h
+++ b/source/blender/gpu/intern/gpu_node_graph.h
@@ -19,6 +19,8 @@
/** \file
* \ingroup gpu
+ *
+ * Intermediate node graph for generating GLSL shaders.
*/
#ifndef __GPU_NODE_GRAPH_H__
@@ -45,6 +47,7 @@ typedef enum eGPUDataSource {
GPU_SOURCE_BUILTIN,
GPU_SOURCE_STRUCT,
GPU_SOURCE_TEX,
+ GPU_SOURCE_TEX_TILED_MAPPING,
} eGPUDataSource;
typedef enum {
@@ -53,8 +56,9 @@ typedef enum {
GPU_NODE_LINK_BUILTIN,
GPU_NODE_LINK_COLORBAND,
GPU_NODE_LINK_CONSTANT,
- GPU_NODE_LINK_IMAGE_BLENDER,
- GPU_NODE_LINK_IMAGE_TILEMAP,
+ GPU_NODE_LINK_IMAGE,
+ GPU_NODE_LINK_IMAGE_TILED,
+ GPU_NODE_LINK_IMAGE_TILED_MAPPING,
GPU_NODE_LINK_OUTPUT,
GPU_NODE_LINK_UNIFORM,
} GPUNodeLinkType;
@@ -79,7 +83,7 @@ struct GPUNodeLink {
union {
/* GPU_NODE_LINK_CONSTANT | GPU_NODE_LINK_UNIFORM */
- float *data;
+ const float *data;
/* GPU_NODE_LINK_BUILTIN */
eGPUBuiltin builtin;
/* GPU_NODE_LINK_COLORBAND */
@@ -87,15 +91,9 @@ struct GPUNodeLink {
/* GPU_NODE_LINK_OUTPUT */
struct GPUOutput *output;
/* GPU_NODE_LINK_ATTR */
- struct {
- const char *attr_name;
- CustomDataType attr_type;
- };
- /* GPU_NODE_LINK_IMAGE_BLENDER | GPU_NODE_LINK_IMAGE_TILEMAP */
- struct {
- struct Image *ima;
- struct ImageUser *iuser;
- };
+ struct GPUMaterialAttribute *attr;
+ /* GPU_NODE_LINK_IMAGE_BLENDER */
+ struct GPUMaterialTexture *texture;
};
};
@@ -118,35 +116,16 @@ typedef struct GPUInput {
eGPUDataSource source; /* data source */
- int shaderloc; /* id from opengl */
- char shadername[32]; /* name in shader */
-
/* Content based on eGPUDataSource */
union {
/* GPU_SOURCE_CONSTANT | GPU_SOURCE_UNIFORM */
float vec[16]; /* vector data */
/* GPU_SOURCE_BUILTIN */
eGPUBuiltin builtin; /* builtin uniform */
- /* GPU_SOURCE_TEX */
- struct {
- struct GPUTexture **colorband; /* input texture, only set at runtime */
- struct Image *ima; /* image */
- struct ImageUser *iuser; /* image user */
- bool bindtex; /* input is responsible for binding the texture? */
- int texid; /* number for multitexture, starting from zero */
- eGPUType textype; /* texture type (2D, 1D Array ...) */
- };
+ /* GPU_SOURCE_TEX | GPU_SOURCE_TEX_TILED_MAPPING */
+ struct GPUMaterialTexture *texture;
/* GPU_SOURCE_ATTR */
- struct {
- /** Attribute name. */
- char attr_name[MAX_CUSTOMDATA_LAYER_NAME];
- /** ID for vertex attributes. */
- int attr_id;
- /** This is the first one that is bound. */
- bool attr_first;
- /** Attribute type. */
- CustomDataType attr_type;
- };
+ struct GPUMaterialAttribute *attr;
};
} GPUInput;
@@ -154,8 +133,7 @@ typedef struct GPUNodeGraph {
/* Nodes */
ListBase nodes;
- /* Inputs and output. */
- ListBase inputs;
+ /* Output. */
GPUNodeLink *outlink;
/* Requested attributes and textures. */
@@ -171,7 +149,7 @@ void gpu_node_graph_free(GPUNodeGraph *graph);
/* Material calls */
-void gpu_material_add_node(struct GPUMaterial *material, struct GPUNode *node);
+struct GPUNodeGraph *gpu_material_node_graph(struct GPUMaterial *material);
struct GPUTexture **gpu_material_ramp_texture_row_set(struct GPUMaterial *mat,
int size,
float *pixels,
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 6caa0ac5a74..670a6c46187 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -1096,6 +1096,8 @@ typedef enum eChildOf_Flags {
CHILDOF_SIZEY = (1 << 7),
CHILDOF_SIZEZ = (1 << 8),
CHILDOF_ALL = 511,
+ /* Temporary flag used by the Set Inverse operator. */
+ CHILDOF_SET_INVERSE = (1 << 9),
} eChildOf_Flags;
/* Pivot Constraint */
@@ -1147,6 +1149,8 @@ typedef enum eCameraSolver_Flags {
/* ObjectSolver Constraint -> flag */
typedef enum eObjectSolver_Flags {
OBJECTSOLVER_ACTIVECLIP = (1 << 0),
+ /* Temporary flag used by the Set Inverse operator. */
+ OBJECTSOLVER_SET_INVERSE = (1 << 1),
} eObjectSolver_Flags;
/* ObjectSolver Constraint -> flag */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index b142939eaeb..bfa7400f926 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -124,7 +124,7 @@ struct CustomData_MeshMasks;
typedef struct Object_Runtime {
/**
* The custom data layer mask that was last used
- * to calculate mesh_eval and mesh_deform_eval.
+ * to calculate data_eval and mesh_deform_eval.
*/
CustomData_MeshMasks last_data_mask;
@@ -141,25 +141,25 @@ typedef struct Object_Runtime {
char _pad1[3];
/**
- * Denotes whether the evaluated mesh is owned by this object or is referenced and owned by
+ * Denotes whether the evaluated data is owned by this object or is referenced and owned by
* somebody else.
*/
- char is_mesh_eval_owned;
+ char is_data_eval_owned;
/** Axis aligned boundbox (in localspace). */
struct BoundBox *bb;
/**
- * Original mesh pointer, before object->data was changed to point
- * to mesh_eval.
+ * Original data pointer, before object->data was changed to point
+ * to data_eval.
* Is assigned by dependency graph's copy-on-write evaluation.
*/
- struct Mesh *mesh_orig;
+ struct ID *data_orig;
/**
- * Mesh structure created during object evaluation.
+ * Object data structure created during object evaluation.
* It has all modifiers applied.
*/
- struct Mesh *mesh_eval;
+ struct ID *data_eval;
/**
* Mesh structure created during object evaluation.
* It has deformation only modifiers applied on it.
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 02aec9527f0..a219bbcfc8e 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -155,7 +155,7 @@ static EnumPropertyItem rna_enum_gpencil_brush_eraser_modes_items[] = {
{GP_BRUSH_ERASER_SOFT,
"SOFT",
0,
- "Dissolve,",
+ "Dissolve",
"Erase strokes, fading their points strength and thickness"},
{GP_BRUSH_ERASER_HARD, "HARD", 0, "Point", "Erase stroke points"},
{GP_BRUSH_ERASER_STROKE, "STROKE", 0, "Stroke", "Erase entire strokes"},
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 8e57de9baeb..64e6fc9059c 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -973,11 +973,18 @@ static void rna_def_constraint_childof(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Scale Z", "Use Z Scale of Parent");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+ prop = RNA_def_property(srna, "set_inverse_pending", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CHILDOF_SET_INVERSE);
+ RNA_def_property_ui_text(
+ prop, "Set Inverse Pending", "Set to true to request recalculation of the inverse matrix");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
prop = RNA_def_property(srna, "inverse_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "invmat");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Inverse Matrix", "Transformation matrix to apply before");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
}
static void rna_def_constraint_python(BlenderRNA *brna)
@@ -3152,6 +3159,12 @@ static void rna_def_constraint_object_solver(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Active Clip", "Use active clip defined in scene");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+ prop = RNA_def_property(srna, "set_inverse_pending", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", OBJECTSOLVER_SET_INVERSE);
+ RNA_def_property_ui_text(
+ prop, "Set Inverse Pending", "Set to true to request recalculation of the inverse matrix");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
/* object */
prop = RNA_def_property(srna, "object", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "object");
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 9a4048e6aaa..cc0ebd8e6b2 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -5635,7 +5635,7 @@ static void rna_def_modifier_laplaciandeform(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "anchor_grp_name");
RNA_def_property_ui_text(
- prop, "Vertex Group for Anchors", "Name of Vertex Group which determines Anchors");
+ prop, "Anchor Weights", "Name of Vertex Group which determines Anchors");
RNA_def_property_string_funcs(
prop, NULL, NULL, "rna_LaplacianDeformModifier_anchor_grp_name_set");
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 5552de00be8..cbeb8f17991 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -487,7 +487,7 @@ static Object *eval_object_ensure(Object *ob,
ReportList *reports,
PointerRNA *rnaptr_depsgraph)
{
- if (ob->runtime.mesh_eval == NULL) {
+ if (ob->runtime.data_eval == NULL) {
Object *ob_orig = ob;
Depsgraph *depsgraph = rnaptr_depsgraph != NULL ? rnaptr_depsgraph->data : NULL;
if (depsgraph == NULL) {
@@ -496,7 +496,7 @@ static Object *eval_object_ensure(Object *ob,
if (depsgraph != NULL) {
ob = DEG_get_evaluated_object(depsgraph, ob);
}
- if (ob == NULL || ob->runtime.mesh_eval == NULL) {
+ if (ob == NULL || BKE_object_get_evaluated_mesh(ob) == NULL) {
BKE_reportf(
reports, RPT_ERROR, "Object '%s' has no evaluated mesh data", ob_orig->id.name + 2);
return NULL;
@@ -521,8 +521,7 @@ static void rna_Object_ray_cast(Object *ob,
/* TODO(sergey): This isn't very reliable check. It is possible to have non-NULL pointer
* but which is out of date, and possibly dangling one. */
- if (ob->runtime.mesh_eval == NULL &&
- (ob = eval_object_ensure(ob, C, reports, rnaptr_depsgraph)) == NULL) {
+ if ((ob = eval_object_ensure(ob, C, reports, rnaptr_depsgraph)) == NULL) {
return;
}
@@ -538,7 +537,8 @@ static void rna_Object_ray_cast(Object *ob,
/* No need to managing allocation or freeing of the BVH data.
* This is generated and freed as needed. */
- BKE_bvhtree_from_mesh_get(&treeData, ob->runtime.mesh_eval, BVHTREE_FROM_LOOPTRI, 4);
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ BKE_bvhtree_from_mesh_get(&treeData, mesh_eval, BVHTREE_FROM_LOOPTRI, 4);
/* may fail if the mesh has no faces, in that case the ray-cast misses */
if (treeData.tree != NULL) {
@@ -559,8 +559,7 @@ static void rna_Object_ray_cast(Object *ob,
copy_v3_v3(r_location, hit.co);
copy_v3_v3(r_normal, hit.no);
- *r_index = mesh_looptri_to_poly_index(ob->runtime.mesh_eval,
- &treeData.looptri[hit.index]);
+ *r_index = mesh_looptri_to_poly_index(mesh_eval, &treeData.looptri[hit.index]);
}
}
@@ -589,14 +588,14 @@ static void rna_Object_closest_point_on_mesh(Object *ob,
{
BVHTreeFromMesh treeData = {NULL};
- if (ob->runtime.mesh_eval == NULL &&
- (ob = eval_object_ensure(ob, C, reports, rnaptr_depsgraph)) == NULL) {
+ if ((ob = eval_object_ensure(ob, C, reports, rnaptr_depsgraph)) == NULL) {
return;
}
/* No need to managing allocation or freeing of the BVH data.
* this is generated and freed as needed. */
- BKE_bvhtree_from_mesh_get(&treeData, ob->runtime.mesh_eval, BVHTREE_FROM_LOOPTRI, 4);
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ BKE_bvhtree_from_mesh_get(&treeData, mesh_eval, BVHTREE_FROM_LOOPTRI, 4);
if (treeData.tree == NULL) {
BKE_reportf(reports,
@@ -617,8 +616,7 @@ static void rna_Object_closest_point_on_mesh(Object *ob,
copy_v3_v3(r_location, nearest.co);
copy_v3_v3(r_normal, nearest.no);
- *r_index = mesh_looptri_to_poly_index(ob->runtime.mesh_eval,
- &treeData.looptri[nearest.index]);
+ *r_index = mesh_looptri_to_poly_index(mesh_eval, &treeData.looptri[nearest.index]);
goto finally;
}
@@ -659,8 +657,7 @@ void rna_Object_me_eval_info(
switch (type) {
case 1:
case 2:
- if (ob->runtime.mesh_eval == NULL &&
- (ob = eval_object_ensure(ob, C, NULL, rnaptr_depsgraph)) == NULL) {
+ if ((ob = eval_object_ensure(ob, C, NULL, rnaptr_depsgraph)) == NULL) {
return;
}
}
@@ -675,7 +672,7 @@ void rna_Object_me_eval_info(
me_eval = ob->runtime.mesh_deform_eval;
break;
case 2:
- me_eval = ob->runtime.mesh_eval;
+ me_eval = BKE_object_get_evaluated_mesh(ob);
break;
}
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index a3cf6fcd0b7..2031c444c9a 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -128,14 +128,12 @@ static int engine_get_preview_pixel_size(RenderEngine *UNUSED(engine), Scene *sc
static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *UNUSED(scene))
{
- GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_COLOR);
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE);
GPU_shader_bind(shader);
int img_loc = GPU_shader_get_uniform_ensure(shader, "image");
- int color_loc = GPU_shader_get_uniform_ensure(shader, "color");
GPU_shader_uniform_int(shader, img_loc, 0);
- GPU_shader_uniform_vector(shader, color_loc, 3, 1, (float[3]){1.0f, 1.0f, 1.0f});
}
static void engine_unbind_display_space_shader(RenderEngine *UNUSED(engine))
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 3d5d5091bf1..762c1985fa9 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1280,9 +1280,26 @@ static const EnumPropertyItem *rna_3DViewShading_render_pass_itemf(bContext *C,
RNA_enum_item_add(&result, &totitem, item);
}
}
+
+ RNA_enum_item_end(&result, &totitem);
*r_free = true;
return result;
}
+static int rna_3DViewShading_render_pass_get(PointerRNA *ptr)
+{
+ View3DShading *shading = (View3DShading *)ptr->data;
+ eViewLayerEEVEEPassType result = shading->render_pass;
+ Scene *scene = rna_3DViewShading_scene(ptr);
+
+ if (result == EEVEE_RENDER_PASS_AO && ((scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0)) {
+ result = EEVEE_RENDER_PASS_COMBINED;
+ }
+ if (result == EEVEE_RENDER_PASS_BLOOM && ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
+ result = EEVEE_RENDER_PASS_COMBINED;
+ }
+
+ return result;
+}
static void rna_SpaceView3D_use_local_collections_update(bContext *C, PointerRNA *ptr)
{
@@ -3379,7 +3396,8 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "render_pass");
RNA_def_property_enum_items(prop, rna_enum_view3dshading_render_pass_type_items);
RNA_def_property_ui_text(prop, "Render Pass", "Render Pass to show in the viewport");
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_3DViewShading_render_pass_itemf");
+ RNA_def_property_enum_funcs(
+ prop, "rna_3DViewShading_render_pass_get", NULL, "rna_3DViewShading_render_pass_itemf");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 9615c6f01e0..93d03720058 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -276,7 +276,7 @@ void node_shader_gpu_bump_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink *
void node_shader_gpu_default_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink **link)
{
if (!*link) {
- *link = GPU_attribute(CD_ORCO, "");
+ *link = GPU_attribute(mat, CD_ORCO, "");
GPU_link(mat, "generated_texco", GPU_builtin(GPU_VIEW_POSITION), *link, link);
node_shader_gpu_bump_tex_coord(mat, node, link);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_attribute.c b/source/blender/nodes/shader/nodes/node_shader_attribute.c
index ecb8c53c312..757db5fe8b3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_attribute.c
+++ b/source/blender/nodes/shader/nodes/node_shader_attribute.c
@@ -66,7 +66,7 @@ static int node_shader_gpu_attribute(GPUMaterial *mat,
GPU_builtin(GPU_VOLUME_TEMPERATURE));
}
else {
- GPUNodeLink *cd_attr = GPU_attribute(CD_AUTO_FROM_NAME, attr->name);
+ GPUNodeLink *cd_attr = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->name);
GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr);
/* for each output. */
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c
index 6b23fec5f18..b1ee3c4806a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c
@@ -46,7 +46,8 @@ static int node_shader_gpu_geometry(GPUMaterial *mat,
GPUNodeLink *bary_link = (!out[5].hasoutput) ? GPU_constant(val) :
GPU_builtin(GPU_BARYCENTRIC_TEXCO);
/* Opti: don't request orco if not needed. */
- GPUNodeLink *orco_link = (!out[2].hasoutput) ? GPU_constant(val) : GPU_attribute(CD_ORCO, "");
+ GPUNodeLink *orco_link = (!out[2].hasoutput) ? GPU_constant(val) :
+ GPU_attribute(mat, CD_ORCO, "");
const bool success = GPU_stack_link(mat,
node,
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
index 006f15f40a1..0f3ffe51706 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
@@ -92,7 +92,7 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
GPU_link(mat,
"node_normal_map",
GPU_builtin(GPU_OBJECT_INFO),
- GPU_attribute(CD_TANGENT, nm->uv_map),
+ GPU_attribute(mat, CD_TANGENT, nm->uv_map),
GPU_builtin(GPU_WORLD_NORMAL),
newnormal,
&newnormal);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.c b/source/blender/nodes/shader/nodes/node_shader_tangent.c
index 478b9524737..474db465d87 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tangent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tangent.c
@@ -43,10 +43,10 @@ static int node_shader_gpu_tangent(GPUMaterial *mat,
if (attr->direction_type == SHD_TANGENT_UVMAP) {
return GPU_stack_link(
- mat, node, "node_tangentmap", in, out, GPU_attribute(CD_TANGENT, attr->uv_map));
+ mat, node, "node_tangentmap", in, out, GPU_attribute(mat, CD_TANGENT, attr->uv_map));
}
else {
- GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
+ GPUNodeLink *orco = GPU_attribute(mat, CD_ORCO, "");
if (attr->axis == SHD_TANGENT_AXIS_X) {
GPU_link(mat, "tangent_orco_x", orco, &orco);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
index 3c1a2280aae..81a5ee31f7d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
@@ -47,8 +47,8 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat,
/* Opti: don't request orco if not needed. */
GPUNodeLink *orco = (!out[0].hasoutput) ? GPU_constant((float[4]){0.0f, 0.0f, 0.0f, 0.0f}) :
- GPU_attribute(CD_ORCO, "");
- GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, "");
+ GPU_attribute(mat, CD_ORCO, "");
+ GPUNodeLink *mtface = GPU_attribute(mat, CD_MTFACE, "");
GPUNodeLink *viewpos = GPU_builtin(GPU_VIEW_POSITION);
GPUNodeLink *worldnor = GPU_builtin(GPU_WORLD_NORMAL);
GPUNodeLink *texcofacs = GPU_builtin(GPU_CAMERA_TEXCO_FACTORS);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 6c380efe0b2..d2615d76345 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -88,7 +88,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
"node_tex_environment_equirectangular",
in[0].link,
GPU_constant(&clamp_size),
- GPU_image(ima, iuser),
+ GPU_image(mat, ima, iuser),
&in[0].link);
}
else {
@@ -103,7 +103,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_linear_no_mip",
in[0].link,
- GPU_image(ima, iuser),
+ GPU_image(mat, ima, iuser),
&out[0].link,
&outalpha);
break;
@@ -111,13 +111,17 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_nearest",
in[0].link,
- GPU_image(ima, iuser),
+ GPU_image(mat, ima, iuser),
&out[0].link,
&outalpha);
break;
default:
- GPU_link(
- mat, "node_tex_image_cubic", in[0].link, GPU_image(ima, iuser), &out[0].link, &outalpha);
+ GPU_link(mat,
+ "node_tex_image_cubic",
+ in[0].link,
+ GPU_image(mat, ima, iuser),
+ &out[0].link,
+ &outalpha);
break;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index 781fd1eb579..ebc852486dc 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -123,26 +123,21 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
}
if (!*texco) {
- *texco = GPU_attribute(CD_MTFACE, "");
+ *texco = GPU_attribute(mat, CD_MTFACE, "");
node_shader_gpu_bump_tex_coord(mat, node, texco);
}
node_shader_gpu_tex_mapping(mat, node, in, out);
if (ima->source == IMA_SRC_TILED) {
- /* The tiled shader needs both the tile array itself as well as the mapping from tile to array
- * position. Which of these to allocate is automatically decided based on the shader argument
- * type, so here the first GPU_image(ima, iuser) will resolve to the array and the second to
- * the mapping since the third argument in the shader has type sampler2DArray while
- * the fourth is sampler1DArray.
- */
+ /* UDIM tiles needs a samper2DArray and sampler1DArray for tile mapping. */
GPU_stack_link(mat,
node,
names_tiled[tex->interpolation],
in,
out,
- GPU_image(ima, iuser),
- GPU_image(ima, iuser));
+ GPU_image_tiled(mat, ima, iuser),
+ GPU_image_tiled_mapping(mat, ima, iuser));
}
else {
switch (tex->projection) {
@@ -157,20 +152,21 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser));
break;
case SHD_PROJ_BOX:
vnor = GPU_builtin(GPU_WORLD_NORMAL);
ob_mat = GPU_builtin(GPU_OBJECT_MATRIX);
blend = GPU_uniform(&tex->projection_blend);
- gpu_image = GPU_image(ima, iuser);
+ gpu_image = GPU_image(mat, ima, iuser);
/* equivalent to normal_world_to_object */
GPU_link(mat, "normal_transform_transposed_m4v3", vnor, ob_mat, &norm);
- GPU_link(mat, gpu_node_name, *texco, norm, GPU_image(ima, iuser), &col1, &col2, &col3);
+ GPU_link(
+ mat, gpu_node_name, *texco, norm, GPU_image(mat, ima, iuser), &col1, &col2, &col3);
GPU_stack_link(
mat, node, "node_tex_image_box", in, out, norm, col1, col2, col3, gpu_image, blend);
break;
@@ -184,9 +180,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser));
break;
case SHD_PROJ_TUBE:
@@ -198,9 +194,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser));
break;
}
@@ -208,7 +204,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
if (do_texco_clip) {
gpu_node_name = names_clip[tex->interpolation];
in[0].link = input_coords;
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser), out[0].link);
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser), out[0].link);
}
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
index b1fb0cad4b2..0a576e465fa 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
@@ -63,7 +63,7 @@ static int node_shader_gpu_tex_sky(GPUMaterial *mat,
GPUNodeStack *out)
{
if (!in[0].link) {
- in[0].link = GPU_attribute(CD_ORCO, "");
+ in[0].link = GPU_attribute(mat, CD_ORCO, "");
}
node_shader_gpu_tex_mapping(mat, node, in, out);
diff --git a/source/blender/nodes/shader/nodes/node_shader_uvmap.c b/source/blender/nodes/shader/nodes/node_shader_uvmap.c
index a2e47735490..f01542be44a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_uvmap.c
+++ b/source/blender/nodes/shader/nodes/node_shader_uvmap.c
@@ -41,7 +41,7 @@ static int node_shader_gpu_uvmap(GPUMaterial *mat,
GPUNodeStack *out)
{
NodeShaderUVMap *attr = node->storage;
- GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, attr->uv_map);
+ GPUNodeLink *mtface = GPU_attribute(mat, CD_MTFACE, attr->uv_map);
GPU_stack_link(mat, node, "node_uvmap", in, out, mtface);
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
index ac8b49c4572..df303b2d3f1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
@@ -60,7 +60,7 @@ static int gpu_shader_vector_displacement(GPUMaterial *mat,
"node_vector_displacement_tangent",
in,
out,
- GPU_attribute(CD_TANGENT, ""),
+ GPU_attribute(mat, CD_TANGENT, ""),
GPU_builtin(GPU_WORLD_NORMAL),
GPU_builtin(GPU_OBJECT_MATRIX),
GPU_builtin(GPU_VIEW_MATRIX));
diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c b/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
index 8848fc37c66..98d575cece2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
@@ -39,7 +39,7 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
GPUNodeStack *out)
{
NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage;
- GPUNodeLink *vertexColorLink = GPU_attribute(CD_MCOL, vertexColor->layer_name);
+ GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_MCOL, vertexColor->layer_name);
return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
}
diff --git a/source/blender/usd/intern/usd_writer_mesh.cc b/source/blender/usd/intern/usd_writer_mesh.cc
index bc3bc06f8a6..74005afaf31 100644
--- a/source/blender/usd/intern/usd_writer_mesh.cc
+++ b/source/blender/usd/intern/usd_writer_mesh.cc
@@ -483,7 +483,7 @@ USDMeshWriter::USDMeshWriter(const USDExporterContext &ctx) : USDGenericMeshWrit
Mesh *USDMeshWriter::get_export_mesh(Object *object_eval, bool & /*r_needsfree*/)
{
- return object_eval->runtime.mesh_eval;
+ return BKE_object_get_evaluated_mesh(object_eval);
}
} // namespace USD
diff --git a/source/blender/windowmanager/intern/wm_keymap_utils.c b/source/blender/windowmanager/intern/wm_keymap_utils.c
index 4603f14729d..5e6b55a508e 100644
--- a/source/blender/windowmanager/intern/wm_keymap_utils.c
+++ b/source/blender/windowmanager/intern/wm_keymap_utils.c
@@ -318,7 +318,7 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
}
/* Paint Face Mask */
else if (STRPREFIX(opname, "PAINT_OT_face_select")) {
- km = WM_keymap_find_all(C, "Face Mask", 0, 0);
+ km = WM_keymap_find_all(C, "Paint Face Mask (Weight, Vertex, Texture)", 0, 0);
}
else if (STRPREFIX(opname, "PAINT_OT")) {
/* check for relevant mode */