diff options
author | Hans Goudey <h.goudey@me.com> | 2020-09-11 01:43:08 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2020-09-11 01:43:08 +0300 |
commit | eabba50141477b9d35f00e5790052973a2f152d8 (patch) | |
tree | f2a06d8360751efb20f96fef3acc949a69964c68 /source | |
parent | 1b5f355af8a60347e880da19bd84dfdaea1a2d9e (diff) | |
parent | a444b38fa37d7e6e7b5b3e792da3b3bb8dc6b3b5 (diff) |
Merge branch 'property-search-button-label-pointer' into property-search-move-context-to-panel
Diffstat (limited to 'source')
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(®ion->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + UI_view2d_region_to_view( + ®ion->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); |