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
path: root/source
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2020-09-11 01:43:08 +0300
committerHans Goudey <h.goudey@me.com>2020-09-11 01:43:08 +0300
commiteabba50141477b9d35f00e5790052973a2f152d8 (patch)
treef2a06d8360751efb20f96fef3acc949a69964c68 /source
parent1b5f355af8a60347e880da19bd84dfdaea1a2d9e (diff)
parenta444b38fa37d7e6e7b5b3e792da3b3bb8dc6b3b5 (diff)
Merge branch 'property-search-button-label-pointer' into property-search-move-context-to-panel
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_gpencil_geom.h5
-rw-r--r--source/blender/blenkernel/intern/armature.c130
-rw-r--r--source/blender/blenkernel/intern/brush.c171
-rw-r--r--source/blender/blenkernel/intern/camera.c75
-rw-r--r--source/blender/blenkernel/intern/curve.c167
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.c126
-rw-r--r--source/blender/blenkernel/intern/image.c93
-rw-r--r--source/blender/blenkernel/intern/key.c108
-rw-r--r--source/blender/blenkernel/intern/light.c67
-rw-r--r--source/blender/blenkernel/intern/lightprobe.c36
-rw-r--r--source/blender/blenkernel/intern/mask.c161
-rw-r--r--source/blender/blenkernel/intern/material.c90
-rw-r--r--source/blender/blenkernel/intern/mball.c79
-rw-r--r--source/blender/blenkernel/intern/paint.c47
-rw-r--r--source/blender/blenkernel/intern/speaker.c49
-rw-r--r--source/blender/blenkernel/intern/world.c62
-rw-r--r--source/blender/blenlib/intern/path_util.c5
-rw-r--r--source/blender/blenloader/intern/readfile.c922
-rw-r--r--source/blender/blenloader/intern/versioning_290.c12
-rw-r--r--source/blender/blenloader/intern/writefile.c475
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c33
-rw-r--r--source/blender/editors/include/UI_interface_icons.h1
-rw-r--r--source/blender/editors/interface/interface_icons.c30
-rw-r--r--source/blender/editors/interface/interface_layout.c6
-rw-r--r--source/blender/editors/object/object_add.c26
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_boundary.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c136
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c58
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h12
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c225
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c416
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c2
-rw-r--r--source/blender/gpu/intern/gpu_batch.cc3
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc2
-rw-r--r--source/blender/gpu/intern/gpu_state.cc7
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc1
-rw-r--r--source/blender/gpu/opengl/gl_state.cc4
-rw-r--r--source/blender/makesdna/DNA_brush_types.h1
-rw-r--r--source/blender/makesdna/DNA_space_types.h1
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c60
-rw-r--r--source/blender/makesrna/intern/rna_brush.c7
-rw-r--r--source/blender/makesrna/intern/rna_particle.c4
-rw-r--r--source/blender/makesrna/intern/rna_space.c6
46 files changed, 1941 insertions, 1995 deletions
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index 3baa650c8f0..404cbbe1741 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -113,7 +113,7 @@ float BKE_gpencil_stroke_length(const struct bGPDstroke *gps, bool use_3d);
void BKE_gpencil_stroke_set_random_color(struct bGPDstroke *gps);
-void BKE_gpencil_convert_mesh(struct Main *bmain,
+bool BKE_gpencil_convert_mesh(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob_gp,
@@ -124,8 +124,7 @@ void BKE_gpencil_convert_mesh(struct Main *bmain,
const float matrix[4][4],
const int frame_offset,
const bool use_seams,
- const bool use_faces,
- const bool simple_material);
+ const bool use_faces);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index a653087f961..49ca25aca29 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -45,6 +45,7 @@
#include "DNA_scene_types.h"
#include "BKE_action.h"
+#include "BKE_anim_data.h"
#include "BKE_anim_visualization.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
@@ -62,6 +63,8 @@
#include "BIK_api.h"
+#include "BLO_read_write.h"
+
#include "CLG_log.h"
static CLG_LogRef LOG = {"bke.armature"};
@@ -165,6 +168,125 @@ static void armature_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void write_bone(BlendWriter *writer, Bone *bone)
+{
+ /* PATCH for upward compatibility after 2.37+ armature recode */
+ bone->size[0] = bone->size[1] = bone->size[2] = 1.0f;
+
+ /* Write this bone */
+ BLO_write_struct(writer, Bone, bone);
+
+ /* Write ID Properties -- and copy this comment EXACTLY for easy finding
+ * of library blocks that implement this.*/
+ if (bone->prop) {
+ IDP_BlendWrite(writer, bone->prop);
+ }
+
+ /* Write Children */
+ LISTBASE_FOREACH (Bone *, cbone, &bone->childbase) {
+ write_bone(writer, cbone);
+ }
+}
+
+static void armature_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ bArmature *arm = (bArmature *)id;
+ if (arm->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed datablocks. */
+ arm->bonehash = NULL;
+ arm->edbo = NULL;
+ /* Must always be cleared (armatures don't have their own edit-data). */
+ arm->needs_flush_to_id = 0;
+ arm->act_edbone = NULL;
+
+ BLO_write_id_struct(writer, bArmature, id_address, &arm->id);
+ BKE_id_blend_write(writer, &arm->id);
+
+ if (arm->adt) {
+ BKE_animdata_blend_write(writer, arm->adt);
+ }
+
+ /* Direct data */
+ LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
+ write_bone(writer, bone);
+ }
+ }
+}
+
+static void direct_link_bones(BlendDataReader *reader, Bone *bone)
+{
+ BLO_read_data_address(reader, &bone->parent);
+ BLO_read_data_address(reader, &bone->prop);
+ IDP_BlendDataRead(reader, &bone->prop);
+
+ BLO_read_data_address(reader, &bone->bbone_next);
+ BLO_read_data_address(reader, &bone->bbone_prev);
+
+ bone->flag &= ~(BONE_DRAW_ACTIVE | BONE_DRAW_LOCKED_WEIGHT);
+
+ BLO_read_list(reader, &bone->childbase);
+
+ LISTBASE_FOREACH (Bone *, child, &bone->childbase) {
+ direct_link_bones(reader, child);
+ }
+}
+
+static void armature_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ bArmature *arm = (bArmature *)id;
+ BLO_read_list(reader, &arm->bonebase);
+ arm->bonehash = NULL;
+ arm->edbo = NULL;
+ /* Must always be cleared (armatures don't have their own edit-data). */
+ arm->needs_flush_to_id = 0;
+
+ BLO_read_data_address(reader, &arm->adt);
+ BKE_animdata_blend_read_data(reader, arm->adt);
+
+ LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
+ direct_link_bones(reader, bone);
+ }
+
+ BLO_read_data_address(reader, &arm->act_bone);
+ arm->act_edbone = NULL;
+
+ BKE_armature_bone_hash_make(arm);
+}
+
+static void lib_link_bones(BlendLibReader *reader, Bone *bone)
+{
+ IDP_BlendReadLib(reader, bone->prop);
+
+ LISTBASE_FOREACH (Bone *, curbone, &bone->childbase) {
+ lib_link_bones(reader, curbone);
+ }
+}
+
+static void armature_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ bArmature *arm = (bArmature *)id;
+ LISTBASE_FOREACH (Bone *, curbone, &arm->bonebase) {
+ lib_link_bones(reader, curbone);
+ }
+}
+
+static void expand_bones(BlendExpander *expander, Bone *bone)
+{
+ IDP_BlendReadExpand(expander, bone->prop);
+
+ LISTBASE_FOREACH (Bone *, curBone, &bone->childbase) {
+ expand_bones(expander, curBone);
+ }
+}
+
+static void armature_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ bArmature *arm = (bArmature *)id;
+ LISTBASE_FOREACH (Bone *, curBone, &arm->bonebase) {
+ expand_bones(expander, curBone);
+ }
+}
+
IDTypeInfo IDType_ID_AR = {
.id_code = ID_AR,
.id_filter = FILTER_ID_AR,
@@ -182,10 +304,10 @@ IDTypeInfo IDType_ID_AR = {
.foreach_id = armature_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = armature_blend_write,
+ .blend_read_data = armature_blend_read_data,
+ .blend_read_lib = armature_blend_read_lib,
+ .blend_read_expand = armature_blend_read_expand,
};
/** \} */
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index b35d2b199aa..a816e4354b8 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -52,6 +52,8 @@
#include "RE_render_ext.h" /* RE_texture_evaluate */
+#include "BLO_read_write.h"
+
static void brush_init_data(ID *id)
{
Brush *brush = (Brush *)id;
@@ -196,6 +198,163 @@ static void brush_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_texture_mtex_foreach_id(data, &brush->mask_mtex);
}
+static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Brush *brush = (Brush *)id;
+ if (brush->id.us > 0 || BLO_write_is_undo(writer)) {
+ BLO_write_id_struct(writer, Brush, id_address, &brush->id);
+ BKE_id_blend_write(writer, &brush->id);
+
+ if (brush->curve) {
+ BKE_curvemapping_blend_write(writer, brush->curve);
+ }
+
+ if (brush->gpencil_settings) {
+ BLO_write_struct(writer, BrushGpencilSettings, brush->gpencil_settings);
+
+ if (brush->gpencil_settings->curve_sensitivity) {
+ BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_sensitivity);
+ }
+ if (brush->gpencil_settings->curve_strength) {
+ BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_strength);
+ }
+ if (brush->gpencil_settings->curve_jitter) {
+ BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_jitter);
+ }
+ if (brush->gpencil_settings->curve_rand_pressure) {
+ BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_pressure);
+ }
+ if (brush->gpencil_settings->curve_rand_strength) {
+ BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_strength);
+ }
+ if (brush->gpencil_settings->curve_rand_uv) {
+ BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_uv);
+ }
+ if (brush->gpencil_settings->curve_rand_hue) {
+ BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_hue);
+ }
+ if (brush->gpencil_settings->curve_rand_saturation) {
+ BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_saturation);
+ }
+ if (brush->gpencil_settings->curve_rand_value) {
+ BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_value);
+ }
+ }
+ if (brush->gradient) {
+ BLO_write_struct(writer, ColorBand, brush->gradient);
+ }
+ }
+}
+
+static void brush_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Brush *brush = (Brush *)id;
+
+ /* fallof curve */
+ BLO_read_data_address(reader, &brush->curve);
+
+ BLO_read_data_address(reader, &brush->gradient);
+
+ if (brush->curve) {
+ BKE_curvemapping_blend_read(reader, brush->curve);
+ }
+ else {
+ BKE_brush_curve_preset(brush, CURVE_PRESET_SHARP);
+ }
+
+ /* grease pencil */
+ BLO_read_data_address(reader, &brush->gpencil_settings);
+ if (brush->gpencil_settings != NULL) {
+ BLO_read_data_address(reader, &brush->gpencil_settings->curve_sensitivity);
+ BLO_read_data_address(reader, &brush->gpencil_settings->curve_strength);
+ BLO_read_data_address(reader, &brush->gpencil_settings->curve_jitter);
+
+ BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_pressure);
+ BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_strength);
+ BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_uv);
+ BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_hue);
+ BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_saturation);
+ BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_value);
+
+ if (brush->gpencil_settings->curve_sensitivity) {
+ BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_sensitivity);
+ }
+
+ if (brush->gpencil_settings->curve_strength) {
+ BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_strength);
+ }
+
+ if (brush->gpencil_settings->curve_jitter) {
+ BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_jitter);
+ }
+
+ if (brush->gpencil_settings->curve_rand_pressure) {
+ BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_pressure);
+ }
+
+ if (brush->gpencil_settings->curve_rand_strength) {
+ BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_strength);
+ }
+
+ if (brush->gpencil_settings->curve_rand_uv) {
+ BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_uv);
+ }
+
+ if (brush->gpencil_settings->curve_rand_hue) {
+ BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_hue);
+ }
+
+ if (brush->gpencil_settings->curve_rand_saturation) {
+ BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_saturation);
+ }
+
+ if (brush->gpencil_settings->curve_rand_value) {
+ BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_value);
+ }
+ }
+
+ brush->preview = NULL;
+ brush->icon_imbuf = NULL;
+}
+
+static void brush_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Brush *brush = (Brush *)id;
+
+ /* brush->(mask_)mtex.obj is ignored on purpose? */
+ BLO_read_id_address(reader, brush->id.lib, &brush->mtex.tex);
+ BLO_read_id_address(reader, brush->id.lib, &brush->mask_mtex.tex);
+ BLO_read_id_address(reader, brush->id.lib, &brush->clone.image);
+ BLO_read_id_address(reader, brush->id.lib, &brush->toggle_brush);
+ BLO_read_id_address(reader, brush->id.lib, &brush->paint_curve);
+
+ /* link default grease pencil palette */
+ if (brush->gpencil_settings != NULL) {
+ if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
+ BLO_read_id_address(reader, brush->id.lib, &brush->gpencil_settings->material);
+
+ if (!brush->gpencil_settings->material) {
+ brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED;
+ }
+ }
+ else {
+ brush->gpencil_settings->material = NULL;
+ }
+ }
+}
+
+static void brush_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Brush *brush = (Brush *)id;
+ BLO_expand(expander, brush->mtex.tex);
+ BLO_expand(expander, brush->mask_mtex.tex);
+ BLO_expand(expander, brush->clone.image);
+ BLO_expand(expander, brush->paint_curve);
+ if (brush->gpencil_settings != NULL) {
+ BLO_expand(expander, brush->gpencil_settings->material);
+ }
+}
+
IDTypeInfo IDType_ID_BR = {
.id_code = ID_BR,
.id_filter = FILTER_ID_BR,
@@ -213,10 +372,10 @@ IDTypeInfo IDType_ID_BR = {
.foreach_id = brush_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = brush_blend_write,
+ .blend_read_data = brush_blend_read_data,
+ .blend_read_lib = brush_blend_read_lib,
+ .blend_read_expand = brush_blend_read_expand,
};
static RNG *brush_rng;
@@ -1548,10 +1707,12 @@ void BKE_brush_sculpt_reset(Brush *br)
break;
case SCULPT_TOOL_SCRAPE:
case SCULPT_TOOL_FILL:
- br->alpha = 1.0f;
+ br->alpha = 0.7f;
+ br->area_radius_factor = 1.0f;
br->spacing = 7;
br->flag |= BRUSH_ACCUMULATE;
br->flag |= BRUSH_INVERT_TO_SCRAPE_FILL;
+ br->flag2 |= BRUSH_AREA_RADIUS_PRESSURE;
break;
case SCULPT_TOOL_ROTATE:
br->alpha = 1.0;
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index eef2ab94078..4fe3ddc81a1 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -24,6 +24,9 @@
#include <stddef.h>
#include <stdlib.h>
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_ID.h"
#include "DNA_camera_types.h"
#include "DNA_defaults.h"
@@ -38,6 +41,7 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BKE_anim_data.h"
#include "BKE_camera.h"
#include "BKE_idtype.h"
#include "BKE_layer.h"
@@ -54,6 +58,8 @@
#include "MEM_guardedalloc.h"
+#include "BLO_read_write.h"
+
/* -------------------------------------------------------------------- */
/** \name Camera Data-Block
* \{ */
@@ -113,6 +119,67 @@ static void camera_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void camera_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Camera *cam = (Camera *)id;
+ if (cam->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* write LibData */
+ BLO_write_id_struct(writer, Camera, id_address, &cam->id);
+ BKE_id_blend_write(writer, &cam->id);
+
+ if (cam->adt) {
+ BKE_animdata_blend_write(writer, cam->adt);
+ }
+
+ LISTBASE_FOREACH (CameraBGImage *, bgpic, &cam->bg_images) {
+ BLO_write_struct(writer, CameraBGImage, bgpic);
+ }
+ }
+}
+
+static void camera_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Camera *ca = (Camera *)id;
+ BLO_read_data_address(reader, &ca->adt);
+ BKE_animdata_blend_read_data(reader, ca->adt);
+
+ BLO_read_list(reader, &ca->bg_images);
+
+ LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) {
+ bgpic->iuser.ok = 1;
+ bgpic->iuser.scene = NULL;
+ }
+}
+
+static void camera_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Camera *ca = (Camera *)id;
+ BLO_read_id_address(reader, ca->id.lib, &ca->ipo); /* deprecated, for versioning */
+
+ BLO_read_id_address(reader, ca->id.lib, &ca->dof_ob); /* deprecated, for versioning */
+ BLO_read_id_address(reader, ca->id.lib, &ca->dof.focus_object);
+
+ LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) {
+ BLO_read_id_address(reader, ca->id.lib, &bgpic->ima);
+ BLO_read_id_address(reader, ca->id.lib, &bgpic->clip);
+ }
+}
+
+static void camera_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Camera *ca = (Camera *)id;
+ BLO_expand(expander, ca->ipo); // XXX deprecated - old animation system
+
+ LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) {
+ if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) {
+ BLO_expand(expander, bgpic->ima);
+ }
+ else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) {
+ BLO_expand(expander, bgpic->ima);
+ }
+ }
+}
+
IDTypeInfo IDType_ID_CA = {
.id_code = ID_CA,
.id_filter = FILTER_ID_CA,
@@ -130,10 +197,10 @@ IDTypeInfo IDType_ID_CA = {
.foreach_id = camera_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = camera_blend_write,
+ .blend_read_data = camera_blend_read_data,
+ .blend_read_lib = camera_blend_read_lib,
+ .blend_read_expand = camera_blend_read_expand,
};
/** \} */
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 351f73ea76e..dfa8d65d117 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -28,12 +28,16 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_endian_switch.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_anim_types.h"
#include "DNA_curve_types.h"
#include "DNA_defaults.h"
@@ -44,6 +48,7 @@
#include "DNA_object_types.h"
#include "DNA_vfont_types.h"
+#include "BKE_anim_data.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_font.h"
@@ -59,6 +64,8 @@
#include "CLG_log.h"
+#include "BLO_read_write.h"
+
/* globals */
/* local */
@@ -131,6 +138,158 @@ static void curve_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS(data, curve->vfontbi, IDWALK_CB_USER);
}
+static void curve_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Curve *cu = (Curve *)id;
+ if (cu->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed datablocks. */
+ cu->editnurb = NULL;
+ cu->editfont = NULL;
+ cu->batch_cache = NULL;
+
+ /* write LibData */
+ BLO_write_id_struct(writer, Curve, id_address, &cu->id);
+ BKE_id_blend_write(writer, &cu->id);
+
+ /* direct data */
+ BLO_write_pointer_array(writer, cu->totcol, cu->mat);
+ if (cu->adt) {
+ BKE_animdata_blend_write(writer, cu->adt);
+ }
+
+ if (cu->vfont) {
+ BLO_write_raw(writer, cu->len + 1, cu->str);
+ BLO_write_struct_array(writer, CharInfo, cu->len_char32 + 1, cu->strinfo);
+ BLO_write_struct_array(writer, TextBox, cu->totbox, cu->tb);
+ }
+ else {
+ /* is also the order of reading */
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
+ BLO_write_struct(writer, Nurb, nu);
+ }
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
+ if (nu->type == CU_BEZIER) {
+ BLO_write_struct_array(writer, BezTriple, nu->pntsu, nu->bezt);
+ }
+ else {
+ BLO_write_struct_array(writer, BPoint, nu->pntsu * nu->pntsv, nu->bp);
+ if (nu->knotsu) {
+ BLO_write_float_array(writer, KNOTSU(nu), nu->knotsu);
+ }
+ if (nu->knotsv) {
+ BLO_write_float_array(writer, KNOTSV(nu), nu->knotsv);
+ }
+ }
+ }
+ }
+ }
+}
+
+static void switch_endian_knots(Nurb *nu)
+{
+ if (nu->knotsu) {
+ BLI_endian_switch_float_array(nu->knotsu, KNOTSU(nu));
+ }
+ if (nu->knotsv) {
+ BLI_endian_switch_float_array(nu->knotsv, KNOTSV(nu));
+ }
+}
+
+static void curve_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Curve *cu = (Curve *)id;
+ BLO_read_data_address(reader, &cu->adt);
+ BKE_animdata_blend_read_data(reader, cu->adt);
+
+ /* Protect against integer overflow vulnerability. */
+ CLAMP(cu->len_char32, 0, INT_MAX - 4);
+
+ BLO_read_pointer_array(reader, (void **)&cu->mat);
+
+ BLO_read_data_address(reader, &cu->str);
+ BLO_read_data_address(reader, &cu->strinfo);
+ BLO_read_data_address(reader, &cu->tb);
+
+ if (cu->vfont == NULL) {
+ BLO_read_list(reader, &(cu->nurb));
+ }
+ else {
+ cu->nurb.first = cu->nurb.last = NULL;
+
+ TextBox *tb = MEM_calloc_arrayN(MAXTEXTBOX, sizeof(TextBox), "TextBoxread");
+ if (cu->tb) {
+ memcpy(tb, cu->tb, cu->totbox * sizeof(TextBox));
+ MEM_freeN(cu->tb);
+ cu->tb = tb;
+ }
+ else {
+ cu->totbox = 1;
+ cu->actbox = 1;
+ cu->tb = tb;
+ cu->tb[0].w = cu->linewidth;
+ }
+ if (cu->wordspace == 0.0f) {
+ cu->wordspace = 1.0f;
+ }
+ }
+
+ cu->editnurb = NULL;
+ cu->editfont = NULL;
+ cu->batch_cache = NULL;
+
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
+ BLO_read_data_address(reader, &nu->bezt);
+ BLO_read_data_address(reader, &nu->bp);
+ BLO_read_data_address(reader, &nu->knotsu);
+ BLO_read_data_address(reader, &nu->knotsv);
+ if (cu->vfont == NULL) {
+ nu->charidx = 0;
+ }
+
+ if (BLO_read_requires_endian_switch(reader)) {
+ switch_endian_knots(nu);
+ }
+ }
+ cu->texflag &= ~CU_AUTOSPACE_EVALUATED;
+}
+
+static void curve_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Curve *cu = (Curve *)id;
+ for (int a = 0; a < cu->totcol; a++) {
+ BLO_read_id_address(reader, cu->id.lib, &cu->mat[a]);
+ }
+
+ BLO_read_id_address(reader, cu->id.lib, &cu->bevobj);
+ BLO_read_id_address(reader, cu->id.lib, &cu->taperobj);
+ BLO_read_id_address(reader, cu->id.lib, &cu->textoncurve);
+ BLO_read_id_address(reader, cu->id.lib, &cu->vfont);
+ BLO_read_id_address(reader, cu->id.lib, &cu->vfontb);
+ BLO_read_id_address(reader, cu->id.lib, &cu->vfonti);
+ BLO_read_id_address(reader, cu->id.lib, &cu->vfontbi);
+
+ BLO_read_id_address(reader, cu->id.lib, &cu->ipo); // XXX deprecated - old animation system
+ BLO_read_id_address(reader, cu->id.lib, &cu->key);
+}
+
+static void curve_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Curve *cu = (Curve *)id;
+ for (int a = 0; a < cu->totcol; a++) {
+ BLO_expand(expander, cu->mat[a]);
+ }
+
+ BLO_expand(expander, cu->vfont);
+ BLO_expand(expander, cu->vfontb);
+ BLO_expand(expander, cu->vfonti);
+ BLO_expand(expander, cu->vfontbi);
+ BLO_expand(expander, cu->key);
+ BLO_expand(expander, cu->ipo); // XXX deprecated - old animation system
+ BLO_expand(expander, cu->bevobj);
+ BLO_expand(expander, cu->taperobj);
+ BLO_expand(expander, cu->textoncurve);
+}
+
IDTypeInfo IDType_ID_CU = {
.id_code = ID_CU,
.id_filter = FILTER_ID_CU,
@@ -148,10 +307,10 @@ IDTypeInfo IDType_ID_CU = {
.foreach_id = curve_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = curve_blend_write,
+ .blend_read_data = curve_blend_read_data,
+ .blend_read_lib = curve_blend_read_lib,
+ .blend_read_expand = curve_blend_read_expand,
};
static int cu_isectLL(const float v1[3],
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index 937741c2ac0..83e3a3098e9 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -2252,19 +2252,33 @@ static Material *gpencil_add_material(Main *bmain,
return mat_gp;
}
-static int gpencil_material_find_index_by_name_prefix(Object *ob, const char *name_prefix)
+static int gpencil_material_find_index_by_name(Object *ob, const char *name)
{
- const int name_prefix_len = strlen(name_prefix);
for (int i = 0; i < ob->totcol; i++) {
Material *ma = BKE_object_material_get(ob, i + 1);
- if ((ma != NULL) && (ma->gp_style != NULL) &&
- (STREQLEN(ma->id.name + 2, name_prefix, name_prefix_len))) {
+ if ((ma != NULL) && (ma->gp_style != NULL) && (STREQ(ma->id.name + 2, name))) {
return i;
}
}
return -1;
}
+
+/* Create the name with the object name and a subfix. */
+static void make_element_name(char *obname, char *name, const int maxlen, char *r_name)
+{
+ char str[256];
+ sprintf(str, "%s_%s", obname, name);
+ /* Replace any point by underscore. */
+ char *current_pos = strchr(str, '.');
+ while (current_pos) {
+ *current_pos = '_';
+ current_pos = strchr(current_pos, '.');
+ }
+
+ BLI_strncpy_utf8(r_name, str, maxlen);
+}
+
/**
* Convert a mesh object to grease pencil stroke.
*
@@ -2280,9 +2294,8 @@ static int gpencil_material_find_index_by_name_prefix(Object *ob, const char *na
* \param frame_offset: Destination frame number offset.
* \param use_seams: Only export seam edges.
* \param use_faces: Export faces as filled strokes.
- * \simple_material: Create only 2 materials (stroke and fill)
*/
-void BKE_gpencil_convert_mesh(Main *bmain,
+bool BKE_gpencil_convert_mesh(Main *bmain,
Depsgraph *depsgraph,
Scene *scene,
Object *ob_gp,
@@ -2293,11 +2306,10 @@ void BKE_gpencil_convert_mesh(Main *bmain,
const float matrix[4][4],
const int frame_offset,
const bool use_seams,
- const bool use_faces,
- const bool simple_material)
+ const bool use_faces)
{
if (ELEM(NULL, ob_gp, ob_mesh) || (ob_gp->type != OB_GPENCIL) || (ob_gp->data == NULL)) {
- return;
+ return false;
}
bGPdata *gpd = (bGPdata *)ob_gp->data;
@@ -2308,77 +2320,56 @@ void BKE_gpencil_convert_mesh(Main *bmain,
MPoly *mp, *mpoly = me_eval->mpoly;
MLoop *mloop = me_eval->mloop;
int mpoly_len = me_eval->totpoly;
- int stroke_mat_index = gpencil_material_find_index_by_name_prefix(ob_gp, "Stroke");
- int fill_mat_index = gpencil_material_find_index_by_name_prefix(ob_gp, "Fill");
-
- /* If the object has enough materials means it was created in a previous step. */
- const bool create_mat = ((ob_gp->totcol > 0) && (ob_gp->totcol >= ob_mesh->totcol)) ? false :
- true;
+ char element_name[200];
/* Need at least an edge. */
if (me_eval->totvert < 2) {
- return;
+ return false;
}
- int r_idx;
const float default_colors[2][4] = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.7f, 0.7f, 0.7f, 1.0f}};
/* Create stroke material. */
- if (create_mat) {
- if (stroke_mat_index == -1) {
- gpencil_add_material(bmain, ob_gp, "Stroke", default_colors[0], true, false, &r_idx);
- stroke_mat_index = ob_gp->totcol - 1;
- }
+ make_element_name(ob_mesh->id.name + 2, "Stroke", 64, element_name);
+ int stroke_mat_index = gpencil_material_find_index_by_name(ob_gp, element_name);
+
+ if (stroke_mat_index == -1) {
+ gpencil_add_material(
+ bmain, ob_gp, element_name, default_colors[0], true, false, &stroke_mat_index);
}
+
/* Export faces as filled strokes. */
if (use_faces) {
- if (create_mat) {
- /* Find a material slot with material assigned. */
- bool material_found = false;
- for (int i = 0; i < ob_mesh->totcol; i++) {
- Material *ma = BKE_object_material_get(ob_mesh, i + 1);
- if (ma != NULL) {
- material_found = true;
- break;
- }
- }
-
- /* If no materials or use simple materials, create a simple fill. */
- if ((!material_found) || (simple_material)) {
- if (fill_mat_index == -1) {
- gpencil_add_material(bmain, ob_gp, "Fill", default_colors[1], false, true, &r_idx);
- fill_mat_index = ob_gp->totcol - 1;
- }
- }
- else {
- /* Create all materials for fill. */
- for (int i = 0; i < ob_mesh->totcol; i++) {
- Material *ma = BKE_object_material_get(ob_mesh, i + 1);
- if (ma == NULL) {
- continue;
- }
- float color[4];
- copy_v3_v3(color, &ma->r);
- color[3] = 1.0f;
- gpencil_add_material(bmain, ob_gp, ma->id.name + 2, color, false, true, &r_idx);
- }
- }
- }
/* Read all polygons and create fill for each. */
if (mpoly_len > 0) {
- bGPDlayer *gpl_fill = BKE_gpencil_layer_named_get(gpd, DATA_("Fills"));
+ make_element_name(ob_mesh->id.name + 2, "Fills", 128, element_name);
+ /* Create Layer and Frame. */
+ bGPDlayer *gpl_fill = BKE_gpencil_layer_named_get(gpd, element_name);
if (gpl_fill == NULL) {
- gpl_fill = BKE_gpencil_layer_addnew(gpd, DATA_("Fills"), true);
+ gpl_fill = BKE_gpencil_layer_addnew(gpd, element_name, true);
}
bGPDframe *gpf_fill = BKE_gpencil_layer_frame_get(
gpl_fill, CFRA + frame_offset, GP_GETFRAME_ADD_NEW);
int i;
for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
MLoop *ml = &mloop[mp->loopstart];
- /* Create fill stroke. */
- int mat_idx = (simple_material) || (mp->mat_nr + 1 > ob_gp->totcol - 1) ?
- MAX2(fill_mat_index, 0) :
- mp->mat_nr + 1;
+ /* Find material. */
+ int mat_idx = 0;
+ Material *ma = BKE_object_material_get(ob_mesh, mp->mat_nr + 1);
+ make_element_name(
+ ob_mesh->id.name + 2, (ma != NULL) ? ma->id.name + 2 : "Fill", 64, element_name);
+ mat_idx = gpencil_material_find_index_by_name(ob_gp, element_name);
+ if (mat_idx == -1) {
+ float color[4];
+ if (ma != NULL) {
+ copy_v3_v3(color, &ma->r);
+ color[3] = 1.0f;
+ }
+ else {
+ copy_v4_v4(color, default_colors[1]);
+ }
+ gpencil_add_material(bmain, ob_gp, element_name, color, false, true, &mat_idx);
+ }
bGPDstroke *gps_fill = BKE_gpencil_stroke_add(gpf_fill, mat_idx, mp->totloop, 10, false);
gps_fill->flag |= GP_STROKE_CYCLIC;
@@ -2386,13 +2377,16 @@ void BKE_gpencil_convert_mesh(Main *bmain,
/* Add points to strokes. */
for (int j = 0; j < mp->totloop; j++, ml++) {
MVert *mv = &me_eval->mvert[ml->v];
-
bGPDspoint *pt = &gps_fill->points[j];
copy_v3_v3(&pt->x, mv->co);
mul_m4_v3(matrix, &pt->x);
pt->pressure = 1.0f;
pt->strength = 1.0f;
}
+ /* If has only 3 points subdivide. */
+ if (mp->totloop == 3) {
+ BKE_gpencil_stroke_subdivide(gps_fill, 1, GP_SUBDIV_SIMPLE);
+ }
BKE_gpencil_stroke_geometry_update(gps_fill);
}
@@ -2400,17 +2394,23 @@ void BKE_gpencil_convert_mesh(Main *bmain,
}
/* Create stroke from edges. */
- bGPDlayer *gpl_stroke = BKE_gpencil_layer_named_get(gpd, DATA_("Lines"));
+ make_element_name(ob_mesh->id.name + 2, "Lines", 128, element_name);
+
+ /* Create Layer and Frame. */
+ bGPDlayer *gpl_stroke = BKE_gpencil_layer_named_get(gpd, element_name);
if (gpl_stroke == NULL) {
- gpl_stroke = BKE_gpencil_layer_addnew(gpd, DATA_("Lines"), true);
+ gpl_stroke = BKE_gpencil_layer_addnew(gpd, element_name, true);
}
bGPDframe *gpf_stroke = BKE_gpencil_layer_frame_get(
gpl_stroke, CFRA + frame_offset, GP_GETFRAME_ADD_NEW);
+
gpencil_generate_edgeloops(
ob_eval, gpf_stroke, stroke_mat_index, angle, thickness, offset, matrix, use_seams);
/* Tag for recalculation */
DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+
+ return true;
}
/**
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 88dc29305ea..0ddac216931 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -47,6 +47,9 @@
# include "intern/openexr/openexr_multi.h"
#endif
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_brush_types.h"
#include "DNA_camera_types.h"
#include "DNA_defaults.h"
@@ -97,6 +100,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "BLO_read_write.h"
+
/* for image user iteration */
#include "DNA_node_types.h"
#include "DNA_screen_types.h"
@@ -216,6 +221,88 @@ static void image_foreach_cache(ID *id,
}
}
+static void image_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Image *ima = (Image *)id;
+ if (ima->id.us > 0 || BLO_write_is_undo(writer)) {
+ ImagePackedFile *imapf;
+
+ /* Some trickery to keep forward compatibility of packed images. */
+ BLI_assert(ima->packedfile == NULL);
+ if (ima->packedfiles.first != NULL) {
+ imapf = ima->packedfiles.first;
+ ima->packedfile = imapf->packedfile;
+ }
+
+ /* write LibData */
+ BLO_write_id_struct(writer, Image, id_address, &ima->id);
+ BKE_id_blend_write(writer, &ima->id);
+
+ for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
+ BLO_write_struct(writer, ImagePackedFile, imapf);
+ BKE_packedfile_blend_write(writer, imapf->packedfile);
+ }
+
+ BKE_previewimg_blend_write(writer, ima->preview);
+
+ LISTBASE_FOREACH (ImageView *, iv, &ima->views) {
+ BLO_write_struct(writer, ImageView, iv);
+ }
+ BLO_write_struct(writer, Stereo3dFormat, ima->stereo3d_format);
+
+ BLO_write_struct_list(writer, ImageTile, &ima->tiles);
+
+ ima->packedfile = NULL;
+
+ BLO_write_struct_list(writer, RenderSlot, &ima->renderslots);
+ }
+}
+
+static void image_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Image *ima = (Image *)id;
+ BLO_read_list(reader, &ima->tiles);
+
+ BLO_read_list(reader, &(ima->renderslots));
+ if (!BLO_read_data_is_undo(reader)) {
+ /* We reset this last render slot index only when actually reading a file, not for undo. */
+ ima->last_render_slot = ima->render_slot;
+ }
+
+ BLO_read_list(reader, &(ima->views));
+ BLO_read_list(reader, &(ima->packedfiles));
+
+ if (ima->packedfiles.first) {
+ LISTBASE_FOREACH (ImagePackedFile *, imapf, &ima->packedfiles) {
+ BKE_packedfile_blend_read(reader, &imapf->packedfile);
+ }
+ ima->packedfile = NULL;
+ }
+ else {
+ BKE_packedfile_blend_read(reader, &ima->packedfile);
+ }
+
+ BLI_listbase_clear(&ima->anims);
+ BLO_read_data_address(reader, &ima->preview);
+ BKE_previewimg_blend_read(reader, ima->preview);
+ BLO_read_data_address(reader, &ima->stereo3d_format);
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ tile->ok = IMA_OK;
+ }
+}
+
+static void image_blend_read_lib(BlendLibReader *UNUSED(reader), ID *id)
+{
+ Image *ima = (Image *)id;
+ /* Images have some kind of 'main' cache, when NULL we should also clear all others. */
+ /* Needs to be done *after* cache pointers are restored (call to
+ * `foreach_cache`/`blo_cache_storage_entry_restore_in_new`), easier for now to do it in
+ * lib_link... */
+ if (ima->cache == NULL) {
+ BKE_image_free_buffers(ima);
+ }
+}
+
IDTypeInfo IDType_ID_IM = {
.id_code = ID_IM,
.id_filter = FILTER_ID_IM,
@@ -233,9 +320,9 @@ IDTypeInfo IDType_ID_IM = {
.foreach_id = NULL,
.foreach_cache = image_foreach_cache,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
+ .blend_write = image_blend_write,
+ .blend_read_data = image_blend_read_data,
+ .blend_read_lib = image_blend_read_lib,
.blend_read_expand = NULL,
};
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 9cdbb30b90a..1b63aa1a8af 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -28,12 +28,16 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_endian_switch.h"
#include "BLI_math_vector.h"
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_ID.h"
#include "DNA_anim_types.h"
#include "DNA_key_types.h"
@@ -43,6 +47,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BKE_anim_data.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_deform.h"
@@ -58,6 +63,8 @@
#include "RNA_access.h"
+#include "BLO_read_write.h"
+
static void shapekey_copy_data(Main *UNUSED(bmain),
ID *id_dst,
const ID *id_src,
@@ -98,6 +105,94 @@ static void shapekey_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS_ID(data, key->from, IDWALK_CB_LOOPBACK);
}
+static void shapekey_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Key *key = (Key *)id;
+ if (key->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* write LibData */
+ BLO_write_id_struct(writer, Key, id_address, &key->id);
+ BKE_id_blend_write(writer, &key->id);
+
+ if (key->adt) {
+ BKE_animdata_blend_write(writer, key->adt);
+ }
+
+ /* direct data */
+ LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
+ BLO_write_struct(writer, KeyBlock, kb);
+ if (kb->data) {
+ BLO_write_raw(writer, kb->totelem * key->elemsize, kb->data);
+ }
+ }
+ }
+}
+
+/* old defines from DNA_ipo_types.h for data-type, stored in DNA - don't modify! */
+#define IPO_FLOAT 4
+#define IPO_BEZTRIPLE 100
+#define IPO_BPOINT 101
+
+static void switch_endian_keyblock(Key *key, KeyBlock *kb)
+{
+ int elemsize = key->elemsize;
+ char *data = kb->data;
+
+ for (int a = 0; a < kb->totelem; a++) {
+ const char *cp = key->elemstr;
+ char *poin = data;
+
+ while (cp[0]) { /* cp[0] == amount */
+ switch (cp[1]) { /* cp[1] = type */
+ case IPO_FLOAT:
+ case IPO_BPOINT:
+ case IPO_BEZTRIPLE: {
+ int b = cp[0];
+ BLI_endian_switch_float_array((float *)poin, b);
+ poin += sizeof(float) * b;
+ break;
+ }
+ }
+
+ cp += 2;
+ }
+ data += elemsize;
+ }
+}
+
+static void shapekey_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Key *key = (Key *)id;
+ BLO_read_list(reader, &(key->block));
+
+ BLO_read_data_address(reader, &key->adt);
+ BKE_animdata_blend_read_data(reader, key->adt);
+
+ BLO_read_data_address(reader, &key->refkey);
+
+ LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
+ BLO_read_data_address(reader, &kb->data);
+
+ if (BLO_read_requires_endian_switch(reader)) {
+ switch_endian_keyblock(key, kb);
+ }
+ }
+}
+
+static void shapekey_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Key *key = (Key *)id;
+ BLI_assert((key->id.tag & LIB_TAG_EXTERN) == 0);
+
+ BLO_read_id_address(reader, key->id.lib, &key->ipo); // XXX deprecated - old animation system
+ BLO_read_id_address(reader, key->id.lib, &key->from);
+}
+
+static void shapekey_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Key *key = (Key *)id;
+ BLO_expand(expander, key->ipo); // XXX deprecated - old animation system
+}
+
IDTypeInfo IDType_ID_KE = {
.id_code = ID_KE,
.id_filter = 0,
@@ -115,21 +210,16 @@ IDTypeInfo IDType_ID_KE = {
.foreach_id = shapekey_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = shapekey_blend_write,
+ .blend_read_data = shapekey_blend_read_data,
+ .blend_read_lib = shapekey_blend_read_lib,
+ .blend_read_expand = shapekey_blend_read_expand,
};
#define KEY_MODE_DUMMY 0 /* use where mode isn't checked for */
#define KEY_MODE_BPOINT 1
#define KEY_MODE_BEZTRIPLE 2
-/* old defines from DNA_ipo_types.h for data-type, stored in DNA - don't modify! */
-#define IPO_FLOAT 4
-#define IPO_BEZTRIPLE 100
-#define IPO_BPOINT 101
-
/* Internal use only. */
typedef struct WeightsArrayCache {
int num_defgroup_weights;
diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c
index 976fa010057..1ce079b006e 100644
--- a/source/blender/blenkernel/intern/light.c
+++ b/source/blender/blenkernel/intern/light.c
@@ -25,6 +25,9 @@
#include "MEM_guardedalloc.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_anim_types.h"
#include "DNA_defaults.h"
#include "DNA_light_types.h"
@@ -37,6 +40,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BKE_anim_data.h"
#include "BKE_colortools.h"
#include "BKE_icons.h"
#include "BKE_idtype.h"
@@ -50,6 +54,8 @@
#include "DEG_depsgraph.h"
+#include "BLO_read_write.h"
+
static void light_init_data(ID *id)
{
Light *la = (Light *)id;
@@ -119,6 +125,59 @@ static void light_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void light_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Light *la = (Light *)id;
+ if (la->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* write LibData */
+ BLO_write_id_struct(writer, Light, id_address, &la->id);
+ BKE_id_blend_write(writer, &la->id);
+
+ if (la->adt) {
+ BKE_animdata_blend_write(writer, la->adt);
+ }
+
+ if (la->curfalloff) {
+ BKE_curvemapping_blend_write(writer, la->curfalloff);
+ }
+
+ /* Node-tree is integral part of lights, no libdata. */
+ if (la->nodetree) {
+ BLO_write_struct(writer, bNodeTree, la->nodetree);
+ ntreeBlendWrite(writer, la->nodetree);
+ }
+
+ BKE_previewimg_blend_write(writer, la->preview);
+ }
+}
+
+static void light_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Light *la = (Light *)id;
+ BLO_read_data_address(reader, &la->adt);
+ BKE_animdata_blend_read_data(reader, la->adt);
+
+ BLO_read_data_address(reader, &la->curfalloff);
+ if (la->curfalloff) {
+ BKE_curvemapping_blend_read(reader, la->curfalloff);
+ }
+
+ BLO_read_data_address(reader, &la->preview);
+ BKE_previewimg_blend_read(reader, la->preview);
+}
+
+static void light_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Light *la = (Light *)id;
+ BLO_read_id_address(reader, la->id.lib, &la->ipo); // XXX deprecated - old animation system
+}
+
+static void light_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Light *la = (Light *)id;
+ BLO_expand(expander, la->ipo); // XXX deprecated - old animation system
+}
+
IDTypeInfo IDType_ID_LA = {
.id_code = ID_LA,
.id_filter = FILTER_ID_LA,
@@ -136,10 +195,10 @@ IDTypeInfo IDType_ID_LA = {
.foreach_id = light_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = light_blend_write,
+ .blend_read_data = light_blend_read_data,
+ .blend_read_lib = light_blend_read_lib,
+ .blend_read_expand = light_blend_read_expand,
};
Light *BKE_light_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/lightprobe.c b/source/blender/blenkernel/intern/lightprobe.c
index b4b13306112..cf680641a7b 100644
--- a/source/blender/blenkernel/intern/lightprobe.c
+++ b/source/blender/blenkernel/intern/lightprobe.c
@@ -30,6 +30,7 @@
#include "BLI_utildefines.h"
+#include "BKE_anim_data.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
@@ -38,6 +39,8 @@
#include "BLT_translation.h"
+#include "BLO_read_write.h"
+
static void lightprobe_init_data(ID *id)
{
LightProbe *probe = (LightProbe *)id;
@@ -54,6 +57,33 @@ static void lightprobe_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS(data, probe->visibility_grp, IDWALK_CB_NOP);
}
+static void lightprobe_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ LightProbe *prb = (LightProbe *)id;
+ if (prb->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* write LibData */
+ BLO_write_id_struct(writer, LightProbe, id_address, &prb->id);
+ BKE_id_blend_write(writer, &prb->id);
+
+ if (prb->adt) {
+ BKE_animdata_blend_write(writer, prb->adt);
+ }
+ }
+}
+
+static void lightprobe_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ LightProbe *prb = (LightProbe *)id;
+ BLO_read_data_address(reader, &prb->adt);
+ BKE_animdata_blend_read_data(reader, prb->adt);
+}
+
+static void lightprobe_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ LightProbe *prb = (LightProbe *)id;
+ BLO_read_id_address(reader, prb->id.lib, &prb->visibility_grp);
+}
+
IDTypeInfo IDType_ID_LP = {
.id_code = ID_LP,
.id_filter = FILTER_ID_LP,
@@ -71,9 +101,9 @@ IDTypeInfo IDType_ID_LP = {
.foreach_id = lightprobe_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
+ .blend_write = lightprobe_blend_write,
+ .blend_read_data = lightprobe_blend_read_data,
+ .blend_read_lib = lightprobe_blend_read_lib,
.blend_read_expand = NULL,
};
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 272c9fda9ae..c8c4fea7ab1 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -28,6 +28,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_endian_switch.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
@@ -43,6 +44,7 @@
#include "BKE_curve.h"
#include "BKE_idtype.h"
+#include "BKE_anim_data.h"
#include "BKE_image.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
@@ -53,6 +55,8 @@
#include "DEG_depsgraph_build.h"
+#include "BLO_read_write.h"
+
static CLG_LogRef LOG = {"bke.mask"};
static void mask_copy_data(Main *UNUSED(bmain),
@@ -94,6 +98,155 @@ static void mask_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void mask_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Mask *mask = (Mask *)id;
+ if (mask->id.us > 0 || BLO_write_is_undo(writer)) {
+ MaskLayer *masklay;
+
+ BLO_write_id_struct(writer, Mask, id_address, &mask->id);
+ BKE_id_blend_write(writer, &mask->id);
+
+ if (mask->adt) {
+ BKE_animdata_blend_write(writer, mask->adt);
+ }
+
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ MaskSpline *spline;
+ MaskLayerShape *masklay_shape;
+
+ BLO_write_struct(writer, MaskLayer, masklay);
+
+ for (spline = masklay->splines.first; spline; spline = spline->next) {
+ int i;
+
+ void *points_deform = spline->points_deform;
+ spline->points_deform = NULL;
+
+ BLO_write_struct(writer, MaskSpline, spline);
+ BLO_write_struct_array(writer, MaskSplinePoint, spline->tot_point, spline->points);
+
+ spline->points_deform = points_deform;
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+
+ if (point->tot_uw) {
+ BLO_write_struct_array(writer, MaskSplinePointUW, point->tot_uw, point->uw);
+ }
+ }
+ }
+
+ for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
+ masklay_shape = masklay_shape->next) {
+ BLO_write_struct(writer, MaskLayerShape, masklay_shape);
+ BLO_write_float_array(
+ writer, masklay_shape->tot_vert * MASK_OBJECT_SHAPE_ELEM_SIZE, masklay_shape->data);
+ }
+ }
+ }
+}
+
+static void mask_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Mask *mask = (Mask *)id;
+ BLO_read_data_address(reader, &mask->adt);
+
+ BLO_read_list(reader, &mask->masklayers);
+
+ LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
+ /* can't use newdataadr since it's a pointer within an array */
+ MaskSplinePoint *act_point_search = NULL;
+
+ BLO_read_list(reader, &masklay->splines);
+
+ LISTBASE_FOREACH (MaskSpline *, spline, &masklay->splines) {
+ MaskSplinePoint *points_old = spline->points;
+
+ BLO_read_data_address(reader, &spline->points);
+
+ for (int i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+
+ if (point->tot_uw) {
+ BLO_read_data_address(reader, &point->uw);
+ }
+ }
+
+ /* detect active point */
+ if ((act_point_search == NULL) && (masklay->act_point >= points_old) &&
+ (masklay->act_point < points_old + spline->tot_point)) {
+ act_point_search = &spline->points[masklay->act_point - points_old];
+ }
+ }
+
+ BLO_read_list(reader, &masklay->splines_shapes);
+
+ LISTBASE_FOREACH (MaskLayerShape *, masklay_shape, &masklay->splines_shapes) {
+ BLO_read_data_address(reader, &masklay_shape->data);
+
+ if (masklay_shape->tot_vert) {
+ if (BLO_read_requires_endian_switch(reader)) {
+ BLI_endian_switch_float_array(masklay_shape->data,
+ masklay_shape->tot_vert * sizeof(float) *
+ MASK_OBJECT_SHAPE_ELEM_SIZE);
+ }
+ }
+ }
+
+ BLO_read_data_address(reader, &masklay->act_spline);
+ masklay->act_point = act_point_search;
+ }
+}
+
+static void lib_link_mask_parent(BlendLibReader *reader, Mask *mask, MaskParent *parent)
+{
+ BLO_read_id_address(reader, mask->id.lib, &parent->id);
+}
+
+static void mask_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Mask *mask = (Mask *)id;
+ LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
+ MaskSpline *spline;
+
+ spline = masklay->splines.first;
+ while (spline) {
+ for (int i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+
+ lib_link_mask_parent(reader, mask, &point->parent);
+ }
+
+ lib_link_mask_parent(reader, mask, &spline->parent);
+
+ spline = spline->next;
+ }
+ }
+}
+
+static void expand_mask_parent(BlendExpander *expander, MaskParent *parent)
+{
+ if (parent->id) {
+ BLO_expand(expander, parent->id);
+ }
+}
+
+static void mask_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Mask *mask = (Mask *)id;
+ LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
+ LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
+ for (int i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+ expand_mask_parent(expander, &point->parent);
+ }
+
+ expand_mask_parent(expander, &spline->parent);
+ }
+ }
+}
+
IDTypeInfo IDType_ID_MSK = {
.id_code = ID_MSK,
.id_filter = FILTER_ID_MSK,
@@ -111,10 +264,10 @@ IDTypeInfo IDType_ID_MSK = {
.foreach_id = mask_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = mask_blend_write,
+ .blend_read_data = mask_blend_read_data,
+ .blend_read_lib = mask_blend_read_lib,
+ .blend_read_expand = mask_blend_read_expand,
};
static struct {
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 245cf19846e..885cc1baefc 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -29,6 +29,9 @@
#include "MEM_guardedalloc.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_ID.h"
#include "DNA_anim_types.h"
#include "DNA_collection_types.h"
@@ -54,6 +57,7 @@
#include "BLT_translation.h"
+#include "BKE_anim_data.h"
#include "BKE_brush.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
@@ -78,6 +82,8 @@
#include "NOD_shader.h"
+#include "BLO_read_write.h"
+
static CLG_LogRef LOG = {"bke.material"};
static void material_init_data(ID *id)
@@ -160,6 +166,82 @@ static void material_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void material_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Material *ma = (Material *)id;
+ if (ma->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed datablocks. */
+ ma->texpaintslot = NULL;
+ BLI_listbase_clear(&ma->gpumaterial);
+
+ /* write LibData */
+ BLO_write_id_struct(writer, Material, id_address, &ma->id);
+ BKE_id_blend_write(writer, &ma->id);
+
+ if (ma->adt) {
+ BKE_animdata_blend_write(writer, ma->adt);
+ }
+
+ /* nodetree is integral part of material, no libdata */
+ if (ma->nodetree) {
+ BLO_write_struct(writer, bNodeTree, ma->nodetree);
+ ntreeBlendWrite(writer, ma->nodetree);
+ }
+
+ BKE_previewimg_blend_write(writer, ma->preview);
+
+ /* grease pencil settings */
+ if (ma->gp_style) {
+ BLO_write_struct(writer, MaterialGPencilStyle, ma->gp_style);
+ }
+ }
+}
+
+static void material_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Material *ma = (Material *)id;
+ BLO_read_data_address(reader, &ma->adt);
+ BKE_animdata_blend_read_data(reader, ma->adt);
+
+ ma->texpaintslot = NULL;
+
+ BLO_read_data_address(reader, &ma->preview);
+ BKE_previewimg_blend_read(reader, ma->preview);
+
+ BLI_listbase_clear(&ma->gpumaterial);
+
+ BLO_read_data_address(reader, &ma->gp_style);
+}
+
+static void material_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Material *ma = (Material *)id;
+ BLO_read_id_address(reader, ma->id.lib, &ma->ipo); // XXX deprecated - old animation system
+
+ /* relink grease pencil settings */
+ if (ma->gp_style != NULL) {
+ MaterialGPencilStyle *gp_style = ma->gp_style;
+ if (gp_style->sima != NULL) {
+ BLO_read_id_address(reader, ma->id.lib, &gp_style->sima);
+ }
+ if (gp_style->ima != NULL) {
+ BLO_read_id_address(reader, ma->id.lib, &gp_style->ima);
+ }
+ }
+}
+
+static void material_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Material *ma = (Material *)id;
+ BLO_expand(expander, ma->ipo); // XXX deprecated - old animation system
+
+ if (ma->gp_style) {
+ MaterialGPencilStyle *gp_style = ma->gp_style;
+ BLO_expand(expander, gp_style->sima);
+ BLO_expand(expander, gp_style->ima);
+ }
+}
+
IDTypeInfo IDType_ID_MA = {
.id_code = ID_MA,
.id_filter = FILTER_ID_MA,
@@ -177,10 +259,10 @@ IDTypeInfo IDType_ID_MA = {
.foreach_id = material_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = material_blend_write,
+ .blend_read_data = material_blend_read_data,
+ .blend_read_lib = material_blend_read_lib,
+ .blend_read_expand = material_blend_read_expand,
};
void BKE_gpencil_material_attr_init(Material *ma)
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 2a1ac12baaa..d71c100ed87 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -35,6 +35,9 @@
#include "MEM_guardedalloc.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_defaults.h"
#include "DNA_material_types.h"
#include "DNA_meta_types.h"
@@ -50,6 +53,7 @@
#include "BKE_main.h"
+#include "BKE_anim_data.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_idtype.h"
@@ -62,6 +66,8 @@
#include "DEG_depsgraph.h"
+#include "BLO_read_write.h"
+
static void metaball_init_data(ID *id)
{
MetaBall *metaball = (MetaBall *)id;
@@ -110,6 +116,71 @@ static void metaball_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void metaball_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ MetaBall *mb = (MetaBall *)id;
+ if (mb->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed datablocks. */
+ BLI_listbase_clear(&mb->disp);
+ mb->editelems = NULL;
+ /* Must always be cleared (meta's don't have their own edit-data). */
+ mb->needs_flush_to_id = 0;
+ mb->lastelem = NULL;
+ mb->batch_cache = NULL;
+
+ /* write LibData */
+ BLO_write_id_struct(writer, MetaBall, id_address, &mb->id);
+ BKE_id_blend_write(writer, &mb->id);
+
+ /* direct data */
+ BLO_write_pointer_array(writer, mb->totcol, mb->mat);
+ if (mb->adt) {
+ BKE_animdata_blend_write(writer, mb->adt);
+ }
+
+ LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
+ BLO_write_struct(writer, MetaElem, ml);
+ }
+ }
+}
+
+static void metaball_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ MetaBall *mb = (MetaBall *)id;
+ BLO_read_data_address(reader, &mb->adt);
+ BKE_animdata_blend_read_data(reader, mb->adt);
+
+ BLO_read_pointer_array(reader, (void **)&mb->mat);
+
+ BLO_read_list(reader, &(mb->elems));
+
+ BLI_listbase_clear(&mb->disp);
+ mb->editelems = NULL;
+ /* Must always be cleared (meta's don't have their own edit-data). */
+ mb->needs_flush_to_id = 0;
+ /* mb->edit_elems.first= mb->edit_elems.last= NULL;*/
+ mb->lastelem = NULL;
+ mb->batch_cache = NULL;
+}
+
+static void metaball_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ MetaBall *mb = (MetaBall *)id;
+ for (int a = 0; a < mb->totcol; a++) {
+ BLO_read_id_address(reader, mb->id.lib, &mb->mat[a]);
+ }
+
+ BLO_read_id_address(reader, mb->id.lib, &mb->ipo); // XXX deprecated - old animation system
+}
+
+static void metaball_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ MetaBall *mb = (MetaBall *)id;
+ for (int a = 0; a < mb->totcol; a++) {
+ BLO_expand(expander, mb->mat[a]);
+ }
+}
+
IDTypeInfo IDType_ID_MB = {
.id_code = ID_MB,
.id_filter = FILTER_ID_MB,
@@ -127,10 +198,10 @@ IDTypeInfo IDType_ID_MB = {
.foreach_id = metaball_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = metaball_blend_write,
+ .blend_read_data = metaball_blend_read_data,
+ .blend_read_lib = metaball_blend_read_lib,
+ .blend_read_expand = metaball_blend_read_expand,
};
/* Functions */
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 278c6c0ee53..545d1bdee13 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -72,6 +72,8 @@
#include "RNA_enum_types.h"
+#include "BLO_read_write.h"
+
#include "bmesh.h"
static void palette_init_data(ID *id)
@@ -102,6 +104,26 @@ static void palette_free_data(ID *id)
BLI_freelistN(&palette->colors);
}
+static void palette_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Palette *palette = (Palette *)id;
+ if (palette->id.us > 0 || BLO_write_is_undo(writer)) {
+ PaletteColor *color;
+ BLO_write_id_struct(writer, Palette, id_address, &palette->id);
+ BKE_id_blend_write(writer, &palette->id);
+
+ for (color = palette->colors.first; color; color = color->next) {
+ BLO_write_struct(writer, PaletteColor, color);
+ }
+ }
+}
+
+static void palette_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Palette *palette = (Palette *)id;
+ BLO_read_list(reader, &palette->colors);
+}
+
IDTypeInfo IDType_ID_PAL = {
.id_code = ID_PAL,
.id_filter = FILTER_ID_PAL,
@@ -119,8 +141,8 @@ IDTypeInfo IDType_ID_PAL = {
.foreach_id = NULL,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
+ .blend_write = palette_blend_write,
+ .blend_read_data = palette_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
};
@@ -146,6 +168,23 @@ static void paint_curve_free_data(ID *id)
paint_curve->tot_points = 0;
}
+static void paint_curve_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ PaintCurve *pc = (PaintCurve *)id;
+ if (pc->id.us > 0 || BLO_write_is_undo(writer)) {
+ BLO_write_id_struct(writer, PaintCurve, id_address, &pc->id);
+ BKE_id_blend_write(writer, &pc->id);
+
+ BLO_write_struct_array(writer, PaintCurvePoint, pc->tot_points, pc->points);
+ }
+}
+
+static void paint_curve_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ PaintCurve *pc = (PaintCurve *)id;
+ BLO_read_data_address(reader, &pc->points);
+}
+
IDTypeInfo IDType_ID_PC = {
.id_code = ID_PC,
.id_filter = FILTER_ID_PC,
@@ -163,8 +202,8 @@ IDTypeInfo IDType_ID_PC = {
.foreach_id = NULL,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
+ .blend_write = paint_curve_blend_write,
+ .blend_read_data = paint_curve_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
};
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index 8f403792c46..0a8b4baf826 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -28,12 +28,15 @@
#include "BLT_translation.h"
+#include "BKE_anim_data.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_speaker.h"
+#include "BLO_read_write.h"
+
static void speaker_init_data(ID *id)
{
Speaker *speaker = (Speaker *)id;
@@ -50,6 +53,44 @@ static void speaker_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS(data, speaker->sound, IDWALK_CB_USER);
}
+static void speaker_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Speaker *spk = (Speaker *)id;
+ if (spk->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* write LibData */
+ BLO_write_id_struct(writer, Speaker, id_address, &spk->id);
+ BKE_id_blend_write(writer, &spk->id);
+
+ if (spk->adt) {
+ BKE_animdata_blend_write(writer, spk->adt);
+ }
+ }
+}
+
+static void speaker_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Speaker *spk = (Speaker *)id;
+ BLO_read_data_address(reader, &spk->adt);
+ BKE_animdata_blend_read_data(reader, spk->adt);
+
+#if 0
+ spk->sound = newdataadr(fd, spk->sound);
+ direct_link_sound(fd, spk->sound);
+#endif
+}
+
+static void speaker_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Speaker *spk = (Speaker *)id;
+ BLO_read_id_address(reader, spk->id.lib, &spk->sound);
+}
+
+static void speaker_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Speaker *spk = (Speaker *)id;
+ BLO_expand(expander, spk->sound);
+}
+
IDTypeInfo IDType_ID_SPK = {
.id_code = ID_SPK,
.id_filter = FILTER_ID_SPK,
@@ -67,10 +108,10 @@ IDTypeInfo IDType_ID_SPK = {
.foreach_id = speaker_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = speaker_blend_write,
+ .blend_read_data = speaker_blend_read_data,
+ .blend_read_lib = speaker_blend_read_lib,
+ .blend_read_expand = speaker_blend_read_expand,
};
void *BKE_speaker_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 25c62f139ed..99f35d06c1d 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -27,6 +27,9 @@
#include "MEM_guardedalloc.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_defaults.h"
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
@@ -35,6 +38,7 @@
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
+#include "BKE_anim_data.h"
#include "BKE_icons.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
@@ -51,6 +55,8 @@
#include "GPU_material.h"
+#include "BLO_read_write.h"
+
/** Free (or release) any data used by this world (does not free the world itself). */
static void world_free_data(ID *id)
{
@@ -122,6 +128,54 @@ static void world_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void world_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ World *wrld = (World *)id;
+ if (wrld->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed datablocks. */
+ BLI_listbase_clear(&wrld->gpumaterial);
+
+ /* write LibData */
+ BLO_write_id_struct(writer, World, id_address, &wrld->id);
+ BKE_id_blend_write(writer, &wrld->id);
+
+ if (wrld->adt) {
+ BKE_animdata_blend_write(writer, wrld->adt);
+ }
+
+ /* nodetree is integral part of world, no libdata */
+ if (wrld->nodetree) {
+ BLO_write_struct(writer, bNodeTree, wrld->nodetree);
+ ntreeBlendWrite(writer, wrld->nodetree);
+ }
+
+ BKE_previewimg_blend_write(writer, wrld->preview);
+ }
+}
+
+static void world_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ World *wrld = (World *)id;
+ BLO_read_data_address(reader, &wrld->adt);
+ BKE_animdata_blend_read_data(reader, wrld->adt);
+
+ BLO_read_data_address(reader, &wrld->preview);
+ BKE_previewimg_blend_read(reader, wrld->preview);
+ BLI_listbase_clear(&wrld->gpumaterial);
+}
+
+static void world_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ World *wrld = (World *)id;
+ BLO_read_id_address(reader, wrld->id.lib, &wrld->ipo); // XXX deprecated - old animation system
+}
+
+static void world_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ World *wrld = (World *)id;
+ BLO_expand(expander, wrld->ipo); // XXX deprecated - old animation system
+}
+
IDTypeInfo IDType_ID_WO = {
.id_code = ID_WO,
.id_filter = FILTER_ID_WO,
@@ -139,10 +193,10 @@ IDTypeInfo IDType_ID_WO = {
.foreach_id = world_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = world_blend_write,
+ .blend_read_data = world_blend_read_data,
+ .blend_read_lib = world_blend_read_lib,
+ .blend_read_expand = world_blend_read_expand,
};
World *BKE_world_add(Main *bmain, const char *name)
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index cde4394a8c3..18a6e8a3525 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1299,6 +1299,11 @@ void BLI_setenv_if_new(const char *env, const char *val)
/**
* Get an env var, result has to be used immediately.
+ *
+* On windows getenv gets its variables from a static copy of the environment variables taken at
+ * process start-up, causing it to not pick up on environment variables created during runtime.
+ * This function uses an alternative method to get environment variables that does pick up on
+ * runtime environment variables.
*/
const char *BLI_getenv(const char *env)
{
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 1c638079230..3d42330dd4f 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2478,134 +2478,6 @@ static void direct_link_id_common(
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Read ID: Brush
- * \{ */
-
-/* library brush linking after fileread */
-static void lib_link_brush(BlendLibReader *reader, Brush *brush)
-{
- /* brush->(mask_)mtex.obj is ignored on purpose? */
- BLO_read_id_address(reader, brush->id.lib, &brush->mtex.tex);
- BLO_read_id_address(reader, brush->id.lib, &brush->mask_mtex.tex);
- BLO_read_id_address(reader, brush->id.lib, &brush->clone.image);
- BLO_read_id_address(reader, brush->id.lib, &brush->toggle_brush);
- BLO_read_id_address(reader, brush->id.lib, &brush->paint_curve);
-
- /* link default grease pencil palette */
- if (brush->gpencil_settings != NULL) {
- if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
- BLO_read_id_address(reader, brush->id.lib, &brush->gpencil_settings->material);
-
- if (!brush->gpencil_settings->material) {
- brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED;
- }
- }
- else {
- brush->gpencil_settings->material = NULL;
- }
- }
-}
-
-static void direct_link_brush(BlendDataReader *reader, Brush *brush)
-{
- /* brush itself has been read */
-
- /* fallof curve */
- BLO_read_data_address(reader, &brush->curve);
-
- BLO_read_data_address(reader, &brush->gradient);
-
- if (brush->curve) {
- BKE_curvemapping_blend_read(reader, brush->curve);
- }
- else {
- BKE_brush_curve_preset(brush, CURVE_PRESET_SHARP);
- }
-
- /* grease pencil */
- BLO_read_data_address(reader, &brush->gpencil_settings);
- if (brush->gpencil_settings != NULL) {
- BLO_read_data_address(reader, &brush->gpencil_settings->curve_sensitivity);
- BLO_read_data_address(reader, &brush->gpencil_settings->curve_strength);
- BLO_read_data_address(reader, &brush->gpencil_settings->curve_jitter);
-
- BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_pressure);
- BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_strength);
- BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_uv);
- BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_hue);
- BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_saturation);
- BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_value);
-
- if (brush->gpencil_settings->curve_sensitivity) {
- BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_sensitivity);
- }
-
- if (brush->gpencil_settings->curve_strength) {
- BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_strength);
- }
-
- if (brush->gpencil_settings->curve_jitter) {
- BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_jitter);
- }
-
- if (brush->gpencil_settings->curve_rand_pressure) {
- BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_pressure);
- }
-
- if (brush->gpencil_settings->curve_rand_strength) {
- BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_strength);
- }
-
- if (brush->gpencil_settings->curve_rand_uv) {
- BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_uv);
- }
-
- if (brush->gpencil_settings->curve_rand_hue) {
- BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_hue);
- }
-
- if (brush->gpencil_settings->curve_rand_saturation) {
- BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_saturation);
- }
-
- if (brush->gpencil_settings->curve_rand_value) {
- BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_rand_value);
- }
- }
-
- brush->preview = NULL;
- brush->icon_imbuf = NULL;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Palette
- * \{ */
-
-static void lib_link_palette(BlendLibReader *UNUSED(reader), Palette *UNUSED(palette))
-{
-}
-
-static void direct_link_palette(BlendDataReader *reader, Palette *palette)
-{
-
- /* palette itself has been read */
- BLO_read_list(reader, &palette->colors);
-}
-
-static void lib_link_paint_curve(BlendLibReader *UNUSED(reader), PaintCurve *UNUSED(pc))
-{
-}
-
-static void direct_link_paint_curve(BlendDataReader *reader, PaintCurve *pc)
-{
- BLO_read_data_address(reader, &pc->points);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Read Animation (legacy for version patching)
* \{ */
@@ -2915,118 +2787,6 @@ static void lib_link_pose(BlendLibReader *reader, Object *ob, bPose *pose)
}
}
-static void lib_link_bones(BlendLibReader *reader, Bone *bone)
-{
- IDP_BlendReadLib(reader, bone->prop);
-
- LISTBASE_FOREACH (Bone *, curbone, &bone->childbase) {
- lib_link_bones(reader, curbone);
- }
-}
-
-static void lib_link_armature(BlendLibReader *reader, bArmature *arm)
-{
- LISTBASE_FOREACH (Bone *, curbone, &arm->bonebase) {
- lib_link_bones(reader, curbone);
- }
-}
-
-static void direct_link_bones(BlendDataReader *reader, Bone *bone)
-{
- BLO_read_data_address(reader, &bone->parent);
- BLO_read_data_address(reader, &bone->prop);
- IDP_BlendDataRead(reader, &bone->prop);
-
- BLO_read_data_address(reader, &bone->bbone_next);
- BLO_read_data_address(reader, &bone->bbone_prev);
-
- bone->flag &= ~(BONE_DRAW_ACTIVE | BONE_DRAW_LOCKED_WEIGHT);
-
- BLO_read_list(reader, &bone->childbase);
-
- LISTBASE_FOREACH (Bone *, child, &bone->childbase) {
- direct_link_bones(reader, child);
- }
-}
-
-static void direct_link_armature(BlendDataReader *reader, bArmature *arm)
-{
- BLO_read_list(reader, &arm->bonebase);
- arm->bonehash = NULL;
- arm->edbo = NULL;
- /* Must always be cleared (armatures don't have their own edit-data). */
- arm->needs_flush_to_id = 0;
-
- BLO_read_data_address(reader, &arm->adt);
- BKE_animdata_blend_read_data(reader, arm->adt);
-
- LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
- direct_link_bones(reader, bone);
- }
-
- BLO_read_data_address(reader, &arm->act_bone);
- arm->act_edbone = NULL;
-
- BKE_armature_bone_hash_make(arm);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Camera
- * \{ */
-
-static void lib_link_camera(BlendLibReader *reader, Camera *ca)
-{
- BLO_read_id_address(reader, ca->id.lib, &ca->ipo); /* deprecated, for versioning */
-
- BLO_read_id_address(reader, ca->id.lib, &ca->dof_ob); /* deprecated, for versioning */
- BLO_read_id_address(reader, ca->id.lib, &ca->dof.focus_object);
-
- LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) {
- BLO_read_id_address(reader, ca->id.lib, &bgpic->ima);
- BLO_read_id_address(reader, ca->id.lib, &bgpic->clip);
- }
-}
-
-static void direct_link_camera(BlendDataReader *reader, Camera *ca)
-{
- BLO_read_data_address(reader, &ca->adt);
- BKE_animdata_blend_read_data(reader, ca->adt);
-
- BLO_read_list(reader, &ca->bg_images);
-
- LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) {
- bgpic->iuser.ok = 1;
- bgpic->iuser.scene = NULL;
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Light
- * \{ */
-
-static void lib_link_light(BlendLibReader *reader, Light *la)
-{
- BLO_read_id_address(reader, la->id.lib, &la->ipo); // XXX deprecated - old animation system
-}
-
-static void direct_link_light(BlendDataReader *reader, Light *la)
-{
- BLO_read_data_address(reader, &la->adt);
- BKE_animdata_blend_read_data(reader, la->adt);
-
- BLO_read_data_address(reader, &la->curfalloff);
- if (la->curfalloff) {
- BKE_curvemapping_blend_read(reader, la->curfalloff);
- }
-
- BLO_read_data_address(reader, &la->preview);
- BKE_previewimg_blend_read(reader, la->preview);
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -3041,253 +2801,6 @@ void blo_do_versions_key_uidgen(Key *key)
}
}
-static void lib_link_key(BlendLibReader *reader, Key *key)
-{
- BLI_assert((key->id.tag & LIB_TAG_EXTERN) == 0);
-
- BLO_read_id_address(reader, key->id.lib, &key->ipo); // XXX deprecated - old animation system
- BLO_read_id_address(reader, key->id.lib, &key->from);
-}
-
-static void switch_endian_keyblock(Key *key, KeyBlock *kb)
-{
- int elemsize = key->elemsize;
- char *data = kb->data;
-
- for (int a = 0; a < kb->totelem; a++) {
- const char *cp = key->elemstr;
- char *poin = data;
-
- while (cp[0]) { /* cp[0] == amount */
- switch (cp[1]) { /* cp[1] = type */
- case IPO_FLOAT:
- case IPO_BPOINT:
- case IPO_BEZTRIPLE: {
- int b = cp[0];
- BLI_endian_switch_float_array((float *)poin, b);
- poin += sizeof(float) * b;
- break;
- }
- }
-
- cp += 2;
- }
- data += elemsize;
- }
-}
-
-static void direct_link_key(BlendDataReader *reader, Key *key)
-{
- BLO_read_list(reader, &(key->block));
-
- BLO_read_data_address(reader, &key->adt);
- BKE_animdata_blend_read_data(reader, key->adt);
-
- BLO_read_data_address(reader, &key->refkey);
-
- LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
- BLO_read_data_address(reader, &kb->data);
-
- if (BLO_read_requires_endian_switch(reader)) {
- switch_endian_keyblock(key, kb);
- }
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Meta Ball
- * \{ */
-
-static void lib_link_mball(BlendLibReader *reader, MetaBall *mb)
-{
- for (int a = 0; a < mb->totcol; a++) {
- BLO_read_id_address(reader, mb->id.lib, &mb->mat[a]);
- }
-
- BLO_read_id_address(reader, mb->id.lib, &mb->ipo); // XXX deprecated - old animation system
-}
-
-static void direct_link_mball(BlendDataReader *reader, MetaBall *mb)
-{
- BLO_read_data_address(reader, &mb->adt);
- BKE_animdata_blend_read_data(reader, mb->adt);
-
- BLO_read_pointer_array(reader, (void **)&mb->mat);
-
- BLO_read_list(reader, &(mb->elems));
-
- BLI_listbase_clear(&mb->disp);
- mb->editelems = NULL;
- /* Must always be cleared (meta's don't have their own edit-data). */
- mb->needs_flush_to_id = 0;
- /* mb->edit_elems.first= mb->edit_elems.last= NULL;*/
- mb->lastelem = NULL;
- mb->batch_cache = NULL;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: World
- * \{ */
-
-static void lib_link_world(BlendLibReader *reader, World *wrld)
-{
- BLO_read_id_address(reader, wrld->id.lib, &wrld->ipo); // XXX deprecated - old animation system
-}
-
-static void direct_link_world(BlendDataReader *reader, World *wrld)
-{
- BLO_read_data_address(reader, &wrld->adt);
- BKE_animdata_blend_read_data(reader, wrld->adt);
-
- BLO_read_data_address(reader, &wrld->preview);
- BKE_previewimg_blend_read(reader, wrld->preview);
- BLI_listbase_clear(&wrld->gpumaterial);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Image
- * \{ */
-
-static void lib_link_image(BlendLibReader *UNUSED(reader), Image *ima)
-{
- /* Images have some kind of 'main' cache, when NULL we should also clear all others. */
- /* Needs to be done *after* cache pointers are restored (call to
- * `foreach_cache`/`blo_cache_storage_entry_restore_in_new`), easier for now to do it in
- * lib_link... */
- if (ima->cache == NULL) {
- BKE_image_free_buffers(ima);
- }
-}
-
-static void direct_link_image(BlendDataReader *reader, Image *ima)
-{
- BLO_read_list(reader, &ima->tiles);
-
- BLO_read_list(reader, &(ima->renderslots));
- if (!BLO_read_data_is_undo(reader)) {
- /* We reset this last render slot index only when actually reading a file, not for undo. */
- ima->last_render_slot = ima->render_slot;
- }
-
- BLO_read_list(reader, &(ima->views));
- BLO_read_list(reader, &(ima->packedfiles));
-
- if (ima->packedfiles.first) {
- LISTBASE_FOREACH (ImagePackedFile *, imapf, &ima->packedfiles) {
- BKE_packedfile_blend_read(reader, &imapf->packedfile);
- }
- ima->packedfile = NULL;
- }
- else {
- BKE_packedfile_blend_read(reader, &ima->packedfile);
- }
-
- BLI_listbase_clear(&ima->anims);
- BLO_read_data_address(reader, &ima->preview);
- BKE_previewimg_blend_read(reader, ima->preview);
- BLO_read_data_address(reader, &ima->stereo3d_format);
- LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
- tile->ok = IMA_OK;
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Curve
- * \{ */
-
-static void lib_link_curve(BlendLibReader *reader, Curve *cu)
-{
- for (int a = 0; a < cu->totcol; a++) {
- BLO_read_id_address(reader, cu->id.lib, &cu->mat[a]);
- }
-
- BLO_read_id_address(reader, cu->id.lib, &cu->bevobj);
- BLO_read_id_address(reader, cu->id.lib, &cu->taperobj);
- BLO_read_id_address(reader, cu->id.lib, &cu->textoncurve);
- BLO_read_id_address(reader, cu->id.lib, &cu->vfont);
- BLO_read_id_address(reader, cu->id.lib, &cu->vfontb);
- BLO_read_id_address(reader, cu->id.lib, &cu->vfonti);
- BLO_read_id_address(reader, cu->id.lib, &cu->vfontbi);
-
- BLO_read_id_address(reader, cu->id.lib, &cu->ipo); // XXX deprecated - old animation system
- BLO_read_id_address(reader, cu->id.lib, &cu->key);
-}
-
-static void switch_endian_knots(Nurb *nu)
-{
- if (nu->knotsu) {
- BLI_endian_switch_float_array(nu->knotsu, KNOTSU(nu));
- }
- if (nu->knotsv) {
- BLI_endian_switch_float_array(nu->knotsv, KNOTSV(nu));
- }
-}
-
-static void direct_link_curve(BlendDataReader *reader, Curve *cu)
-{
- BLO_read_data_address(reader, &cu->adt);
- BKE_animdata_blend_read_data(reader, cu->adt);
-
- /* Protect against integer overflow vulnerability. */
- CLAMP(cu->len_char32, 0, INT_MAX - 4);
-
- BLO_read_pointer_array(reader, (void **)&cu->mat);
-
- BLO_read_data_address(reader, &cu->str);
- BLO_read_data_address(reader, &cu->strinfo);
- BLO_read_data_address(reader, &cu->tb);
-
- if (cu->vfont == NULL) {
- BLO_read_list(reader, &(cu->nurb));
- }
- else {
- cu->nurb.first = cu->nurb.last = NULL;
-
- TextBox *tb = MEM_calloc_arrayN(MAXTEXTBOX, sizeof(TextBox), "TextBoxread");
- if (cu->tb) {
- memcpy(tb, cu->tb, cu->totbox * sizeof(TextBox));
- MEM_freeN(cu->tb);
- cu->tb = tb;
- }
- else {
- cu->totbox = 1;
- cu->actbox = 1;
- cu->tb = tb;
- cu->tb[0].w = cu->linewidth;
- }
- if (cu->wordspace == 0.0f) {
- cu->wordspace = 1.0f;
- }
- }
-
- cu->editnurb = NULL;
- cu->editfont = NULL;
- cu->batch_cache = NULL;
-
- LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
- BLO_read_data_address(reader, &nu->bezt);
- BLO_read_data_address(reader, &nu->bp);
- BLO_read_data_address(reader, &nu->knotsu);
- BLO_read_data_address(reader, &nu->knotsv);
- if (cu->vfont == NULL) {
- nu->charidx = 0;
- }
-
- if (BLO_read_requires_endian_switch(reader)) {
- switch_endian_knots(nu);
- }
- }
- cu->texflag &= ~CU_AUTOSPACE_EVALUATED;
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -3317,43 +2830,6 @@ static void direct_link_texture(BlendDataReader *reader, Tex *tex)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Read ID: Material
- * \{ */
-
-static void lib_link_material(BlendLibReader *reader, Material *ma)
-{
- BLO_read_id_address(reader, ma->id.lib, &ma->ipo); // XXX deprecated - old animation system
-
- /* relink grease pencil settings */
- if (ma->gp_style != NULL) {
- MaterialGPencilStyle *gp_style = ma->gp_style;
- if (gp_style->sima != NULL) {
- BLO_read_id_address(reader, ma->id.lib, &gp_style->sima);
- }
- if (gp_style->ima != NULL) {
- BLO_read_id_address(reader, ma->id.lib, &gp_style->ima);
- }
- }
-}
-
-static void direct_link_material(BlendDataReader *reader, Material *ma)
-{
- BLO_read_data_address(reader, &ma->adt);
- BKE_animdata_blend_read_data(reader, ma->adt);
-
- ma->texpaintslot = NULL;
-
- BLO_read_data_address(reader, &ma->preview);
- BKE_previewimg_blend_read(reader, ma->preview);
-
- BLI_listbase_clear(&ma->gpumaterial);
-
- BLO_read_data_address(reader, &ma->gp_style);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Read ID: Particle Settings
* \{ */
@@ -6844,45 +6320,6 @@ static void fix_relpaths_library(const char *basepath, Main *main)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Read ID: Light Probe
- * \{ */
-
-static void lib_link_lightprobe(BlendLibReader *reader, LightProbe *prb)
-{
- BLO_read_id_address(reader, prb->id.lib, &prb->visibility_grp);
-}
-
-static void direct_link_lightprobe(BlendDataReader *reader, LightProbe *prb)
-{
- BLO_read_data_address(reader, &prb->adt);
- BKE_animdata_blend_read_data(reader, prb->adt);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Speaker
- * \{ */
-
-static void lib_link_speaker(BlendLibReader *reader, Speaker *spk)
-{
- BLO_read_id_address(reader, spk->id.lib, &spk->sound);
-}
-
-static void direct_link_speaker(BlendDataReader *reader, Speaker *spk)
-{
- BLO_read_data_address(reader, &spk->adt);
- BKE_animdata_blend_read_data(reader, spk->adt);
-
-#if 0
- spk->sound = newdataadr(fd, spk->sound);
- direct_link_sound(fd, spk->sound);
-#endif
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Read ID: Sound
* \{ */
@@ -6921,88 +6358,6 @@ static void lib_link_sound(BlendLibReader *reader, bSound *sound)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Read ID: Masks
- * \{ */
-
-static void direct_link_mask(BlendDataReader *reader, Mask *mask)
-{
- BLO_read_data_address(reader, &mask->adt);
-
- BLO_read_list(reader, &mask->masklayers);
-
- LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
- /* can't use newdataadr since it's a pointer within an array */
- MaskSplinePoint *act_point_search = NULL;
-
- BLO_read_list(reader, &masklay->splines);
-
- LISTBASE_FOREACH (MaskSpline *, spline, &masklay->splines) {
- MaskSplinePoint *points_old = spline->points;
-
- BLO_read_data_address(reader, &spline->points);
-
- for (int i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *point = &spline->points[i];
-
- if (point->tot_uw) {
- BLO_read_data_address(reader, &point->uw);
- }
- }
-
- /* detect active point */
- if ((act_point_search == NULL) && (masklay->act_point >= points_old) &&
- (masklay->act_point < points_old + spline->tot_point)) {
- act_point_search = &spline->points[masklay->act_point - points_old];
- }
- }
-
- BLO_read_list(reader, &masklay->splines_shapes);
-
- LISTBASE_FOREACH (MaskLayerShape *, masklay_shape, &masklay->splines_shapes) {
- BLO_read_data_address(reader, &masklay_shape->data);
-
- if (masklay_shape->tot_vert) {
- if (BLO_read_requires_endian_switch(reader)) {
- BLI_endian_switch_float_array(masklay_shape->data,
- masklay_shape->tot_vert * sizeof(float) *
- MASK_OBJECT_SHAPE_ELEM_SIZE);
- }
- }
- }
-
- BLO_read_data_address(reader, &masklay->act_spline);
- masklay->act_point = act_point_search;
- }
-}
-
-static void lib_link_mask_parent(BlendLibReader *reader, Mask *mask, MaskParent *parent)
-{
- BLO_read_id_address(reader, mask->id.lib, &parent->id);
-}
-
-static void lib_link_mask(BlendLibReader *reader, Mask *mask)
-{
- LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
- MaskSpline *spline;
-
- spline = masklay->splines.first;
- while (spline) {
- for (int i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *point = &spline->points[i];
-
- lib_link_mask_parent(reader, mask, &point->parent);
- }
-
- lib_link_mask_parent(reader, mask, &spline->parent);
-
- spline = spline->next;
- }
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Read ID: Hair
* \{ */
@@ -7275,72 +6630,27 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
case ID_OB:
direct_link_object(&reader, (Object *)id);
break;
- case ID_CU:
- direct_link_curve(&reader, (Curve *)id);
- break;
- case ID_MB:
- direct_link_mball(&reader, (MetaBall *)id);
- break;
- case ID_MA:
- direct_link_material(&reader, (Material *)id);
- break;
case ID_TE:
direct_link_texture(&reader, (Tex *)id);
break;
- case ID_IM:
- direct_link_image(&reader, (Image *)id);
- break;
- case ID_LA:
- direct_link_light(&reader, (Light *)id);
- break;
case ID_IP:
direct_link_ipo(&reader, (Ipo *)id);
break;
- case ID_KE:
- direct_link_key(&reader, (Key *)id);
- break;
- case ID_WO:
- direct_link_world(&reader, (World *)id);
- break;
case ID_LI:
direct_link_library(fd, (Library *)id, main);
break;
- case ID_CA:
- direct_link_camera(&reader, (Camera *)id);
- break;
- case ID_SPK:
- direct_link_speaker(&reader, (Speaker *)id);
- break;
case ID_SO:
direct_link_sound(&reader, (bSound *)id);
break;
- case ID_LP:
- direct_link_lightprobe(&reader, (LightProbe *)id);
- break;
case ID_GR:
direct_link_collection(&reader, (Collection *)id);
break;
- case ID_AR:
- direct_link_armature(&reader, (bArmature *)id);
- break;
- case ID_BR:
- direct_link_brush(&reader, (Brush *)id);
- break;
case ID_PA:
direct_link_particlesettings(&reader, (ParticleSettings *)id);
break;
case ID_GD:
direct_link_gpencil(&reader, (bGPdata *)id);
break;
- case ID_MSK:
- direct_link_mask(&reader, (Mask *)id);
- break;
- case ID_PAL:
- direct_link_palette(&reader, (Palette *)id);
- break;
- case ID_PC:
- direct_link_paint_curve(&reader, (PaintCurve *)id);
- break;
case ID_CF:
direct_link_cachefile(&reader, (CacheFile *)id);
break;
@@ -7367,6 +6677,21 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
case ID_TXT:
case ID_VF:
case ID_MC:
+ case ID_PAL:
+ case ID_PC:
+ case ID_BR:
+ case ID_IM:
+ case ID_LA:
+ case ID_MA:
+ case ID_MB:
+ case ID_CU:
+ case ID_CA:
+ case ID_WO:
+ case ID_MSK:
+ case ID_SPK:
+ case ID_AR:
+ case ID_LP:
+ case ID_KE:
/* Do nothing. Handled by IDTypeInfo callback. */
break;
}
@@ -7972,9 +7297,6 @@ static void lib_link_all(FileData *fd, Main *bmain)
* Please keep order of entries in that switch matching that order, it's easier to quickly see
* whether something is wrong then. */
switch (GS(id->name)) {
- case ID_MSK:
- lib_link_mask(&reader, (Mask *)id);
- break;
case ID_WM:
lib_link_windowmanager(&reader, (wmWindowManager *)id);
break;
@@ -7993,48 +7315,18 @@ static void lib_link_all(FileData *fd, Main *bmain)
* 3D viewport may contains pointers to other ID data (like bgpic)! See T41411. */
lib_link_screen(&reader, (bScreen *)id);
break;
- case ID_WO:
- lib_link_world(&reader, (World *)id);
- break;
- case ID_LP:
- lib_link_lightprobe(&reader, (LightProbe *)id);
- break;
- case ID_SPK:
- lib_link_speaker(&reader, (Speaker *)id);
- break;
case ID_PA:
lib_link_particlesettings(&reader, (ParticleSettings *)id);
break;
- case ID_PC:
- lib_link_paint_curve(&reader, (PaintCurve *)id);
- break;
- case ID_BR:
- lib_link_brush(&reader, (Brush *)id);
- break;
case ID_GR:
lib_link_collection(&reader, (Collection *)id);
break;
case ID_SO:
lib_link_sound(&reader, (bSound *)id);
break;
- case ID_CA:
- lib_link_camera(&reader, (Camera *)id);
- break;
- case ID_LA:
- lib_link_light(&reader, (Light *)id);
- break;
- case ID_MB:
- lib_link_mball(&reader, (MetaBall *)id);
- break;
- case ID_CU:
- lib_link_curve(&reader, (Curve *)id);
- break;
case ID_CF:
lib_link_cachefiles(&reader, (CacheFile *)id);
break;
- case ID_AR:
- lib_link_armature(&reader, (bArmature *)id);
- break;
case ID_HA:
lib_link_hair(&reader, (Hair *)id);
break;
@@ -8044,24 +7336,12 @@ static void lib_link_all(FileData *fd, Main *bmain)
case ID_VO:
lib_link_volume(&reader, (Volume *)id);
break;
- case ID_MA:
- lib_link_material(&reader, (Material *)id);
- break;
case ID_TE:
lib_link_texture(&reader, (Tex *)id);
break;
- case ID_IM:
- lib_link_image(&reader, (Image *)id);
- break;
case ID_GD:
lib_link_gpencil(&reader, (bGPdata *)id);
break;
- case ID_PAL:
- lib_link_palette(&reader, (Palette *)id);
- break;
- case ID_KE:
- lib_link_key(&reader, (Key *)id);
- break;
case ID_SIM:
lib_link_simulation(&reader, (Simulation *)id);
break;
@@ -8080,6 +7360,21 @@ static void lib_link_all(FileData *fd, Main *bmain)
case ID_TXT:
case ID_VF:
case ID_MC:
+ case ID_PAL:
+ case ID_PC:
+ case ID_BR:
+ case ID_IM:
+ case ID_LA:
+ case ID_MA:
+ case ID_MB:
+ case ID_CU:
+ case ID_CA:
+ case ID_WO:
+ case ID_MSK:
+ case ID_SPK:
+ case ID_AR:
+ case ID_LP:
+ case ID_KE:
/* Do nothing. Handled by IDTypeInfo callback. */
break;
}
@@ -8765,73 +8060,12 @@ static void expand_collection(BlendExpander *expander, Collection *collection)
#endif
}
-static void expand_key(BlendExpander *expander, Key *key)
-{
- BLO_expand(expander, key->ipo); // XXX deprecated - old animation system
-}
-
static void expand_texture(BlendExpander *expander, Tex *tex)
{
BLO_expand(expander, tex->ima);
BLO_expand(expander, tex->ipo); // XXX deprecated - old animation system
}
-static void expand_brush(BlendExpander *expander, Brush *brush)
-{
- BLO_expand(expander, brush->mtex.tex);
- BLO_expand(expander, brush->mask_mtex.tex);
- BLO_expand(expander, brush->clone.image);
- BLO_expand(expander, brush->paint_curve);
- if (brush->gpencil_settings != NULL) {
- BLO_expand(expander, brush->gpencil_settings->material);
- }
-}
-
-static void expand_material(BlendExpander *expander, Material *ma)
-{
- BLO_expand(expander, ma->ipo); // XXX deprecated - old animation system
-
- if (ma->gp_style) {
- MaterialGPencilStyle *gp_style = ma->gp_style;
- BLO_expand(expander, gp_style->sima);
- BLO_expand(expander, gp_style->ima);
- }
-}
-
-static void expand_light(BlendExpander *expander, Light *la)
-{
- BLO_expand(expander, la->ipo); // XXX deprecated - old animation system
-}
-
-static void expand_world(BlendExpander *expander, World *wrld)
-{
- BLO_expand(expander, wrld->ipo); // XXX deprecated - old animation system
-}
-
-static void expand_mball(BlendExpander *expander, MetaBall *mb)
-{
- for (int a = 0; a < mb->totcol; a++) {
- BLO_expand(expander, mb->mat[a]);
- }
-}
-
-static void expand_curve(BlendExpander *expander, Curve *cu)
-{
- for (int a = 0; a < cu->totcol; a++) {
- BLO_expand(expander, cu->mat[a]);
- }
-
- BLO_expand(expander, cu->vfont);
- BLO_expand(expander, cu->vfontb);
- BLO_expand(expander, cu->vfonti);
- BLO_expand(expander, cu->vfontbi);
- BLO_expand(expander, cu->key);
- BLO_expand(expander, cu->ipo); // XXX deprecated - old animation system
- BLO_expand(expander, cu->bevobj);
- BLO_expand(expander, cu->taperobj);
- BLO_expand(expander, cu->textoncurve);
-}
-
/* callback function used to expand constraint ID-links */
static void expand_constraint_cb(bConstraint *UNUSED(con),
ID **idpoin,
@@ -8867,22 +8101,6 @@ static void expand_pose(BlendExpander *expander, bPose *pose)
}
}
-static void expand_bones(BlendExpander *expander, Bone *bone)
-{
- IDP_BlendReadExpand(expander, bone->prop);
-
- LISTBASE_FOREACH (Bone *, curBone, &bone->childbase) {
- expand_bones(expander, curBone);
- }
-}
-
-static void expand_armature(BlendExpander *expander, bArmature *arm)
-{
- LISTBASE_FOREACH (Bone *, curBone, &arm->bonebase) {
- expand_bones(expander, curBone);
- }
-}
-
static void expand_object_expandModifiers(void *userData,
Object *UNUSED(ob),
ID **idpoin,
@@ -9090,59 +8308,15 @@ static void expand_scene(BlendExpander *expander, Scene *sce)
}
}
-static void expand_camera(BlendExpander *expander, Camera *ca)
-{
- BLO_expand(expander, ca->ipo); // XXX deprecated - old animation system
-
- LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) {
- if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) {
- BLO_expand(expander, bgpic->ima);
- }
- else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) {
- BLO_expand(expander, bgpic->ima);
- }
- }
-}
-
static void expand_cachefile(BlendExpander *UNUSED(expander), CacheFile *UNUSED(cache_file))
{
}
-static void expand_speaker(BlendExpander *expander, Speaker *spk)
-{
- BLO_expand(expander, spk->sound);
-}
-
static void expand_sound(BlendExpander *expander, bSound *snd)
{
BLO_expand(expander, snd->ipo); // XXX deprecated - old animation system
}
-static void expand_lightprobe(BlendExpander *UNUSED(expander), LightProbe *UNUSED(prb))
-{
-}
-
-static void expand_mask_parent(BlendExpander *expander, MaskParent *parent)
-{
- if (parent->id) {
- BLO_expand(expander, parent->id);
- }
-}
-
-static void expand_mask(BlendExpander *expander, Mask *mask)
-{
- LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
- LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
- for (int i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *point = &spline->points[i];
- expand_mask_parent(expander, &point->parent);
- }
-
- expand_mask_parent(expander, &spline->parent);
- }
- }
-}
-
static void expand_gpencil(BlendExpander *expander, bGPdata *gpd)
{
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
@@ -9235,60 +8409,24 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
case ID_OB:
expand_object(&expander, (Object *)id);
break;
- case ID_CU:
- expand_curve(&expander, (Curve *)id);
- break;
- case ID_MB:
- expand_mball(&expander, (MetaBall *)id);
- break;
case ID_SCE:
expand_scene(&expander, (Scene *)id);
break;
- case ID_MA:
- expand_material(&expander, (Material *)id);
- break;
case ID_TE:
expand_texture(&expander, (Tex *)id);
break;
- case ID_WO:
- expand_world(&expander, (World *)id);
- break;
- case ID_LA:
- expand_light(&expander, (Light *)id);
- break;
- case ID_KE:
- expand_key(&expander, (Key *)id);
- break;
- case ID_CA:
- expand_camera(&expander, (Camera *)id);
- break;
- case ID_SPK:
- expand_speaker(&expander, (Speaker *)id);
- break;
case ID_SO:
expand_sound(&expander, (bSound *)id);
break;
- case ID_LP:
- expand_lightprobe(&expander, (LightProbe *)id);
- break;
- case ID_AR:
- expand_armature(&expander, (bArmature *)id);
- break;
case ID_GR:
expand_collection(&expander, (Collection *)id);
break;
- case ID_BR:
- expand_brush(&expander, (Brush *)id);
- break;
case ID_IP:
expand_ipo(&expander, (Ipo *)id); // XXX deprecated - old animation system
break;
case ID_PA:
expand_particlesettings(&expander, (ParticleSettings *)id);
break;
- case ID_MSK:
- expand_mask(&expander, (Mask *)id);
- break;
case ID_GD:
expand_gpencil(&expander, (bGPdata *)id);
break;
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 73a4b1a9098..cf07e9acad3 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -585,6 +585,18 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
do_versions_point_attributes(&pointcloud->pdata);
}
+ /* Show outliner mode column by default. */
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
+ if (space->spacetype == SPACE_OUTLINER) {
+ SpaceOutliner *space_outliner = (SpaceOutliner *)space;
+
+ space_outliner->flag |= SO_MODE_COLUMN;
+ }
+ }
+ }
+ }
/* Keep this block, even when empty. */
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 82cf8887396..d4e3f4646d6 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1393,154 +1393,6 @@ static void write_object(BlendWriter *writer, Object *ob, const void *id_address
}
}
-static void write_key(BlendWriter *writer, Key *key, const void *id_address)
-{
- if (key->id.us > 0 || BLO_write_is_undo(writer)) {
- /* write LibData */
- BLO_write_id_struct(writer, Key, id_address, &key->id);
- BKE_id_blend_write(writer, &key->id);
-
- if (key->adt) {
- BKE_animdata_blend_write(writer, key->adt);
- }
-
- /* direct data */
- LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
- BLO_write_struct(writer, KeyBlock, kb);
- if (kb->data) {
- BLO_write_raw(writer, kb->totelem * key->elemsize, kb->data);
- }
- }
- }
-}
-
-static void write_camera(BlendWriter *writer, Camera *cam, const void *id_address)
-{
- if (cam->id.us > 0 || BLO_write_is_undo(writer)) {
- /* write LibData */
- BLO_write_id_struct(writer, Camera, id_address, &cam->id);
- BKE_id_blend_write(writer, &cam->id);
-
- if (cam->adt) {
- BKE_animdata_blend_write(writer, cam->adt);
- }
-
- LISTBASE_FOREACH (CameraBGImage *, bgpic, &cam->bg_images) {
- BLO_write_struct(writer, CameraBGImage, bgpic);
- }
- }
-}
-
-static void write_mball(BlendWriter *writer, MetaBall *mb, const void *id_address)
-{
- if (mb->id.us > 0 || BLO_write_is_undo(writer)) {
- /* Clean up, important in undo case to reduce false detection of changed datablocks. */
- BLI_listbase_clear(&mb->disp);
- mb->editelems = NULL;
- /* Must always be cleared (meta's don't have their own edit-data). */
- mb->needs_flush_to_id = 0;
- mb->lastelem = NULL;
- mb->batch_cache = NULL;
-
- /* write LibData */
- BLO_write_id_struct(writer, MetaBall, id_address, &mb->id);
- BKE_id_blend_write(writer, &mb->id);
-
- /* direct data */
- BLO_write_pointer_array(writer, mb->totcol, mb->mat);
- if (mb->adt) {
- BKE_animdata_blend_write(writer, mb->adt);
- }
-
- LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
- BLO_write_struct(writer, MetaElem, ml);
- }
- }
-}
-
-static void write_curve(BlendWriter *writer, Curve *cu, const void *id_address)
-{
- if (cu->id.us > 0 || BLO_write_is_undo(writer)) {
- /* Clean up, important in undo case to reduce false detection of changed datablocks. */
- cu->editnurb = NULL;
- cu->editfont = NULL;
- cu->batch_cache = NULL;
-
- /* write LibData */
- BLO_write_id_struct(writer, Curve, id_address, &cu->id);
- BKE_id_blend_write(writer, &cu->id);
-
- /* direct data */
- BLO_write_pointer_array(writer, cu->totcol, cu->mat);
- if (cu->adt) {
- BKE_animdata_blend_write(writer, cu->adt);
- }
-
- if (cu->vfont) {
- BLO_write_raw(writer, cu->len + 1, cu->str);
- BLO_write_struct_array(writer, CharInfo, cu->len_char32 + 1, cu->strinfo);
- BLO_write_struct_array(writer, TextBox, cu->totbox, cu->tb);
- }
- else {
- /* is also the order of reading */
- LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
- BLO_write_struct(writer, Nurb, nu);
- }
- LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
- if (nu->type == CU_BEZIER) {
- BLO_write_struct_array(writer, BezTriple, nu->pntsu, nu->bezt);
- }
- else {
-
- BLO_write_struct_array(writer, BPoint, nu->pntsu * nu->pntsv, nu->bp);
- if (nu->knotsu) {
- BLO_write_float_array(writer, KNOTSU(nu), nu->knotsu);
- }
- if (nu->knotsv) {
- BLO_write_float_array(writer, KNOTSV(nu), nu->knotsv);
- }
- }
- }
- }
- }
-}
-
-static void write_image(BlendWriter *writer, Image *ima, const void *id_address)
-{
- if (ima->id.us > 0 || BLO_write_is_undo(writer)) {
- ImagePackedFile *imapf;
-
- /* Some trickery to keep forward compatibility of packed images. */
- BLI_assert(ima->packedfile == NULL);
- if (ima->packedfiles.first != NULL) {
- imapf = ima->packedfiles.first;
- ima->packedfile = imapf->packedfile;
- }
-
- /* write LibData */
- BLO_write_id_struct(writer, Image, id_address, &ima->id);
- BKE_id_blend_write(writer, &ima->id);
-
- for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
- BLO_write_struct(writer, ImagePackedFile, imapf);
- BKE_packedfile_blend_write(writer, imapf->packedfile);
- }
-
- BKE_previewimg_blend_write(writer, ima->preview);
-
- LISTBASE_FOREACH (ImageView *, iv, &ima->views) {
- BLO_write_struct(writer, ImageView, iv);
- }
- BLO_write_struct(writer, Stereo3dFormat, ima->stereo3d_format);
-
- BLO_write_struct_list(writer, ImageTile, &ima->tiles);
-
- ima->packedfile = NULL;
-
- BLO_write_struct_list(writer, RenderSlot, &ima->renderslots);
- }
-}
-
static void write_texture(BlendWriter *writer, Tex *tex, const void *id_address)
{
if (tex->id.us > 0 || BLO_write_is_undo(writer)) {
@@ -1567,85 +1419,6 @@ static void write_texture(BlendWriter *writer, Tex *tex, const void *id_address)
}
}
-static void write_material(BlendWriter *writer, Material *ma, const void *id_address)
-{
- if (ma->id.us > 0 || BLO_write_is_undo(writer)) {
- /* Clean up, important in undo case to reduce false detection of changed datablocks. */
- ma->texpaintslot = NULL;
- BLI_listbase_clear(&ma->gpumaterial);
-
- /* write LibData */
- BLO_write_id_struct(writer, Material, id_address, &ma->id);
- BKE_id_blend_write(writer, &ma->id);
-
- if (ma->adt) {
- BKE_animdata_blend_write(writer, ma->adt);
- }
-
- /* nodetree is integral part of material, no libdata */
- if (ma->nodetree) {
- BLO_write_struct(writer, bNodeTree, ma->nodetree);
- ntreeBlendWrite(writer, ma->nodetree);
- }
-
- BKE_previewimg_blend_write(writer, ma->preview);
-
- /* grease pencil settings */
- if (ma->gp_style) {
- BLO_write_struct(writer, MaterialGPencilStyle, ma->gp_style);
- }
- }
-}
-
-static void write_world(BlendWriter *writer, World *wrld, const void *id_address)
-{
- if (wrld->id.us > 0 || BLO_write_is_undo(writer)) {
- /* Clean up, important in undo case to reduce false detection of changed datablocks. */
- BLI_listbase_clear(&wrld->gpumaterial);
-
- /* write LibData */
- BLO_write_id_struct(writer, World, id_address, &wrld->id);
- BKE_id_blend_write(writer, &wrld->id);
-
- if (wrld->adt) {
- BKE_animdata_blend_write(writer, wrld->adt);
- }
-
- /* nodetree is integral part of world, no libdata */
- if (wrld->nodetree) {
- BLO_write_struct(writer, bNodeTree, wrld->nodetree);
- ntreeBlendWrite(writer, wrld->nodetree);
- }
-
- BKE_previewimg_blend_write(writer, wrld->preview);
- }
-}
-
-static void write_light(BlendWriter *writer, Light *la, const void *id_address)
-{
- if (la->id.us > 0 || BLO_write_is_undo(writer)) {
- /* write LibData */
- BLO_write_id_struct(writer, Light, id_address, &la->id);
- BKE_id_blend_write(writer, &la->id);
-
- if (la->adt) {
- BKE_animdata_blend_write(writer, la->adt);
- }
-
- if (la->curfalloff) {
- BKE_curvemapping_blend_write(writer, la->curfalloff);
- }
-
- /* Node-tree is integral part of lights, no libdata. */
- if (la->nodetree) {
- BLO_write_struct(writer, bNodeTree, la->nodetree);
- ntreeBlendWrite(writer, la->nodetree);
- }
-
- BKE_previewimg_blend_write(writer, la->preview);
- }
-}
-
static void write_collection_nolib(BlendWriter *writer, Collection *collection)
{
/* Shared function for collection data-blocks and scene master collection. */
@@ -2349,63 +2122,6 @@ static void write_screen(BlendWriter *writer, bScreen *screen, const void *id_ad
}
}
-static void write_bone(BlendWriter *writer, Bone *bone)
-{
- /* PATCH for upward compatibility after 2.37+ armature recode */
- bone->size[0] = bone->size[1] = bone->size[2] = 1.0f;
-
- /* Write this bone */
- BLO_write_struct(writer, Bone, bone);
-
- /* Write ID Properties -- and copy this comment EXACTLY for easy finding
- * of library blocks that implement this.*/
- if (bone->prop) {
- IDP_BlendWrite(writer, bone->prop);
- }
-
- /* Write Children */
- LISTBASE_FOREACH (Bone *, cbone, &bone->childbase) {
- write_bone(writer, cbone);
- }
-}
-
-static void write_armature(BlendWriter *writer, bArmature *arm, const void *id_address)
-{
- if (arm->id.us > 0 || BLO_write_is_undo(writer)) {
- /* Clean up, important in undo case to reduce false detection of changed datablocks. */
- arm->bonehash = NULL;
- arm->edbo = NULL;
- /* Must always be cleared (armatures don't have their own edit-data). */
- arm->needs_flush_to_id = 0;
- arm->act_edbone = NULL;
-
- BLO_write_id_struct(writer, bArmature, id_address, &arm->id);
- BKE_id_blend_write(writer, &arm->id);
-
- if (arm->adt) {
- BKE_animdata_blend_write(writer, arm->adt);
- }
-
- /* Direct data */
- LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
- write_bone(writer, bone);
- }
- }
-}
-
-static void write_speaker(BlendWriter *writer, Speaker *spk, const void *id_address)
-{
- if (spk->id.us > 0 || BLO_write_is_undo(writer)) {
- /* write LibData */
- BLO_write_id_struct(writer, Speaker, id_address, &spk->id);
- BKE_id_blend_write(writer, &spk->id);
-
- if (spk->adt) {
- BKE_animdata_blend_write(writer, spk->adt);
- }
- }
-}
-
static void write_sound(BlendWriter *writer, bSound *sound, const void *id_address)
{
if (sound->id.us > 0 || BLO_write_is_undo(writer)) {
@@ -2423,137 +2139,6 @@ static void write_sound(BlendWriter *writer, bSound *sound, const void *id_addre
}
}
-static void write_probe(BlendWriter *writer, LightProbe *prb, const void *id_address)
-{
- if (prb->id.us > 0 || BLO_write_is_undo(writer)) {
- /* write LibData */
- BLO_write_id_struct(writer, LightProbe, id_address, &prb->id);
- BKE_id_blend_write(writer, &prb->id);
-
- if (prb->adt) {
- BKE_animdata_blend_write(writer, prb->adt);
- }
- }
-}
-
-static void write_brush(BlendWriter *writer, Brush *brush, const void *id_address)
-{
- if (brush->id.us > 0 || BLO_write_is_undo(writer)) {
- BLO_write_id_struct(writer, Brush, id_address, &brush->id);
- BKE_id_blend_write(writer, &brush->id);
-
- if (brush->curve) {
- BKE_curvemapping_blend_write(writer, brush->curve);
- }
-
- if (brush->gpencil_settings) {
- BLO_write_struct(writer, BrushGpencilSettings, brush->gpencil_settings);
-
- if (brush->gpencil_settings->curve_sensitivity) {
- BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_sensitivity);
- }
- if (brush->gpencil_settings->curve_strength) {
- BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_strength);
- }
- if (brush->gpencil_settings->curve_jitter) {
- BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_jitter);
- }
- if (brush->gpencil_settings->curve_rand_pressure) {
- BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_pressure);
- }
- if (brush->gpencil_settings->curve_rand_strength) {
- BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_strength);
- }
- if (brush->gpencil_settings->curve_rand_uv) {
- BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_uv);
- }
- if (brush->gpencil_settings->curve_rand_hue) {
- BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_hue);
- }
- if (brush->gpencil_settings->curve_rand_saturation) {
- BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_saturation);
- }
- if (brush->gpencil_settings->curve_rand_value) {
- BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_value);
- }
- }
- if (brush->gradient) {
- BLO_write_struct(writer, ColorBand, brush->gradient);
- }
- }
-}
-
-static void write_palette(BlendWriter *writer, Palette *palette, const void *id_address)
-{
- if (palette->id.us > 0 || BLO_write_is_undo(writer)) {
- PaletteColor *color;
- BLO_write_id_struct(writer, Palette, id_address, &palette->id);
- BKE_id_blend_write(writer, &palette->id);
-
- for (color = palette->colors.first; color; color = color->next) {
- BLO_write_struct(writer, PaletteColor, color);
- }
- }
-}
-
-static void write_paintcurve(BlendWriter *writer, PaintCurve *pc, const void *id_address)
-{
- if (pc->id.us > 0 || BLO_write_is_undo(writer)) {
- BLO_write_id_struct(writer, PaintCurve, id_address, &pc->id);
- BKE_id_blend_write(writer, &pc->id);
-
- BLO_write_struct_array(writer, PaintCurvePoint, pc->tot_points, pc->points);
- }
-}
-
-static void write_mask(BlendWriter *writer, Mask *mask, const void *id_address)
-{
- if (mask->id.us > 0 || BLO_write_is_undo(writer)) {
- MaskLayer *masklay;
-
- BLO_write_id_struct(writer, Mask, id_address, &mask->id);
- BKE_id_blend_write(writer, &mask->id);
-
- if (mask->adt) {
- BKE_animdata_blend_write(writer, mask->adt);
- }
-
- for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- MaskSpline *spline;
- MaskLayerShape *masklay_shape;
-
- BLO_write_struct(writer, MaskLayer, masklay);
-
- for (spline = masklay->splines.first; spline; spline = spline->next) {
- int i;
-
- void *points_deform = spline->points_deform;
- spline->points_deform = NULL;
-
- BLO_write_struct(writer, MaskSpline, spline);
- BLO_write_struct_array(writer, MaskSplinePoint, spline->tot_point, spline->points);
-
- spline->points_deform = points_deform;
-
- for (i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *point = &spline->points[i];
-
- if (point->tot_uw) {
- BLO_write_struct_array(writer, MaskSplinePointUW, point->tot_uw, point->uw);
- }
- }
- }
-
- for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
- masklay_shape = masklay_shape->next) {
- BLO_write_struct(writer, MaskLayerShape, masklay_shape);
- BLO_write_float_array(
- writer, masklay_shape->tot_vert * MASK_OBJECT_SHAPE_ELEM_SIZE, masklay_shape->data);
- }
- }
- }
-}
-
static void write_cachefile(BlendWriter *writer, CacheFile *cache_file, const void *id_address)
{
if (cache_file->id.us > 0 || BLO_write_is_undo(writer)) {
@@ -2983,69 +2568,24 @@ static bool write_file_handle(Main *mainvar,
case ID_SCR:
write_screen(&writer, (bScreen *)id_buffer, id);
break;
- case ID_MSK:
- write_mask(&writer, (Mask *)id_buffer, id);
- break;
case ID_SCE:
write_scene(&writer, (Scene *)id_buffer, id);
break;
- case ID_CU:
- write_curve(&writer, (Curve *)id_buffer, id);
- break;
- case ID_MB:
- write_mball(&writer, (MetaBall *)id_buffer, id);
- break;
- case ID_IM:
- write_image(&writer, (Image *)id_buffer, id);
- break;
- case ID_CA:
- write_camera(&writer, (Camera *)id_buffer, id);
- break;
- case ID_LA:
- write_light(&writer, (Light *)id_buffer, id);
- break;
- case ID_KE:
- write_key(&writer, (Key *)id_buffer, id);
- break;
- case ID_WO:
- write_world(&writer, (World *)id_buffer, id);
- break;
- case ID_SPK:
- write_speaker(&writer, (Speaker *)id_buffer, id);
- break;
- case ID_LP:
- write_probe(&writer, (LightProbe *)id_buffer, id);
- break;
case ID_SO:
write_sound(&writer, (bSound *)id_buffer, id);
break;
case ID_GR:
write_collection(&writer, (Collection *)id_buffer, id);
break;
- case ID_AR:
- write_armature(&writer, (bArmature *)id_buffer, id);
- break;
case ID_OB:
write_object(&writer, (Object *)id_buffer, id);
break;
- case ID_MA:
- write_material(&writer, (Material *)id_buffer, id);
- break;
case ID_TE:
write_texture(&writer, (Tex *)id_buffer, id);
break;
case ID_PA:
write_particlesettings(&writer, (ParticleSettings *)id_buffer, id);
break;
- case ID_BR:
- write_brush(&writer, (Brush *)id_buffer, id);
- break;
- case ID_PAL:
- write_palette(&writer, (Palette *)id_buffer, id);
- break;
- case ID_PC:
- write_paintcurve(&writer, (PaintCurve *)id_buffer, id);
- break;
case ID_GD:
write_gpencil(&writer, (bGPdata *)id_buffer, id);
break;
@@ -3072,6 +2612,21 @@ static bool write_file_handle(Main *mainvar,
case ID_TXT:
case ID_VF:
case ID_MC:
+ case ID_PC:
+ case ID_PAL:
+ case ID_BR:
+ case ID_IM:
+ case ID_LA:
+ case ID_MA:
+ case ID_MB:
+ case ID_CU:
+ case ID_CA:
+ case ID_WO:
+ case ID_MSK:
+ case ID_SPK:
+ case ID_AR:
+ case ID_LP:
+ case ID_KE:
/* Do nothing, handled in IDTypeInfo callback. */
break;
case ID_LI:
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c
index f4e40c2670f..e4862617d12 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.c
+++ b/source/blender/editors/gpencil/gpencil_mesh.c
@@ -162,7 +162,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
Object *ob_gpencil = NULL;
ListBase list = {NULL, NULL};
- const bool simple_material = gpencil_bake_ob_list(C, depsgraph, scene, &list);
+ gpencil_bake_ob_list(C, depsgraph, scene, &list);
/* Cannot check this in poll because the active object changes. */
if (list.first == NULL) {
@@ -264,8 +264,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
ob_eval->obmat,
frame_offset,
use_seams,
- use_faces,
- simple_material);
+ use_faces);
/* Reproject all untaged created strokes. */
if (project_type != GP_REPROJECT_KEEP) {
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 6748211a1bc..fdab3649b13 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1525,6 +1525,9 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
pt1 = gps->points + i;
pt2 = gps->points + i + 1;
+ float inf1 = 0.0f;
+ float inf2 = 0.0f;
+
/* only process if it hasn't been masked out... */
if ((p->flags & GP_PAINTFLAG_SELECTMASK) && !(gps->points->flag & GP_SPOINT_SELECT)) {
continue;
@@ -1603,22 +1606,36 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
pt2->flag |= GP_SPOINT_TAG;
do_cull = true;
}
+
+ inf1 = 1.0f;
+ inf2 = 1.0f;
}
else {
- pt1->pressure -= gpencil_stroke_eraser_calc_influence(p, mval, radius, pc1) *
- strength;
- pt2->pressure -= gpencil_stroke_eraser_calc_influence(p, mval, radius, pc2) *
- strength * 0.5f;
+ /* Erase point. Only erase if the eraser is on top of the point. */
+ inf1 = gpencil_stroke_eraser_calc_influence(p, mval, radius, pc1);
+ if (inf1 > 0.0f) {
+ pt1->pressure = 0.0f;
+ pt1->flag |= GP_SPOINT_TAG;
+ do_cull = true;
+ }
+ inf2 = gpencil_stroke_eraser_calc_influence(p, mval, radius, pc2);
+ if (inf2 > 0.0f) {
+ pt2->pressure = 0.0f;
+ pt2->flag |= GP_SPOINT_TAG;
+ do_cull = true;
+ }
}
/* 2) Tag any point with overly low influence for removal in the next pass */
- if ((pt1->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) ||
- (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) {
+ if ((inf1 > 0.0f) &&
+ (((pt1->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) ||
+ (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)))) {
pt1->flag |= GP_SPOINT_TAG;
do_cull = true;
}
- if ((pt2->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) ||
- (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) {
+ if ((inf1 > 2.0f) &&
+ (((pt2->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) ||
+ (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)))) {
pt2->flag |= GP_SPOINT_TAG;
do_cull = true;
}
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 7b59d45b203..bbe66f7fd73 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -106,6 +106,7 @@ struct PreviewImage *UI_icon_to_preview(int icon_id);
int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, const bool big);
int UI_idcode_icon_get(const int idcode);
int UI_library_icon_get(const struct ID *id);
+int UI_mode_icon_get(const int mode);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index b5f902adfb5..c91b4d826a7 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -2294,6 +2294,36 @@ int UI_idcode_icon_get(const int idcode)
}
}
+int UI_mode_icon_get(const int mode)
+{
+ switch (mode) {
+ case OB_MODE_OBJECT:
+ return ICON_OBJECT_DATAMODE;
+ case OB_MODE_EDIT:
+ case OB_MODE_EDIT_GPENCIL:
+ return ICON_EDITMODE_HLT;
+ case OB_MODE_SCULPT:
+ case OB_MODE_SCULPT_GPENCIL:
+ return ICON_SCULPTMODE_HLT;
+ case OB_MODE_VERTEX_PAINT:
+ case OB_MODE_VERTEX_GPENCIL:
+ return ICON_VPAINT_HLT;
+ case OB_MODE_WEIGHT_PAINT:
+ case OB_MODE_WEIGHT_GPENCIL:
+ return ICON_WPAINT_HLT;
+ case OB_MODE_TEXTURE_PAINT:
+ return ICON_TPAINT_HLT;
+ case OB_MODE_PARTICLE_EDIT:
+ return ICON_PARTICLEMODE;
+ case OB_MODE_POSE:
+ return ICON_POSE_HLT;
+ case OB_MODE_PAINT_GPENCIL:
+ return ICON_GREASEPENCIL;
+ default:
+ return ICON_NONE;
+ }
+}
+
/* draws icon with dpi scale factor */
void UI_icon_draw(float x, float y, int icon_id)
{
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 31fe38bb82f..4bfd058eb07 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -635,7 +635,7 @@ static void ui_item_array(uiLayout *layout,
uiButNumber *number_but = (uiButNumber *)but;
but->a1 = number_but->step_size;
- ui_but_change_type(but, UI_BTYPE_NUM_SLIDER);
+ but = ui_but_change_type(but, UI_BTYPE_NUM_SLIDER);
}
}
}
@@ -709,7 +709,7 @@ static void ui_item_array(uiLayout *layout,
uiButNumber *number_but = (uiButNumber *)but;
but->a1 = number_but->step_size;
- ui_but_change_type(but, UI_BTYPE_NUM_SLIDER);
+ but = ui_but_change_type(but, UI_BTYPE_NUM_SLIDER);
}
if ((toggle == 1) && but->type == UI_BTYPE_CHECKBOX) {
but->type = UI_BTYPE_TOGGLE;
@@ -2347,7 +2347,7 @@ void uiItemFullR(uiLayout *layout,
uiButNumber *num_but = (uiButNumber *)but;
but->a1 = num_but->step_size;
- ui_but_change_type(but, UI_BTYPE_NUM_SLIDER);
+ but = ui_but_change_type(but, UI_BTYPE_NUM_SLIDER);
}
if (flag & UI_ITEM_R_CHECKBOX_INVERT) {
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 482ae4019c3..4de48fba494 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -2596,20 +2596,18 @@ static int object_convert_exec(bContext *C, wmOperator *op)
bGPdata *gpd = (bGPdata *)ob_gpencil->data;
gpd->draw_mode = GP_DRAWMODE_3D;
- BKE_gpencil_convert_mesh(bmain,
- depsgraph,
- scene,
- ob_gpencil,
- ob,
- angle,
- thickness,
- offset,
- matrix,
- 0,
- use_seams,
- use_faces,
- false);
- gpencilConverted = true;
+ gpencilConverted |= BKE_gpencil_convert_mesh(bmain,
+ depsgraph,
+ scene,
+ ob_gpencil,
+ ob,
+ angle,
+ thickness,
+ offset,
+ matrix,
+ 0,
+ use_seams,
+ use_faces);
/* Remove unused materials. */
int actcol = ob_gpencil->actcol;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 5070709cb6d..e6ea79a771a 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1920,6 +1920,9 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
if (ELEM(data->brush->sculpt_tool, SCULPT_TOOL_SCRAPE, SCULPT_TOOL_FILL) &&
data->brush->area_radius_factor > 0.0f) {
test_radius *= data->brush->area_radius_factor;
+ if (ss->cache && data->brush->flag2 & BRUSH_AREA_RADIUS_PRESSURE) {
+ test_radius *= ss->cache->pressure;
+ }
}
else {
test_radius *= data->brush->normal_radius_factor;
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index 3051413a405..b07dd18b6fc 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -501,6 +501,10 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object,
{
SculptSession *ss = object->sculpt;
+ if (initial_vertex == BOUNDARY_VERTEX_NONE) {
+ return NULL;
+ }
+
SCULPT_vertex_random_access_ensure(ss);
SCULPT_boundary_info_ensure(object);
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index 94052223e39..46a5f90f6c2 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -893,6 +893,9 @@ static int outliner_item_drag_drop_invoke(bContext *C,
if (outliner_item_is_co_within_close_toggle(te, view_mval[0])) {
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
+ if (outliner_is_co_within_mode_column(space_outliner, view_mval)) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
/* Scroll the view when dragging near edges, but not
* when the drag goes too far outside the region. */
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index fbef3aa07d7..3de786ddd4d 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -53,6 +53,7 @@
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -1884,6 +1885,109 @@ static void outliner_buttons(const bContext *C,
}
}
+static void outliner_mode_toggle_fn(bContext *C, void *tselem_poin, void *UNUSED(arg2))
+{
+ SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
+ TreeStoreElem *tselem = (TreeStoreElem *)tselem_poin;
+ TreeViewContext tvc;
+ outliner_viewcontext_init(C, &tvc);
+
+ TreeElement *te = outliner_find_tree_element(&space_outliner->tree, tselem);
+ if (!te) {
+ return;
+ }
+
+ wmWindow *win = CTX_wm_window(C);
+ const bool do_extend = win->eventstate->ctrl != 0;
+ outliner_item_mode_toggle(C, &tvc, te, do_extend);
+}
+
+/* Draw icons for adding and removing objects from the current interation mode. */
+static void outliner_draw_mode_column_toggle(uiBlock *block,
+ TreeViewContext *tvc,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ const bool lock_object_modes)
+{
+ const int active_mode = tvc->obact->mode;
+ bool draw_active_icon = true;
+
+ if (tselem->type == 0 && te->idcode == ID_OB) {
+ Object *ob = (Object *)tselem->id;
+
+ /* When not locking object modes, objects can remain in non-object modes. For modes that do not
+ * allow multi-object editing, these other objects should still show be viewed as not in the
+ * mode. Otherwise multiple objects show the same mode icon in the outliner even though only
+ * one object is actually editable in the mode. */
+ if (!lock_object_modes && ob != tvc->obact && !(tvc->ob_edit || tvc->ob_pose)) {
+ draw_active_icon = false;
+ }
+
+ if (ob->type == tvc->obact->type) {
+ int icon;
+ const char *tip;
+
+ if (draw_active_icon && ob->mode == tvc->obact->mode) {
+ icon = UI_mode_icon_get(active_mode);
+ tip = TIP_("Remove from the current mode");
+ }
+ else {
+ /* Not all objects support particle systems */
+ if (active_mode == OB_MODE_PARTICLE_EDIT && !psys_get_current(ob)) {
+ return;
+ }
+ icon = ICON_DOT;
+ tip = TIP_(
+ "Change the object in the current mode\n"
+ "* Ctrl to add to the current mode");
+ }
+
+ uiBut *but = uiDefIconBut(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ icon,
+ 0,
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ tip);
+ UI_but_func_set(but, outliner_mode_toggle_fn, tselem, NULL);
+ UI_but_flag_enable(but, UI_BUT_DRAG_LOCK);
+
+ if (ID_IS_LINKED(&ob->id)) {
+ UI_but_disable(but, TIP_("Can't edit external library data"));
+ }
+ }
+ }
+}
+
+static void outliner_draw_mode_column(const bContext *C,
+ uiBlock *block,
+ TreeViewContext *tvc,
+ SpaceOutliner *space_outliner,
+ ListBase *tree)
+{
+ TreeStoreElem *tselem;
+ const bool lock_object_modes = tvc->scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK;
+
+ LISTBASE_FOREACH (TreeElement *, te, tree) {
+ tselem = TREESTORE(te);
+
+ if (tvc->obact && tvc->obact->mode != OB_MODE_OBJECT) {
+ outliner_draw_mode_column_toggle(block, tvc, te, tselem, lock_object_modes);
+ }
+
+ if (TSELEM_OPEN(tselem, space_outliner)) {
+ outliner_draw_mode_column(C, block, tvc, space_outliner, &te->subtree);
+ }
+ }
+}
+
/* ****************************************************** */
/* Normal Drawing... */
@@ -3500,11 +3604,20 @@ static void outliner_draw_tree(bContext *C,
ARegion *region,
SpaceOutliner *space_outliner,
const float restrict_column_width,
+ const bool use_mode_column,
TreeElement **te_edit)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
int starty, startx;
+ /* Move the tree a unit left in view layer mode */
+ short mode_column_offset = (use_mode_column && (space_outliner->outlinevis == SO_SCENES)) ?
+ UI_UNIT_X :
+ 0;
+ if (!use_mode_column && (space_outliner->outlinevis == SO_VIEW_LAYER)) {
+ mode_column_offset -= UI_UNIT_X;
+ }
+
GPU_blend(GPU_BLEND_ALPHA); /* Only once. */
if (space_outliner->outlinevis == SO_DATA_API) {
@@ -3530,12 +3643,12 @@ static void outliner_draw_tree(bContext *C,
/* Gray hierarchy lines. */
starty = (int)region->v2d.tot.ymax - UI_UNIT_Y / 2 - OL_Y_OFFSET;
- startx = UI_UNIT_X / 2 - (U.pixelsize + 1) / 2;
+ startx = mode_column_offset + UI_UNIT_X / 2 - (U.pixelsize + 1) / 2;
outliner_draw_hierarchy_lines(space_outliner, &space_outliner->tree, startx, &starty);
/* Items themselves. */
starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
- startx = 0;
+ startx = mode_column_offset;
LISTBASE_FOREACH (TreeElement *, te, &space_outliner->tree) {
outliner_draw_tree_element(C,
block,
@@ -3658,12 +3771,22 @@ void draw_outliner(const bContext *C)
/* set matrix for 2d-view controls */
UI_view2d_view_ortho(v2d);
+ /* Only show mode column in View Layers and Scenes view */
+ const bool use_mode_column = (space_outliner->flag & SO_MODE_COLUMN) &&
+ (ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES));
+
/* draw outliner stuff (background, hierarchy lines and names) */
const float restrict_column_width = outliner_restrict_columns_width(space_outliner);
outliner_back(region);
block = UI_block_begin(C, region, __func__, UI_EMBOSS);
- outliner_draw_tree(
- (bContext *)C, block, &tvc, region, space_outliner, restrict_column_width, &te_edit);
+ outliner_draw_tree((bContext *)C,
+ block,
+ &tvc,
+ region,
+ space_outliner,
+ restrict_column_width,
+ use_mode_column,
+ &te_edit);
/* Compute outliner dimensions after it has been drawn. */
int tree_width, tree_height;
@@ -3698,6 +3821,11 @@ void draw_outliner(const bContext *C)
props_active);
}
+ /* Draw mode icons */
+ if (use_mode_column) {
+ outliner_draw_mode_column(C, block, &tvc, space_outliner, &space_outliner->tree);
+ }
+
UI_block_emboss_set(block, UI_EMBOSS);
/* Draw edit buttons if necessary. */
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index ad7346a5651..dea67a8678d 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -286,61 +286,6 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Object Mode Enter/Exit Utilities
- * \{ */
-
-static void item_object_mode_enter_exit(bContext *C, ReportList *reports, Object *ob, bool enter)
-{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *obact = OBACT(view_layer);
-
- if ((ob->type != obact->type) || ID_IS_LINKED(ob->data)) {
- return;
- }
- if (((ob->mode & obact->mode) != 0) == enter) {
- return;
- }
-
- if (ob == obact) {
- BKE_report(reports, RPT_WARNING, "Active object mode not changed");
- return;
- }
-
- Base *base = BKE_view_layer_base_find(view_layer, ob);
- if (base == NULL) {
- return;
- }
- Scene *scene = CTX_data_scene(C);
- outliner_object_mode_toggle(C, scene, view_layer, base);
-}
-
-void item_object_mode_enter_fn(bContext *C,
- ReportList *reports,
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
- TreeStoreElem *tselem,
- void *UNUSED(user_data))
-{
- Object *ob = (Object *)tselem->id;
- item_object_mode_enter_exit(C, reports, ob, true);
-}
-
-void item_object_mode_exit_fn(bContext *C,
- ReportList *reports,
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
- TreeStoreElem *tselem,
- void *UNUSED(user_data))
-{
- Object *ob = (Object *)tselem->id;
- item_object_mode_enter_exit(C, reports, ob, false);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Rename Operator
* \{ */
@@ -492,7 +437,8 @@ static void id_delete(bContext *C, ReportList *reports, TreeElement *te, TreeSto
Main *bmain = CTX_data_main(C);
ID *id = tselem->id;
- BLI_assert(te->idcode != 0 && id != NULL);
+ BLI_assert(id != NULL);
+ BLI_assert((tselem->type == 0 && te->idcode != 0) || tselem->type == TSE_LAYER_COLLECTION);
UNUSED_VARS_NDEBUG(te);
if (te->idcode == ID_LI && ((Library *)id)->parent != NULL) {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 7e7fdf4bab2..88080218e7f 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -222,7 +222,6 @@ typedef enum TreeItemSelectAction {
OL_ITEM_ACTIVATE = (1 << 2), /* Activate the item */
OL_ITEM_EXTEND = (1 << 3), /* Extend the current selection */
OL_ITEM_RECURSIVE = (1 << 4), /* Select recursively */
- OL_ITEM_TOGGLE_MODE = (1 << 5) /* Temporary */
} TreeItemSelectAction;
/* outliner_tree.c ----------------------------------------------- */
@@ -282,13 +281,14 @@ void outliner_item_select(struct bContext *C,
struct TreeElement *te,
const short select_flag);
-void outliner_object_mode_toggle(struct bContext *C,
- Scene *scene,
- ViewLayer *view_layer,
- Base *base);
-
bool outliner_item_is_co_over_name_icons(const TreeElement *te, float view_co_x);
bool outliner_item_is_co_within_close_toggle(const TreeElement *te, float view_co_x);
+bool outliner_is_co_within_mode_column(SpaceOutliner *space_outliner, const float view_mval[2]);
+
+void outliner_item_mode_toggle(struct bContext *C,
+ TreeViewContext *tvc,
+ TreeElement *te,
+ const bool do_extend);
/* outliner_edit.c ---------------------------------------------- */
typedef void (*outliner_operation_fn)(struct bContext *C,
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 266ea293d43..61228e24ed9 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -64,6 +64,7 @@
#include "ED_undo.h"
#include "WM_api.h"
+#include "WM_toolsystem.h"
#include "WM_types.h"
#include "UI_interface.h"
@@ -74,187 +75,91 @@
#include "outliner_intern.h"
-static bool do_outliner_activate_common(bContext *C,
- Main *bmain,
- Depsgraph *depsgraph,
- Scene *scene,
- ViewLayer *view_layer,
- Base *base,
- const bool extend,
- const bool do_exit)
+static void do_outliner_item_editmode_toggle(bContext *C, Scene *scene, Base *base)
{
- bool use_all = false;
-
- if (do_exit) {
- FOREACH_OBJECT_BEGIN (view_layer, ob_iter) {
- ED_object_mode_generic_exit(bmain, depsgraph, scene, ob_iter);
- }
- FOREACH_OBJECT_END;
- }
-
- /* Just like clicking in the object changes the active object,
- * clicking on the object data should change it as well. */
- ED_object_base_activate(C, base);
+ Main *bmain = CTX_data_main(C);
+ Object *ob = base->object;
- if (extend) {
- use_all = true;
+ if (BKE_object_is_in_editmode(ob)) {
+ ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
}
else {
- ED_object_base_deselect_all(view_layer, NULL, SEL_DESELECT);
+ ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_NO_CONTEXT);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
}
-
- return use_all;
}
-/**
- * Bring the newly selected object into edit mode.
- *
- * If extend is used, we try to have the other compatible selected objects in the new mode as well.
- * Otherwise only the new object will be active, selected and in the edit mode.
- */
-static void do_outliner_item_editmode_toggle(
- bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend)
+static void do_outliner_item_posemode_toggle(bContext *C, Base *base)
{
Main *bmain = CTX_data_main(C);
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Object *obact = OBACT(view_layer);
Object *ob = base->object;
- bool use_all = false;
- if (obact == NULL) {
- ED_object_base_activate(C, base);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- obact = ob;
- use_all = true;
- }
- else if (obact->data == ob->data) {
- use_all = true;
+ if (ID_IS_LINKED(ob)) {
+ BKE_report(CTX_wm_reports(C), RPT_WARNING, "Cannot pose libdata");
}
- else if (obact->mode == OB_MODE_OBJECT) {
- use_all = do_outliner_activate_common(
- C, bmain, depsgraph, scene, view_layer, base, extend, false);
- }
- else if ((ob->type != obact->type) || ((obact->mode & OB_MODE_EDIT) == 0) ||
- ((obact->mode & OB_MODE_POSE) && ELEM(OB_ARMATURE, ob->type, obact->type)) || !extend) {
- use_all = do_outliner_activate_common(
- C, bmain, depsgraph, scene, view_layer, base, extend, true);
- }
-
- if (use_all) {
- WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
+ else if (ob->mode & OB_MODE_POSE) {
+ ED_object_posemode_exit_ex(bmain, ob);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
}
else {
- bool ok;
- if (BKE_object_is_in_editmode(ob)) {
- ok = ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
- }
- else {
- ok = ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_NO_CONTEXT);
- }
- if (ok) {
- ED_object_base_select(base, (ob->mode & OB_MODE_EDIT) ? BA_SELECT : BA_DESELECT);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
+ ED_object_posemode_enter_ex(bmain, ob);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL);
}
}
-static void do_outliner_item_posemode_toggle(
- bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend)
+/* Swap the current active object from the interaction mode with the given base. */
+static void do_outliner_item_mode_toggle_generic(bContext *C, TreeViewContext *tvc, Base *base)
{
Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Object *obact = OBACT(view_layer);
- Object *ob = base->object;
- bool use_all = false;
-
- if (obact == NULL) {
- ED_object_base_activate(C, base);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- obact = ob;
- use_all = true;
- }
- else if (obact->data == ob->data) {
- use_all = true;
- }
- else if (obact->mode == OB_MODE_OBJECT) {
- use_all = do_outliner_activate_common(
- C, bmain, depsgraph, scene, view_layer, base, extend, false);
- }
- else if ((!ELEM(ob->type, obact->type)) ||
- ((obact->mode & OB_MODE_EDIT) && ELEM(OB_ARMATURE, ob->type, obact->type))) {
- use_all = do_outliner_activate_common(
- C, bmain, depsgraph, scene, view_layer, base, extend, true);
- }
+ const int active_mode = tvc->obact->mode;
- if (use_all) {
- WM_operator_name_call(C, "OBJECT_OT_posemode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
+ /* Return all objects to object mode. */
+ FOREACH_OBJECT_BEGIN (tvc->view_layer, ob_iter) {
+ ED_object_mode_generic_exit(bmain, depsgraph, tvc->scene, ob_iter);
}
- else {
- bool ok = false;
-
- if (ID_IS_LINKED(ob)) {
- BKE_report(CTX_wm_reports(C), RPT_WARNING, "Cannot pose libdata");
- }
- else if (ob->mode & OB_MODE_POSE) {
- ok = ED_object_posemode_exit_ex(bmain, ob);
- }
- else {
- ok = ED_object_posemode_enter_ex(bmain, ob);
- }
+ FOREACH_OBJECT_END;
+ WM_toolsystem_update_from_context_view3d(C);
- if (ok) {
- ED_object_base_select(base, (ob->mode & OB_MODE_POSE) ? BA_SELECT : BA_DESELECT);
-
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
- }
-}
+ Base *base_active = BKE_view_layer_base_find(tvc->view_layer, tvc->obact);
+ if (base_active != base) {
+ ED_object_base_select(base_active, BA_DESELECT);
+ ED_object_base_activate(C, base);
+ ED_object_base_select(base, BA_SELECT);
-/* For draw callback to run mode switching */
-void outliner_object_mode_toggle(bContext *C, Scene *scene, ViewLayer *view_layer, Base *base)
-{
- Object *obact = OBACT(view_layer);
- if (obact->mode & OB_MODE_EDIT) {
- do_outliner_item_editmode_toggle(C, scene, view_layer, base, true);
- }
- else if (obact->mode & OB_MODE_POSE) {
- do_outliner_item_posemode_toggle(C, scene, view_layer, base, true);
+ /* XXX: Must add undo step between activation and setting mode to prevent an assert. */
+ ED_undo_push(C, "outliner mode toggle");
+ ED_object_mode_set(C, active_mode);
+ ED_outliner_select_sync_from_object_tag(C);
}
}
/* Toggle the item's interaction mode if supported */
-static void outliner_item_mode_toggle(bContext *C,
- TreeViewContext *tvc,
- TreeElement *te,
- const bool extend)
+void outliner_item_mode_toggle(bContext *C,
+ TreeViewContext *tvc,
+ TreeElement *te,
+ const bool do_extend)
{
TreeStoreElem *tselem = TREESTORE(te);
- if (tselem->type == 0) {
- if (OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
- Object *ob = (Object *)outliner_search_back(te, ID_OB);
- if ((ob != NULL) && (ob->data == tselem->id)) {
- Base *base = BKE_view_layer_base_find(tvc->view_layer, ob);
- if ((base != NULL) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) {
- do_outliner_item_editmode_toggle(C, tvc->scene, tvc->view_layer, base, extend);
- }
- }
- }
- else if (ELEM(te->idcode, ID_GD)) {
- /* set grease pencil to object mode */
- WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
- }
- }
- else if (tselem->type == TSE_POSE_BASE) {
+ if (tselem->type == 0 && te->idcode == ID_OB) {
Object *ob = (Object *)tselem->id;
Base *base = BKE_view_layer_base_find(tvc->view_layer, ob);
- if (base != NULL) {
- do_outliner_item_posemode_toggle(C, tvc->scene, tvc->view_layer, base, extend);
+
+ /* Hidden objects can be removed from the mode. */
+ if (!base || (!(base->flag & BASE_VISIBLE_DEPSGRAPH) && (ob->mode != tvc->obact->mode))) {
+ return;
+ }
+
+ if (!do_extend) {
+ do_outliner_item_mode_toggle_generic(C, tvc, base);
+ }
+ else if (tvc->ob_edit && OB_TYPE_SUPPORT_EDITMODE(ob->type)) {
+ do_outliner_item_editmode_toggle(C, tvc->scene, base);
+ }
+ else if (tvc->ob_pose && ob->type == OB_ARMATURE) {
+ do_outliner_item_posemode_toggle(C, base);
}
}
}
@@ -1272,11 +1177,6 @@ void outliner_item_select(bContext *C,
extend,
select_flag & OL_ITEM_RECURSIVE,
activate_data || space_outliner->flag & SO_SYNC_SELECT);
-
- /* Mode toggle on data activate for now, but move later */
- if (select_flag & OL_ITEM_TOGGLE_MODE) {
- outliner_item_mode_toggle(C, &tvc, te, extend);
- }
}
}
@@ -1353,6 +1253,16 @@ static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *space_ou
return (view_co_x > region->v2d.cur.xmax - outliner_restrict_columns_width(space_outliner));
}
+bool outliner_is_co_within_mode_column(SpaceOutliner *space_outliner, const float view_mval[2])
+{
+ /* Mode toggles only show in View Layer and Scenes modes. */
+ if (!ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES)) {
+ return false;
+ }
+
+ return space_outliner->flag & SO_MODE_COLUMN && view_mval[0] < UI_UNIT_X;
+}
+
/**
* Action to run when clicking in the outliner,
*
@@ -1375,6 +1285,9 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
if (outliner_is_co_within_restrict_columns(space_outliner, region, view_mval[0])) {
return OPERATOR_CANCELLED;
}
+ if (outliner_is_co_within_mode_column(space_outliner, view_mval)) {
+ return OPERATOR_CANCELLED;
+ }
if (!(te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_mval[1]))) {
if (deselect_all) {
@@ -1413,7 +1326,7 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
const short select_flag = OL_ITEM_ACTIVATE | (select ? OL_ITEM_SELECT : OL_ITEM_DESELECT) |
(is_over_name_icons ? OL_ITEM_SELECT_DATA : 0) |
- (extend ? OL_ITEM_EXTEND : 0) | OL_ITEM_TOGGLE_MODE;
+ (extend ? OL_ITEM_EXTEND : 0);
outliner_item_select(C, space_outliner, activate_te, select_flag);
}
@@ -1542,6 +1455,10 @@ static int outliner_box_select_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
+ if (outliner_is_co_within_mode_column(space_outliner, view_mval)) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
+
return WM_gesture_box_invoke(C, op, event);
}
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 01b6e636ded..0743e841794 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -95,110 +95,105 @@
/** \name ID/Library/Data Set/Un-link Utilities
* \{ */
-static void set_operation_types(SpaceOutliner *space_outliner,
- ListBase *lb,
- int *scenelevel,
- int *objectlevel,
- int *idlevel,
- int *datalevel)
+static void get_element_operation_type(
+ TreeElement *te, int *scenelevel, int *objectlevel, int *idlevel, int *datalevel)
{
- TreeElement *te;
- TreeStoreElem *tselem;
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (tselem->flag & TSE_SELECTED) {
+ /* Layer collection points to collection ID. */
+ if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
+ if (*datalevel == 0) {
+ *datalevel = tselem->type;
+ }
+ else if (*datalevel != tselem->type) {
+ *datalevel = -1;
+ }
+ }
+ else {
+ const int idcode = (int)GS(tselem->id->name);
+ bool is_standard_id = false;
+ switch ((ID_Type)idcode) {
+ case ID_SCE:
+ *scenelevel = 1;
+ break;
+ case ID_OB:
+ *objectlevel = 1;
+ break;
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
- if (tselem->flag & TSE_SELECTED) {
- /* Layer collection points to collection ID. */
- if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
- if (*datalevel == 0) {
- *datalevel = tselem->type;
- }
- else if (*datalevel != tselem->type) {
- *datalevel = -1;
- }
+ case ID_ME:
+ case ID_CU:
+ case ID_MB:
+ case ID_LT:
+ case ID_LA:
+ case ID_AR:
+ case ID_CA:
+ case ID_SPK:
+ case ID_MA:
+ case ID_TE:
+ case ID_IP:
+ case ID_IM:
+ case ID_SO:
+ case ID_KE:
+ case ID_WO:
+ case ID_AC:
+ case ID_TXT:
+ case ID_GR:
+ case ID_LS:
+ case ID_LI:
+ case ID_VF:
+ case ID_NT:
+ case ID_BR:
+ case ID_PA:
+ case ID_GD:
+ case ID_MC:
+ case ID_MSK:
+ case ID_PAL:
+ case ID_PC:
+ case ID_CF:
+ case ID_WS:
+ case ID_LP:
+ case ID_HA:
+ case ID_PT:
+ case ID_VO:
+ case ID_SIM:
+ is_standard_id = true;
+ break;
+ case ID_WM:
+ case ID_SCR:
+ /* Those are ignored here. */
+ /* Note: while Screens should be manageable here, deleting a screen used by a workspace
+ * will cause crashes when trying to use that workspace, so for now let's play minimal,
+ * safe change. */
+ break;
+ }
+ if (idcode == ID_NLA) {
+ /* Fake one, not an actual ID type... */
+ is_standard_id = true;
}
- else {
- const int idcode = (int)GS(tselem->id->name);
- bool is_standard_id = false;
- switch ((ID_Type)idcode) {
- case ID_SCE:
- *scenelevel = 1;
- break;
- case ID_OB:
- *objectlevel = 1;
- break;
- case ID_ME:
- case ID_CU:
- case ID_MB:
- case ID_LT:
- case ID_LA:
- case ID_AR:
- case ID_CA:
- case ID_SPK:
- case ID_MA:
- case ID_TE:
- case ID_IP:
- case ID_IM:
- case ID_SO:
- case ID_KE:
- case ID_WO:
- case ID_AC:
- case ID_TXT:
- case ID_GR:
- case ID_LS:
- case ID_LI:
- case ID_VF:
- case ID_NT:
- case ID_BR:
- case ID_PA:
- case ID_GD:
- case ID_MC:
- case ID_MSK:
- case ID_PAL:
- case ID_PC:
- case ID_CF:
- case ID_WS:
- case ID_LP:
- case ID_HA:
- case ID_PT:
- case ID_VO:
- case ID_SIM:
- is_standard_id = true;
- break;
- case ID_WM:
- case ID_SCR:
- /* Those are ignored here. */
- /* Note: while Screens should be manageable here, deleting a screen used by a workspace
- * will cause crashes when trying to use that workspace, so for now let's play minimal,
- * safe change. */
- break;
+ if (is_standard_id) {
+ if (*idlevel == 0) {
+ *idlevel = idcode;
}
- if (idcode == ID_NLA) {
- /* Fake one, not an actual ID type... */
- is_standard_id = true;
+ else if (*idlevel != idcode) {
+ *idlevel = -1;
}
-
- if (is_standard_id) {
- if (*idlevel == 0) {
- *idlevel = idcode;
- }
- else if (*idlevel != idcode) {
- *idlevel = -1;
- }
- if (ELEM(*datalevel, TSE_VIEW_COLLECTION_BASE, TSE_SCENE_COLLECTION_BASE)) {
- *datalevel = 0;
- }
+ if (ELEM(*datalevel, TSE_VIEW_COLLECTION_BASE, TSE_SCENE_COLLECTION_BASE)) {
+ *datalevel = 0;
}
}
}
- if (TSELEM_OPEN(tselem, space_outliner)) {
- set_operation_types(
- space_outliner, &te->subtree, scenelevel, objectlevel, idlevel, datalevel);
- }
}
}
+static TreeElement *get_target_element(SpaceOutliner *space_outliner)
+{
+ TreeElement *te = outliner_find_element_with_flag(&space_outliner->tree, TSE_ACTIVE);
+ BLI_assert(te);
+
+ return te;
+}
+
static void unlink_action_fn(bContext *C,
ReportList *UNUSED(reports),
Scene *UNUSED(scene),
@@ -405,7 +400,7 @@ static void outliner_do_libdata_operation(bContext *C,
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
if (tselem->flag & TSE_SELECTED) {
- if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
+ if ((tselem->type == 0 && te->idcode != 0) || tselem->type == TSE_LAYER_COLLECTION) {
TreeStoreElem *tsep = te->parent ? TREESTORE(te->parent) : NULL;
operation_fn(C, reports, scene, te, tsep, tselem, user_data);
}
@@ -1492,16 +1487,6 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
C, op->reports, scene, space_outliner, &space_outliner->tree, item_rename_fn);
str = "Rename Object";
}
- else if (event == OL_OP_OBJECT_MODE_ENTER) {
- outliner_do_object_operation(
- C, op->reports, scene, space_outliner, &space_outliner->tree, item_object_mode_enter_fn);
- str = "Enter Current Mode";
- }
- else if (event == OL_OP_OBJECT_MODE_EXIT) {
- outliner_do_object_operation(
- C, op->reports, scene, space_outliner, &space_outliner->tree, item_object_mode_exit_fn);
- str = "Exit Current Mode";
- }
else {
BLI_assert(0);
return OPERATOR_CANCELLED;
@@ -1806,18 +1791,16 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutlinerIdOpTypes event;
/* check for invalid states */
if (space_outliner == NULL) {
return OPERATOR_CANCELLED;
}
- set_operation_types(
- space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
- event = RNA_enum_get(op->ptr, "type");
+ TreeElement *te = get_target_element(space_outliner);
+ get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
+ eOutlinerIdOpTypes event = RNA_enum_get(op->ptr, "type");
switch (event) {
case OUTLINER_IDOP_UNLINK: {
/* unlink datablock from its parent */
@@ -2138,18 +2121,16 @@ static int outliner_lib_operation_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutlinerLibOpTypes event;
/* check for invalid states */
if (space_outliner == NULL) {
return OPERATOR_CANCELLED;
}
- set_operation_types(
- space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
- event = RNA_enum_get(op->ptr, "type");
+ TreeElement *te = get_target_element(space_outliner);
+ get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
+ eOutlinerLibOpTypes event = RNA_enum_get(op->ptr, "type");
switch (event) {
case OL_LIB_RENAME: {
outliner_do_libdata_operation(
@@ -2271,8 +2252,9 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op)
if (space_outliner == NULL) {
return OPERATOR_CANCELLED;
}
- set_operation_types(
- space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+ TreeElement *te = get_target_element(space_outliner);
+ get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
/* get action to use */
act = BLI_findlink(&bmain->actions, RNA_enum_get(op->ptr, "action"));
@@ -2379,22 +2361,21 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
wmWindowManager *wm = CTX_wm_manager(C);
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutliner_AnimDataOps event;
/* check for invalid states */
if (space_outliner == NULL) {
return OPERATOR_CANCELLED;
}
- event = RNA_enum_get(op->ptr, "type");
- set_operation_types(
- space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+ TreeElement *te = get_target_element(space_outliner);
+ get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
if (datalevel != TSE_ANIM_DATA) {
return OPERATOR_CANCELLED;
}
/* perform the core operation */
+ eOutliner_AnimDataOps event = RNA_enum_get(op->ptr, "type");
switch (event) {
case OUTLINER_ANIMOP_CLEAR_ADT:
/* Remove Animation Data - this may remove the active action, in some cases... */
@@ -2484,15 +2465,10 @@ static const EnumPropertyItem prop_constraint_op_types[] = {
static int outliner_constraint_operation_exec(bContext *C, wmOperator *op)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutliner_PropConstraintOps event;
-
- event = RNA_enum_get(op->ptr, "type");
- set_operation_types(
- space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+ eOutliner_PropConstraintOps event = RNA_enum_get(op->ptr, "type");
outliner_do_data_operation(
- space_outliner, datalevel, event, &space_outliner->tree, constraint_fn, C);
+ space_outliner, TSE_CONSTRAINT, event, &space_outliner->tree, constraint_fn, C);
if (event == OL_CONSTRAINTOP_DELETE) {
outliner_cleanup_tree(space_outliner);
@@ -2536,15 +2512,10 @@ static const EnumPropertyItem prop_modifier_op_types[] = {
static int outliner_modifier_operation_exec(bContext *C, wmOperator *op)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutliner_PropModifierOps event;
-
- event = RNA_enum_get(op->ptr, "type");
- set_operation_types(
- space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+ eOutliner_PropModifierOps event = RNA_enum_get(op->ptr, "type");
outliner_do_data_operation(
- space_outliner, datalevel, event, &space_outliner->tree, modifier_fn, C);
+ space_outliner, TSE_MODIFIER, event, &space_outliner->tree, modifier_fn, C);
if (event == OL_MODIFIER_OP_DELETE) {
outliner_cleanup_tree(space_outliner);
@@ -2591,17 +2562,16 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutliner_PropDataOps event;
/* check for invalid states */
if (space_outliner == NULL) {
return OPERATOR_CANCELLED;
}
- event = RNA_enum_get(op->ptr, "type");
- set_operation_types(
- space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+ TreeElement *te = get_target_element(space_outliner);
+ get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
+ eOutliner_PropDataOps event = RNA_enum_get(op->ptr, "type");
switch (datalevel) {
case TSE_POSE_CHANNEL: {
outliner_do_data_operation(
@@ -2700,134 +2670,116 @@ static int outliner_operator_menu(bContext *C, const char *opname)
}
static int do_outliner_operation_event(bContext *C,
+ ReportList *reports,
ARegion *region,
SpaceOutliner *space_outliner,
- TreeElement *te,
- const float mval[2])
+ TreeElement *te)
{
- ReportList *reports = CTX_wm_reports(C); /* XXX... */
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ TreeStoreElem *tselem = TREESTORE(te);
- if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- TreeStoreElem *tselem = TREESTORE(te);
+ int select_flag = OL_ITEM_ACTIVATE | OL_ITEM_SELECT;
+ if (tselem->flag & TSE_SELECTED) {
+ select_flag |= OL_ITEM_EXTEND;
+ }
- /* select object that's clicked on and popup context menu */
- if (!(tselem->flag & TSE_SELECTED)) {
+ outliner_item_select(C, space_outliner, te, select_flag);
- if (outliner_flag_is_any_test(&space_outliner->tree, TSE_SELECTED, 1)) {
- outliner_flag_set(&space_outliner->tree, TSE_SELECTED, 0);
- }
+ /* Only redraw, don't rebuild here because TreeElement pointers will
+ * become invalid and operations will crash. */
+ ED_region_tag_redraw_no_rebuild(region);
+ ED_outliner_select_sync_from_outliner(C, space_outliner);
- tselem->flag |= TSE_SELECTED;
+ get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
- /* Only redraw, don't rebuild here because TreeElement pointers will
- * become invalid and operations will crash. */
- ED_region_tag_redraw_no_rebuild(region);
- ED_outliner_select_sync_from_outliner(C, space_outliner);
+ if (scenelevel) {
+ if (objectlevel || datalevel || idlevel) {
+ BKE_report(reports, RPT_WARNING, "Mixed selection");
+ return OPERATOR_CANCELLED;
}
-
- set_operation_types(
- space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
- if (scenelevel) {
- if (objectlevel || datalevel || idlevel) {
- BKE_report(reports, RPT_WARNING, "Mixed selection");
- return OPERATOR_CANCELLED;
- }
- return outliner_operator_menu(C, "OUTLINER_OT_scene_operation");
- }
- if (objectlevel) {
- WM_menu_name_call(C, "OUTLINER_MT_object", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
+ return outliner_operator_menu(C, "OUTLINER_OT_scene_operation");
+ }
+ if (objectlevel) {
+ WM_menu_name_call(C, "OUTLINER_MT_object", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ }
+ if (idlevel) {
+ if (idlevel == -1 || datalevel) {
+ BKE_report(reports, RPT_WARNING, "Mixed selection");
+ return OPERATOR_CANCELLED;
}
- if (idlevel) {
- if (idlevel == -1 || datalevel) {
- BKE_report(reports, RPT_WARNING, "Mixed selection");
- return OPERATOR_CANCELLED;
- }
- switch (idlevel) {
- case ID_GR:
- WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
- break;
- case ID_LI:
- return outliner_operator_menu(C, "OUTLINER_OT_lib_operation");
- break;
- default:
- return outliner_operator_menu(C, "OUTLINER_OT_id_operation");
- break;
- }
- }
- else if (datalevel) {
- if (datalevel == -1) {
- BKE_report(reports, RPT_WARNING, "Mixed selection");
- return OPERATOR_CANCELLED;
- }
- if (datalevel == TSE_ANIM_DATA) {
- return outliner_operator_menu(C, "OUTLINER_OT_animdata_operation");
- }
- if (datalevel == TSE_DRIVER_BASE) {
- /* do nothing... no special ops needed yet */
- return OPERATOR_CANCELLED;
- }
- if (datalevel == TSE_LAYER_COLLECTION) {
+ switch (idlevel) {
+ case ID_GR:
WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
return OPERATOR_FINISHED;
- }
- if (ELEM(datalevel, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
- WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
- }
- if (datalevel == TSE_ID_BASE) {
- /* do nothing... there are no ops needed here yet */
- return 0;
- }
- if (datalevel == TSE_CONSTRAINT) {
- return outliner_operator_menu(C, "OUTLINER_OT_constraint_operation");
- }
- if (datalevel == TSE_MODIFIER) {
- return outliner_operator_menu(C, "OUTLINER_OT_modifier_operation");
- }
- return outliner_operator_menu(C, "OUTLINER_OT_data_operation");
+ break;
+ case ID_LI:
+ return outliner_operator_menu(C, "OUTLINER_OT_lib_operation");
+ break;
+ default:
+ return outliner_operator_menu(C, "OUTLINER_OT_id_operation");
+ break;
}
-
- return 0;
}
-
- for (te = te->subtree.first; te; te = te->next) {
- int retval = do_outliner_operation_event(C, region, space_outliner, te, mval);
- if (retval) {
- return retval;
+ else if (datalevel) {
+ if (datalevel == -1) {
+ BKE_report(reports, RPT_WARNING, "Mixed selection");
+ return OPERATOR_CANCELLED;
+ }
+ if (datalevel == TSE_ANIM_DATA) {
+ return outliner_operator_menu(C, "OUTLINER_OT_animdata_operation");
+ }
+ if (datalevel == TSE_DRIVER_BASE) {
+ /* do nothing... no special ops needed yet */
+ return OPERATOR_CANCELLED;
}
+ if (datalevel == TSE_LAYER_COLLECTION) {
+ WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ }
+ if (ELEM(datalevel, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
+ WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ }
+ if (datalevel == TSE_ID_BASE) {
+ /* do nothing... there are no ops needed here yet */
+ return 0;
+ }
+ if (datalevel == TSE_CONSTRAINT) {
+ return outliner_operator_menu(C, "OUTLINER_OT_constraint_operation");
+ }
+ if (datalevel == TSE_MODIFIER) {
+ return outliner_operator_menu(C, "OUTLINER_OT_modifier_operation");
+ }
+ return outliner_operator_menu(C, "OUTLINER_OT_data_operation");
}
return 0;
}
-static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int outliner_operation(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
uiBut *but = UI_context_active_but_get(C);
- TreeElement *te;
- float fmval[2];
+ float view_mval[2];
if (but) {
UI_but_tooltip_timer_remove(C, but);
}
- UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+ UI_view2d_region_to_view(
+ &region->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
- for (te = space_outliner->tree.first; te; te = te->next) {
- int retval = do_outliner_operation_event(C, region, space_outliner, te, fmval);
- if (retval) {
- return retval;
- }
+ TreeElement *hovered_te = outliner_find_item_at_y(
+ space_outliner, &space_outliner->tree, view_mval[1]);
+ if (!hovered_te) {
+ /* Let this fall through to 'OUTLINER_MT_context_menu'. */
+ return OPERATOR_PASS_THROUGH;
}
- /* Let this fall through to 'OUTLINER_MT_context_menu'. */
- return OPERATOR_PASS_THROUGH;
+ return do_outliner_operation_event(C, op->reports, region, space_outliner, hovered_te);
}
/* Menu only! Calls other operators */
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 6a63c3c65c3..2ed834a15dd 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -314,7 +314,7 @@ static SpaceLink *outliner_create(const ScrArea *UNUSED(area), const Scene *UNUS
space_outliner->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_HIDE;
space_outliner->outlinevis = SO_VIEW_LAYER;
space_outliner->sync_select_dirty |= WM_OUTLINER_SYNC_SELECT_FROM_ALL;
- space_outliner->flag |= SO_SYNC_SELECT;
+ space_outliner->flag = SO_SYNC_SELECT | SO_MODE_COLUMN;
/* header */
region = MEM_callocN(sizeof(ARegion), "header for outliner");
diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc
index de079a89de7..1f873570f4a 100644
--- a/source/blender/gpu/intern/gpu_batch.cc
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -235,14 +235,12 @@ void GPU_batch_draw(GPUBatch *batch)
{
GPU_shader_bind(batch->shader);
GPU_batch_draw_advanced(batch, 0, 0, 0, 0);
- GPU_shader_unbind();
}
void GPU_batch_draw_range(GPUBatch *batch, int v_first, int v_count)
{
GPU_shader_bind(batch->shader);
GPU_batch_draw_advanced(batch, v_first, v_count, 0, 0);
- GPU_shader_unbind();
}
/* Draw multiple instance of a batch without having any instance attributes. */
@@ -252,7 +250,6 @@ void GPU_batch_draw_instanced(GPUBatch *batch, int i_count)
GPU_shader_bind(batch->shader);
GPU_batch_draw_advanced(batch, 0, 0, 0, i_count);
- GPU_shader_unbind();
}
void GPU_batch_draw_advanced(
diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc
index 0a488c0dfc0..9c3a88e30f0 100644
--- a/source/blender/gpu/intern/gpu_immediate.cc
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -186,7 +186,7 @@ void immEnd(void)
if (imm->batch) {
if (imm->vertex_idx < imm->vertex_len) {
- GPU_vertbuf_data_resize(imm->batch->verts[0], imm->vertex_len);
+ GPU_vertbuf_data_resize(imm->batch->verts[0], imm->vertex_idx);
/* TODO: resize only if vertex count is much smaller */
}
GPU_batch_set_shader(imm->batch, imm->shader);
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc
index 529c8795327..be523020e8a 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -173,12 +173,15 @@ void GPU_line_width(float width)
void GPU_point_size(float size)
{
- SET_MUTABLE_STATE(point_size, size * PIXELSIZE);
+ GPUStateManager *stack = Context::get()->state_manager;
+ auto &state = stack->mutable_state;
+ /* Keep the sign of point_size since it represents the enable state. */
+ state.point_size = size * ((state.point_size > 0.0) ? 1.0f : -1.0f);
}
/* Programmable point size
* - shaders set their own point size when enabled
- * - use glPointSize when disabled */
+ * - use GPU_point_size when disabled */
/* TODO remove and use program point size everywhere */
void GPU_program_point_size(bool enable)
{
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index 220c48457bc..ac8439167e3 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -51,6 +51,7 @@ void GPU_vertformat_clear(GPUVertFormat *format)
format->packed = false;
format->name_offset = 0;
format->name_len = 0;
+ format->deinterleaved = false;
for (uint i = 0; i < GPU_VERT_ATTR_MAX_LEN; i++) {
format->attrs[i].name_len = 0;
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
index 03762edac93..1678760e9cd 100644
--- a/source/blender/gpu/opengl/gl_state.cc
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -141,13 +141,13 @@ void GLStateManager::set_mutable_state(const GPUStateMutable &state)
GPUStateMutable changed = state ^ current_mutable_;
/* TODO remove, should be uniform. */
- if (changed.point_size != 0) {
+ if (float_as_uint(changed.point_size) != 0) {
if (state.point_size > 0.0f) {
glEnable(GL_PROGRAM_POINT_SIZE);
- glPointSize(state.point_size);
}
else {
glDisable(GL_PROGRAM_POINT_SIZE);
+ glPointSize(fabsf(state.point_size));
}
}
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 033a69d230e..6c3ffc09919 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -774,6 +774,7 @@ typedef enum eBrushFlags2 {
BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY = (1 << 4),
BRUSH_POSE_USE_LOCK_ROTATION = (1 << 5),
BRUSH_CLOTH_USE_COLLISION = (1 << 6),
+ BRUSH_AREA_RADIUS_PRESSURE = (1 << 7),
} eBrushFlags2;
typedef enum {
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 6fe6a5461e1..06ab01a9730 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -284,6 +284,7 @@ typedef enum eSpaceOutliner_Flag {
/* SO_HIDE_KEYINGSETINFO = (1 << 3), */ /* UNUSED */
SO_SKIP_SORT_ALPHA = (1 << 4),
SO_SYNC_SELECT = (1 << 5),
+ SO_MODE_COLUMN = (1 << 6),
} eSpaceOutliner_Flag;
/* SpaceOutliner.filter */
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index 8ad0271f355..b9688df8a3e 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -805,83 +805,91 @@ static eSDNA_Type sdna_type_nr(const char *dna_type)
static void cast_elem(
const char *ctype, const char *otype, int name_array_len, char *curdata, const char *olddata)
{
- double val = 0.0;
- int curlen = 1, oldlen = 1;
-
eSDNA_Type ctypenr, otypenr;
-
if ((otypenr = sdna_type_nr(otype)) == -1 || (ctypenr = sdna_type_nr(ctype)) == -1) {
return;
}
/* define lengths */
- oldlen = DNA_elem_type_size(otypenr);
- curlen = DNA_elem_type_size(ctypenr);
+ const int oldlen = DNA_elem_type_size(otypenr);
+ const int curlen = DNA_elem_type_size(ctypenr);
+
+ double old_value_f = 0.0;
+ uint64_t old_value_i = 0;
while (name_array_len > 0) {
switch (otypenr) {
case SDNA_TYPE_CHAR:
- val = *olddata;
+ old_value_i = *olddata;
+ old_value_f = (double)old_value_i;
break;
case SDNA_TYPE_UCHAR:
- val = *((unsigned char *)olddata);
+ old_value_i = *((unsigned char *)olddata);
+ old_value_f = (double)old_value_i;
break;
case SDNA_TYPE_SHORT:
- val = *((short *)olddata);
+ old_value_i = *((short *)olddata);
+ old_value_f = (double)old_value_i;
break;
case SDNA_TYPE_USHORT:
- val = *((unsigned short *)olddata);
+ old_value_i = *((unsigned short *)olddata);
+ old_value_f = (double)old_value_i;
break;
case SDNA_TYPE_INT:
- val = *((int *)olddata);
+ old_value_i = *((int *)olddata);
+ old_value_f = (double)old_value_i;
break;
case SDNA_TYPE_FLOAT:
- val = *((float *)olddata);
+ old_value_f = *((float *)olddata);
+ old_value_i = (uint64_t)(int64_t)old_value_f;
break;
case SDNA_TYPE_DOUBLE:
- val = *((double *)olddata);
+ old_value_f = *((double *)olddata);
+ old_value_i = (uint64_t)(int64_t)old_value_f;
break;
case SDNA_TYPE_INT64:
- val = *((int64_t *)olddata);
+ old_value_i = (uint64_t) * ((int64_t *)olddata);
+ old_value_f = (double)old_value_i;
break;
case SDNA_TYPE_UINT64:
- val = *((uint64_t *)olddata);
+ old_value_i = *((uint64_t *)olddata);
+ old_value_f = (double)old_value_i;
break;
}
switch (ctypenr) {
case SDNA_TYPE_CHAR:
- *curdata = val;
+ *curdata = (char)old_value_i;
break;
case SDNA_TYPE_UCHAR:
- *((unsigned char *)curdata) = val;
+ *((unsigned char *)curdata) = (unsigned char)old_value_i;
break;
case SDNA_TYPE_SHORT:
- *((short *)curdata) = val;
+ *((short *)curdata) = (short)old_value_i;
break;
case SDNA_TYPE_USHORT:
- *((unsigned short *)curdata) = val;
+ *((unsigned short *)curdata) = (unsigned short)old_value_i;
break;
case SDNA_TYPE_INT:
- *((int *)curdata) = val;
+ *((int *)curdata) = (int)old_value_i;
break;
case SDNA_TYPE_FLOAT:
if (otypenr < 2) {
- val /= 255;
+ old_value_f /= 255.0;
}
- *((float *)curdata) = val;
+ *((float *)curdata) = old_value_f;
break;
case SDNA_TYPE_DOUBLE:
if (otypenr < 2) {
- val /= 255;
+ old_value_f /= 255.0;
}
- *((double *)curdata) = val;
+ *((double *)curdata) = old_value_f;
break;
case SDNA_TYPE_INT64:
- *((int64_t *)curdata) = val;
+ *((int64_t *)curdata) = (int64_t)old_value_i;
break;
case SDNA_TYPE_UINT64:
- *((uint64_t *)curdata) = val;
+ *((uint64_t *)curdata) = old_value_i;
break;
}
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 0b923eb5635..3fd32aa6fd7 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -2971,6 +2971,13 @@ static void rna_def_brush(BlenderRNA *brna)
prop, "Plane Offset Pressure", "Enable tablet pressure sensitivity for offset");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "use_pressure_area_radius", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_AREA_RADIUS_PRESSURE);
+ RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
+ RNA_def_property_ui_text(
+ prop, "Area Radius Pressure", "Enable tablet pressure sensitivity for area radius");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "use_pressure_size", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SIZE_PRESSURE);
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 3067a5a9453..eab6349317a 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -3019,7 +3019,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
/* physical properties */
prop = RNA_def_property(srna, "mass", PROP_FLOAT, PROP_UNIT_MASS);
RNA_def_property_range(prop, 0.00000001f, 100000.0f);
- RNA_def_property_ui_range(prop, 0.01, 100, 1, 3);
+ RNA_def_property_ui_range(prop, 0.01, 100, 1, 4);
RNA_def_property_ui_text(prop, "Mass", "Mass of the particles");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
@@ -3349,7 +3349,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "keyed_loops", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "keyed_loops");
RNA_def_property_range(prop, 1.0f, 10000.0f);
- RNA_def_property_ui_range(prop, 1.0f, 100.0f, 0.1, 3);
+ RNA_def_property_ui_range(prop, 1.0f, 100.0f, 1, 3);
RNA_def_property_ui_text(prop, "Loop Count", "Number of times the keys are looped");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 99f81fd531a..66d7685b3a6 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -3041,6 +3041,12 @@ static void rna_def_space_outliner(BlenderRNA *brna)
prop, "Sync Outliner Selection", "Sync outliner selection with other editors");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+ prop = RNA_def_property(srna, "show_mode_column", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SO_MODE_COLUMN);
+ RNA_def_property_ui_text(
+ prop, "Show Mode Column", "Show the mode column for mode toggle and activation");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
/* Granular restriction column option. */
prop = RNA_def_property(srna, "show_restrict_column_enable", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_ENABLE);