From 62547c192e1311d30f6d90c10f36507cd4379510 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 24 Feb 2024 20:33:49 +0100 Subject: [PATCH] GPv3: Optional automatic conversion of legacy GP objects on fileload. This adds a new exprimental option to automatically convert GP legacy data to GPv3 one. It supports also linking and appending cases. Conversion also happens when opening a file linking GP legacy data saved by an older .blendfile. --- scripts/startup/bl_ui/space_userpref.py | 1 + .../BKE_grease_pencil_legacy_convert.hh | 4 + .../intern/blendfile_link_append.cc | 17 ++++ .../intern/grease_pencil_convert_legacy.cc | 80 +++++++++++++++++-- .../blenloader/intern/versioning_common.cc | 7 ++ source/blender/makesdna/DNA_userdef_types.h | 3 +- source/blender/makesrna/intern/rna_userdef.cc | 9 +++ 7 files changed, 113 insertions(+), 8 deletions(-) diff --git a/scripts/startup/bl_ui/space_userpref.py b/scripts/startup/bl_ui/space_userpref.py index a33892ace51..9bfbacee1e9 100644 --- a/scripts/startup/bl_ui/space_userpref.py +++ b/scripts/startup/bl_ui/space_userpref.py @@ -2674,6 +2674,7 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel): ({"property": "use_sculpt_texture_paint"}, ("blender/blender/issues/96225", "#96225")), ({"property": "use_experimental_compositors"}, ("blender/blender/issues/88150", "#88150")), ({"property": "use_grease_pencil_version3"}, ("blender/blender/projects/6", "Grease Pencil 3.0")), + ({"property": "use_grease_pencil_version3_convert_on_load"}, ("blender/blender/projects/6", "Grease Pencil 3.0")), ({"property": "use_new_matrix_socket"}, ("blender/blender/issues/116067", "Matrix Socket")), ({"property": "enable_overlay_next"}, ("blender/blender/issues/102179", "#102179")), ({"property": "use_extension_repos"}, ("/blender/blender/issues/117286", "#117286")), diff --git a/source/blender/blenkernel/BKE_grease_pencil_legacy_convert.hh b/source/blender/blenkernel/BKE_grease_pencil_legacy_convert.hh index b9a20559e64..93ecae79dc1 100644 --- a/source/blender/blenkernel/BKE_grease_pencil_legacy_convert.hh +++ b/source/blender/blenkernel/BKE_grease_pencil_legacy_convert.hh @@ -10,6 +10,7 @@ struct bGPdata; struct bGPDframe; +struct BlendFileReadReport; struct GreasePencil; struct GreasePencilDrawing; struct ListBase; @@ -27,6 +28,9 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b void legacy_gpencil_object(Main &bmain, Object &object); +/** Main entry point to convert all legacy GPData into GreasePencil data and objects. */ +void legacy_main(Main &bmain, BlendFileReadReport &reports); + void thickness_factor_to_modifier(const bGPdata &src_object_data, Object &dst_object); void layer_adjustments_to_modifiers(Main &bmain, const bGPdata &src_object_data, diff --git a/source/blender/blenkernel/intern/blendfile_link_append.cc b/source/blender/blenkernel/intern/blendfile_link_append.cc index b8517b7a867..f0fed2ab14e 100644 --- a/source/blender/blenkernel/intern/blendfile_link_append.cc +++ b/source/blender/blenkernel/intern/blendfile_link_append.cc @@ -36,6 +36,7 @@ #include "BLT_translation.hh" +#include "BKE_grease_pencil_legacy_convert.hh" #include "BKE_idtype.hh" #include "BKE_key.hh" #include "BKE_layer.hh" @@ -1379,6 +1380,14 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList * blendfile_link_append_proxies_convert(bmain, reports); BKE_main_mesh_legacy_convert_auto_smooth(*bmain); + + if (U.experimental.use_grease_pencil_version3 && + U.experimental.use_grease_pencil_version3_convert_on_load) + { + BlendFileReadReport bf_reports{}; + bf_reports.reports = reports; + blender::bke::greasepencil::convert::legacy_main(*bmain, bf_reports); + } } void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *reports) @@ -1496,6 +1505,14 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re if ((lapp_context->params->flag & FILE_LINK) != 0) { blendfile_link_append_proxies_convert(lapp_context->params->bmain, reports); BKE_main_mesh_legacy_convert_auto_smooth(*lapp_context->params->bmain); + + if (U.experimental.use_grease_pencil_version3 && + U.experimental.use_grease_pencil_version3_convert_on_load) + { + BlendFileReadReport bf_reports{}; + bf_reports.reports = reports; + blender::bke::greasepencil::convert::legacy_main(*lapp_context->params->bmain, bf_reports); + } } BKE_main_namemap_clear(lapp_context->params->bmain); diff --git a/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc b/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc index 34a6953afe7..084361f95ce 100644 --- a/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc +++ b/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc @@ -6,6 +6,8 @@ * \ingroup bke */ +#include + #include #include "BKE_anim_data.hh" @@ -19,15 +21,20 @@ #include "BKE_grease_pencil_legacy_convert.hh" #include "BKE_idprop.hh" #include "BKE_lib_id.hh" +#include "BKE_lib_remap.hh" +#include "BKE_main.hh" #include "BKE_material.h" #include "BKE_modifier.hh" #include "BKE_node.hh" #include "BKE_node_tree_update.hh" #include "BKE_object.hh" +#include "BLO_readfile.hh" + #include "BLI_color.hh" #include "BLI_function_ref.hh" #include "BLI_listbase.h" +#include "BLI_map.hh" #include "BLI_math_matrix.h" #include "BLI_math_vector_types.hh" #include "BLI_string.h" @@ -2024,21 +2031,41 @@ static void legacy_object_modifiers(Main & /*bmain*/, Object &object) } } -void legacy_gpencil_object(Main &bmain, Object &object) +static void legacy_gpencil_object_ex( + Main &bmain, + Object &object, + std::optional> legacy_to_greasepencil_data) { - bGPdata *gpd = static_cast(object.data); + BLI_assert((GS(static_cast(object.data)->name) == ID_GD_LEGACY)); + + bGPdata *gpd = static_cast(object.data); + GreasePencil *new_grease_pencil = nullptr; + bool do_gpencil_data_conversion = true; + + if (legacy_to_greasepencil_data) { + new_grease_pencil = legacy_to_greasepencil_data->lookup_default(gpd, nullptr); + do_gpencil_data_conversion = (new_grease_pencil == nullptr); + } + + if (!new_grease_pencil) { + new_grease_pencil = static_cast( + BKE_id_new_in_lib(&bmain, gpd->id.lib, ID_GP, gpd->id.name + 2)); + id_us_min(&new_grease_pencil->id); + } - GreasePencil *new_grease_pencil = static_cast( - BKE_id_new(&bmain, ID_GP, gpd->id.name + 2)); object.data = new_grease_pencil; object.type = OB_GREASE_PENCIL; /* NOTE: Could also use #BKE_id_free_us, to also free the legacy GP if not used anymore? */ id_us_min(&gpd->id); - /* No need to increase user-count of `new_grease_pencil`, - * since ID creation already set it to 1. */ + id_us_plus(&new_grease_pencil->id); - legacy_gpencil_to_grease_pencil(bmain, *new_grease_pencil, *gpd); + if (do_gpencil_data_conversion) { + legacy_gpencil_to_grease_pencil(bmain, *new_grease_pencil, *gpd); + if (legacy_to_greasepencil_data) { + legacy_to_greasepencil_data->add(gpd, new_grease_pencil); + } + } legacy_object_modifiers(bmain, object); @@ -2050,6 +2077,45 @@ void legacy_gpencil_object(Main &bmain, Object &object) BKE_object_free_derived_caches(&object); } +void legacy_gpencil_object(Main &bmain, Object &object) +{ + legacy_gpencil_object_ex(bmain, object, std::nullopt); +} + +void legacy_main(Main &bmain, BlendFileReadReport & /*reports*/) +{ + /* Allows to convert a legacy GPencil data only once, in case it's used by several objects. */ + blender::Map legacy_to_greasepencil_data; + + LISTBASE_FOREACH (Object *, object, &bmain.objects) { + if (object->type != OB_GPENCIL_LEGACY) { + continue; + } + legacy_gpencil_object_ex(bmain, *object, std::make_optional(legacy_to_greasepencil_data)); + } + + /* Potential other usages of legacy bGPdata IDs also need to be remapped to their matching new + * GreasePencil counterparts. */ + blender::bke::id::IDRemapper gpd_remapper; + /* Allow remapping from legacy bGPdata IDs to new GreasePencil ones. */ + gpd_remapper.allow_idtype_mismatch = true; + + LISTBASE_FOREACH (bGPdata *, legacy_gpd, &bmain.gpencils) { + GreasePencil *new_grease_pencil = legacy_to_greasepencil_data.lookup_default(legacy_gpd, + nullptr); + if (!new_grease_pencil) { + new_grease_pencil = static_cast( + BKE_id_new_in_lib(&bmain, legacy_gpd->id.lib, ID_GP, legacy_gpd->id.name + 2)); + id_us_min(&new_grease_pencil->id); + legacy_gpencil_to_grease_pencil(bmain, *new_grease_pencil, *legacy_gpd); + legacy_to_greasepencil_data.add(legacy_gpd, new_grease_pencil); + } + gpd_remapper.add(&legacy_gpd->id, &new_grease_pencil->id); + } + + BKE_libblock_remap_multiple(&bmain, gpd_remapper, ID_REMAP_ALLOW_IDTYPE_MISMATCH); +} + void lineart_wrap_v3(const LineartGpencilModifierData *lmd_legacy, GreasePencilLineartModifierData *lmd) { diff --git a/source/blender/blenloader/intern/versioning_common.cc b/source/blender/blenloader/intern/versioning_common.cc index 89164a66761..f32ddeb24a5 100644 --- a/source/blender/blenloader/intern/versioning_common.cc +++ b/source/blender/blenloader/intern/versioning_common.cc @@ -19,6 +19,7 @@ #include "BLI_string_ref.hh" #include "BKE_animsys.h" +#include "BKE_grease_pencil_legacy_convert.hh" #include "BKE_idprop.h" #include "BKE_ipo.h" #include "BKE_lib_id.hh" @@ -537,4 +538,10 @@ void do_versions_after_setup(Main *new_bmain, BlendFileReadReport *reports) * been made idempotent. */ BKE_main_mesh_legacy_convert_auto_smooth(*new_bmain); } + + if (U.experimental.use_grease_pencil_version3 && + U.experimental.use_grease_pencil_version3_convert_on_load) + { + blender::bke::greasepencil::convert::legacy_main(*new_bmain, *reports); + } } diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index f40444f8ff9..487a563ba09 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -722,8 +722,9 @@ typedef struct UserDef_Experimental { char use_shader_node_previews; char use_extension_repos; char use_extension_utils; + char use_grease_pencil_version3_convert_on_load; - char _pad[2]; + char _pad[1]; /** `makesdna` does not allow empty structs. */ } UserDef_Experimental; diff --git a/source/blender/makesrna/intern/rna_userdef.cc b/source/blender/makesrna/intern/rna_userdef.cc index 74405af6cbe..1e90f314401 100644 --- a/source/blender/makesrna/intern/rna_userdef.cc +++ b/source/blender/makesrna/intern/rna_userdef.cc @@ -7162,6 +7162,15 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_property_update(prop, 0, "rna_userdef_use_grease_pencil_version3_update"); + prop = RNA_def_property( + srna, "use_grease_pencil_version3_convert_on_load", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, nullptr, "use_grease_pencil_version3_convert_on_load", 1); + RNA_def_property_ui_text(prop, + "Grease Pencil 3.0 Automatic Conversion", + "Enable automatic conversion to grease pencil 3.0 data when opening a " + "blendfile (only active if 'Grease Pencil 3.0' is enabled)"); + RNA_def_property_update(prop, 0, "rna_userdef_ui_update"); + prop = RNA_def_property(srna, "use_new_matrix_socket", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "use_new_matrix_socket", 1); RNA_def_property_ui_text( -- 2.30.2