Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenloader/intern/readfile.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
| Show First 20 Lines • Show All 246 Lines • ▼ Show 20 Lines | |||||
| } OldNewMap; | } OldNewMap; | ||||
| /* local prototypes */ | /* local prototypes */ | ||||
| static void *read_struct(FileData *fd, BHead *bh, const char *blockname); | static void *read_struct(FileData *fd, BHead *bh, const char *blockname); | ||||
| static void direct_link_modifiers(FileData *fd, ListBase *lb); | static void direct_link_modifiers(FileData *fd, ListBase *lb); | ||||
| static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name); | static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name); | ||||
| static BHead *find_bhead_from_idname(FileData *fd, const char *idname); | static BHead *find_bhead_from_idname(FileData *fd, const char *idname); | ||||
| static SceneCollection *get_scene_collection_active_or_create(struct Scene *scene, struct SceneLayer *scene_layer, const short flag); | static SceneCollection *get_scene_collection_active_or_create(struct Scene *scene, struct ViewLayer *view_layer, const short flag); | ||||
| /* this function ensures that reports are printed, | /* this function ensures that reports are printed, | ||||
| * in the case of libraray linking errors this is important! | * in the case of libraray linking errors this is important! | ||||
| * | * | ||||
| * bit kludge but better then doubling up on prints, | * bit kludge but better then doubling up on prints, | ||||
| * we could alternatively have a versions of a report function which forces printing - campbell | * we could alternatively have a versions of a report function which forces printing - campbell | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 2,569 Lines • ▼ Show 20 Lines | static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main *main) | ||||
| { | { | ||||
| relation->parent = newglobadr(fd, relation->parent); /* data from window - need to access through global oldnew-map */ | relation->parent = newglobadr(fd, relation->parent); /* data from window - need to access through global oldnew-map */ | ||||
| relation->value = newdataadr(fd, relation->value); | relation->value = newdataadr(fd, relation->value); | ||||
| } | } | ||||
| if (ID_IS_LINKED(&workspace->id)) { | if (ID_IS_LINKED(&workspace->id)) { | ||||
| /* Appending workspace so render layer is likely from a different scene. Unset | /* Appending workspace so render layer is likely from a different scene. Unset | ||||
| * now, when activating workspace later we set a valid one from current scene. */ | * now, when activating workspace later we set a valid one from current scene. */ | ||||
| BKE_workspace_render_layer_set(workspace, NULL); | BKE_workspace_view_layer_set(workspace, NULL); | ||||
| } | } | ||||
| /* Same issue/fix as in direct_link_workspace_link_scene_data: Can't read workspace data | /* Same issue/fix as in direct_link_workspace_link_scene_data: Can't read workspace data | ||||
| * when reading windows, so have to update windows after/when reading workspaces. */ | * when reading windows, so have to update windows after/when reading workspaces. */ | ||||
| for (wmWindowManager *wm = main->wm.first; wm; wm = wm->id.next) { | for (wmWindowManager *wm = main->wm.first; wm; wm = wm->id.next) { | ||||
| for (wmWindow *win = wm->windows.first; win; win = win->next) { | for (wmWindow *win = wm->windows.first; win; win = win->next) { | ||||
| WorkSpaceLayout *act_layout = newdataadr(fd, BKE_workspace_active_layout_get(win->workspace_hook)); | WorkSpaceLayout *act_layout = newdataadr(fd, BKE_workspace_active_layout_get(win->workspace_hook)); | ||||
| if (act_layout) { | if (act_layout) { | ||||
| ▲ Show 20 Lines • Show All 3,077 Lines • ▼ Show 20 Lines | if (sce->id.tag & LIB_TAG_NEED_LINK) { | ||||
| /*Game Settings: Dome Warp Text*/ | /*Game Settings: Dome Warp Text*/ | ||||
| sce->gm.dome.warptext = newlibadr(fd, sce->id.lib, sce->gm.dome.warptext); | sce->gm.dome.warptext = newlibadr(fd, sce->id.lib, sce->gm.dome.warptext); | ||||
| /* Motion Tracking */ | /* Motion Tracking */ | ||||
| sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip); | sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip); | ||||
| lib_link_scene_collection(fd, sce->id.lib, sce->collection); | lib_link_scene_collection(fd, sce->id.lib, sce->collection); | ||||
| for (SceneLayer *scene_layer = sce->render_layers.first; scene_layer; scene_layer = scene_layer->next) { | for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) { | ||||
| /* tag scene layer to update for collection tree evaluation */ | /* tag scene layer to update for collection tree evaluation */ | ||||
| scene_layer->flag |= SCENE_LAYER_ENGINE_DIRTY; | view_layer->flag |= VIEW_LAYER_ENGINE_DIRTY; | ||||
| for (FreestyleModuleConfig *fmc = scene_layer->freestyle_config.modules.first; fmc; fmc = fmc->next) { | for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc; fmc = fmc->next) { | ||||
| fmc->script = newlibadr(fd, sce->id.lib, fmc->script); | fmc->script = newlibadr(fd, sce->id.lib, fmc->script); | ||||
| } | } | ||||
| for (FreestyleLineSet *fls = scene_layer->freestyle_config.linesets.first; fls; fls = fls->next) { | for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) { | ||||
| fls->linestyle = newlibadr_us(fd, sce->id.lib, fls->linestyle); | fls->linestyle = newlibadr_us(fd, sce->id.lib, fls->linestyle); | ||||
| fls->group = newlibadr_us(fd, sce->id.lib, fls->group); | fls->group = newlibadr_us(fd, sce->id.lib, fls->group); | ||||
| } | } | ||||
| for (Base *base = scene_layer->object_bases.first; base; base = base->next) { | for (Base *base = view_layer->object_bases.first; base; base = base->next) { | ||||
| /* we only bump the use count for the collection objects */ | /* we only bump the use count for the collection objects */ | ||||
| base->object = newlibadr(fd, sce->id.lib, base->object); | base->object = newlibadr(fd, sce->id.lib, base->object); | ||||
| base->flag |= BASE_DIRTY_ENGINE_SETTINGS; | base->flag |= BASE_DIRTY_ENGINE_SETTINGS; | ||||
| base->collection_properties = NULL; | base->collection_properties = NULL; | ||||
| } | } | ||||
| } | } | ||||
| #ifdef USE_SETSCENE_CHECK | #ifdef USE_SETSCENE_CHECK | ||||
| ▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | |||||
| /** | /** | ||||
| * Workspaces store a render layer pointer which can only be read after scene is read. | * Workspaces store a render layer pointer which can only be read after scene is read. | ||||
| */ | */ | ||||
| static void direct_link_workspace_link_scene_data( | static void direct_link_workspace_link_scene_data( | ||||
| FileData *fd, const Scene *scene, const ListBase *workspaces) | FileData *fd, const Scene *scene, const ListBase *workspaces) | ||||
| { | { | ||||
| for (WorkSpace *workspace = workspaces->first; workspace; workspace = workspace->id.next) { | for (WorkSpace *workspace = workspaces->first; workspace; workspace = workspace->id.next) { | ||||
| SceneLayer *layer = newdataadr(fd, BKE_workspace_render_layer_get(workspace)); | ViewLayer *layer = newdataadr(fd, BKE_workspace_view_layer_get(workspace)); | ||||
| /* only set when layer is from the scene we read */ | /* only set when layer is from the scene we read */ | ||||
| if (layer && (BLI_findindex(&scene->render_layers, layer) != -1)) { | if (layer && (BLI_findindex(&scene->view_layers, layer) != -1)) { | ||||
| BKE_workspace_render_layer_set(workspace, layer); | BKE_workspace_view_layer_set(workspace, layer); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain) | static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain) | ||||
| { | { | ||||
| Editing *ed; | Editing *ed; | ||||
| Sequence *seq; | Sequence *seq; | ||||
| MetaStack *ms; | MetaStack *ms; | ||||
| RigidBodyWorld *rbw; | RigidBodyWorld *rbw; | ||||
| SceneLayer *scene_layer; | ViewLayer *view_layer; | ||||
| SceneRenderLayer *srl; | SceneRenderLayer *srl; | ||||
| sce->depsgraph_hash = NULL; | sce->depsgraph_hash = NULL; | ||||
| sce->obedit = NULL; | sce->obedit = NULL; | ||||
| sce->fps_info = NULL; | sce->fps_info = NULL; | ||||
| sce->customdata_mask_modal = 0; | sce->customdata_mask_modal = 0; | ||||
| sce->lay_updated = 0; | sce->lay_updated = 0; | ||||
| Show All 19 Lines | if (sce->toolsettings) { | ||||
| direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->wpaint); | direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->wpaint); | ||||
| direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->uvsculpt); | direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->uvsculpt); | ||||
| direct_link_paint(fd, &sce->toolsettings->imapaint.paint); | direct_link_paint(fd, &sce->toolsettings->imapaint.paint); | ||||
| sce->toolsettings->imapaint.paintcursor = NULL; | sce->toolsettings->imapaint.paintcursor = NULL; | ||||
| sce->toolsettings->particle.paintcursor = NULL; | sce->toolsettings->particle.paintcursor = NULL; | ||||
| sce->toolsettings->particle.scene = NULL; | sce->toolsettings->particle.scene = NULL; | ||||
| sce->toolsettings->particle.scene_layer = NULL; | sce->toolsettings->particle.view_layer = NULL; | ||||
| sce->toolsettings->particle.object = NULL; | sce->toolsettings->particle.object = NULL; | ||||
| sce->toolsettings->gp_sculpt.paintcursor = NULL; | sce->toolsettings->gp_sculpt.paintcursor = NULL; | ||||
| /* relink grease pencil drawing brushes */ | /* relink grease pencil drawing brushes */ | ||||
| link_list(fd, &sce->toolsettings->gp_brushes); | link_list(fd, &sce->toolsettings->gp_brushes); | ||||
| for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) { | for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) { | ||||
| brush->cur_sensitivity = newdataadr(fd, brush->cur_sensitivity); | brush->cur_sensitivity = newdataadr(fd, brush->cur_sensitivity); | ||||
| if (brush->cur_sensitivity) { | if (brush->cur_sensitivity) { | ||||
| ▲ Show 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain) | ||||
| /* this runs before the very first doversion */ | /* this runs before the very first doversion */ | ||||
| if (sce->collection) { | if (sce->collection) { | ||||
| sce->collection = newdataadr(fd, sce->collection); | sce->collection = newdataadr(fd, sce->collection); | ||||
| direct_link_scene_collection(fd, sce->collection); | direct_link_scene_collection(fd, sce->collection); | ||||
| } | } | ||||
| /* insert into global old-new map for reading without UI (link_global accesses it again) */ | /* insert into global old-new map for reading without UI (link_global accesses it again) */ | ||||
| link_glob_list(fd, &sce->render_layers); | link_glob_list(fd, &sce->view_layers); | ||||
| for (scene_layer = sce->render_layers.first; scene_layer; scene_layer = scene_layer->next) { | for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) { | ||||
| scene_layer->stats = NULL; | view_layer->stats = NULL; | ||||
| link_list(fd, &scene_layer->object_bases); | link_list(fd, &view_layer->object_bases); | ||||
| scene_layer->basact = newdataadr(fd, scene_layer->basact); | view_layer->basact = newdataadr(fd, view_layer->basact); | ||||
| direct_link_layer_collections(fd, &scene_layer->layer_collections); | direct_link_layer_collections(fd, &view_layer->layer_collections); | ||||
| if (scene_layer->properties != NULL) { | if (view_layer->properties != NULL) { | ||||
| scene_layer->properties = newdataadr(fd, scene_layer->properties); | view_layer->properties = newdataadr(fd, view_layer->properties); | ||||
| BLI_assert(scene_layer->properties != NULL); | BLI_assert(view_layer->properties != NULL); | ||||
| IDP_DirectLinkGroup_OrFree(&scene_layer->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); | IDP_DirectLinkGroup_OrFree(&view_layer->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); | ||||
| BKE_scene_layer_engine_settings_validate_layer(scene_layer); | BKE_view_layer_engine_settings_validate_layer(view_layer); | ||||
| } | } | ||||
| scene_layer->id_properties = newdataadr(fd, scene_layer->id_properties); | view_layer->id_properties = newdataadr(fd, view_layer->id_properties); | ||||
| IDP_DirectLinkGroup_OrFree(&scene_layer->id_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); | IDP_DirectLinkGroup_OrFree(&view_layer->id_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); | ||||
| link_list(fd, &(scene_layer->freestyle_config.modules)); | link_list(fd, &(view_layer->freestyle_config.modules)); | ||||
| link_list(fd, &(scene_layer->freestyle_config.linesets)); | link_list(fd, &(view_layer->freestyle_config.linesets)); | ||||
| scene_layer->properties_evaluated = NULL; | view_layer->properties_evaluated = NULL; | ||||
| BLI_listbase_clear(&scene_layer->drawdata); | BLI_listbase_clear(&view_layer->drawdata); | ||||
| } | } | ||||
| sce->collection_properties = newdataadr(fd, sce->collection_properties); | sce->collection_properties = newdataadr(fd, sce->collection_properties); | ||||
| IDP_DirectLinkGroup_OrFree(&sce->collection_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); | IDP_DirectLinkGroup_OrFree(&sce->collection_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); | ||||
| sce->layer_properties = newdataadr(fd, sce->layer_properties); | sce->layer_properties = newdataadr(fd, sce->layer_properties); | ||||
| IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); | IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); | ||||
| BKE_layer_collection_engine_settings_validate_scene(sce); | BKE_layer_collection_engine_settings_validate_scene(sce); | ||||
| BKE_scene_layer_engine_settings_validate_scene(sce); | BKE_view_layer_engine_settings_validate_scene(sce); | ||||
| direct_link_workspace_link_scene_data(fd, sce, &bmain->workspaces); | direct_link_workspace_link_scene_data(fd, sce, &bmain->workspaces); | ||||
| } | } | ||||
| /* ************ READ WM ***************** */ | /* ************ READ WM ***************** */ | ||||
| static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) | static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 717 Lines • ▼ Show 20 Lines | #endif | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Used to link a file (without UI) to the current UI. | * Used to link a file (without UI) to the current UI. | ||||
| * Note that it assumes the old pointers in UI are still valid, so old Main is not freed. | * Note that it assumes the old pointers in UI are still valid, so old Main is not freed. | ||||
| */ | */ | ||||
| void blo_lib_link_restore(Main *newmain, wmWindowManager *curwm, Scene *curscene, SceneLayer *cur_render_layer) | void blo_lib_link_restore(Main *newmain, wmWindowManager *curwm, Scene *curscene, ViewLayer *cur_render_layer) | ||||
| { | { | ||||
| struct IDNameLib_Map *id_map = BKE_main_idmap_create(newmain); | struct IDNameLib_Map *id_map = BKE_main_idmap_create(newmain); | ||||
| for (WorkSpace *workspace = newmain->workspaces.first; workspace; workspace = workspace->id.next) { | for (WorkSpace *workspace = newmain->workspaces.first; workspace; workspace = workspace->id.next) { | ||||
| ListBase *layouts = BKE_workspace_layouts_get(workspace); | ListBase *layouts = BKE_workspace_layouts_get(workspace); | ||||
| for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) { | for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) { | ||||
| lib_link_workspace_layout_restore(id_map, newmain, layout); | lib_link_workspace_layout_restore(id_map, newmain, layout); | ||||
| } | } | ||||
| BKE_workspace_render_layer_set(workspace, cur_render_layer); | BKE_workspace_view_layer_set(workspace, cur_render_layer); | ||||
| } | } | ||||
| for (wmWindow *win = curwm->windows.first; win; win = win->next) { | for (wmWindow *win = curwm->windows.first; win; win = win->next) { | ||||
| WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); | WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); | ||||
| ID *workspace_id = (ID *)workspace; | ID *workspace_id = (ID *)workspace; | ||||
| Scene *oldscene = win->scene; | Scene *oldscene = win->scene; | ||||
| workspace = restore_pointer_by_name(id_map, workspace_id, USER_REAL); | workspace = restore_pointer_by_name(id_map, workspace_id, USER_REAL); | ||||
| ▲ Show 20 Lines • Show All 1,433 Lines • ▼ Show 20 Lines | if (fd->fileversion <= 250) | ||||
| BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->filename)); | BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->filename)); | ||||
| } | } | ||||
| if (G.fileflags & G_FILE_RECOVER) | if (G.fileflags & G_FILE_RECOVER) | ||||
| BLI_strncpy(fd->relabase, fg->filename, sizeof(fd->relabase)); | BLI_strncpy(fd->relabase, fg->filename, sizeof(fd->relabase)); | ||||
| bfd->curscreen = fg->curscreen; | bfd->curscreen = fg->curscreen; | ||||
| bfd->curscene = fg->curscene; | bfd->curscene = fg->curscene; | ||||
| bfd->cur_render_layer = fg->cur_render_layer; | bfd->cur_render_layer = fg->cur_view_layer; | ||||
| MEM_freeN(fg); | MEM_freeN(fg); | ||||
| fd->globalf = bfd->globalf; | fd->globalf = bfd->globalf; | ||||
| fd->fileflags = bfd->fileflags; | fd->fileflags = bfd->fileflags; | ||||
| return blo_nextbhead(fd, bhead); | return blo_nextbhead(fd, bhead); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,219 Lines • ▼ Show 20 Lines | for (srl = sce->r.layers.first; srl; srl = srl->next) { | ||||
| } | } | ||||
| for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { | for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { | ||||
| if (lineset->group) | if (lineset->group) | ||||
| expand_doit(fd, mainvar, lineset->group); | expand_doit(fd, mainvar, lineset->group); | ||||
| expand_doit(fd, mainvar, lineset->linestyle); | expand_doit(fd, mainvar, lineset->linestyle); | ||||
| } | } | ||||
| } | } | ||||
| for (SceneLayer *scene_layer = sce->render_layers.first; scene_layer; scene_layer = scene_layer->next) { | for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) { | ||||
| for (module = scene_layer->freestyle_config.modules.first; module; module = module->next) { | for (module = view_layer->freestyle_config.modules.first; module; module = module->next) { | ||||
| if (module->script) { | if (module->script) { | ||||
| expand_doit(fd, mainvar, module->script); | expand_doit(fd, mainvar, module->script); | ||||
| } | } | ||||
| } | } | ||||
| for (lineset = scene_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) { | for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) { | ||||
| if (lineset->group) { | if (lineset->group) { | ||||
| expand_doit(fd, mainvar, lineset->group); | expand_doit(fd, mainvar, lineset->group); | ||||
| } | } | ||||
| expand_doit(fd, mainvar, lineset->linestyle); | expand_doit(fd, mainvar, lineset->linestyle); | ||||
| } | } | ||||
| } | } | ||||
| if (sce->r.dometext) | if (sce->r.dometext) | ||||
| ▲ Show 20 Lines • Show All 295 Lines • ▼ Show 20 Lines | if (BKE_scene_object_find(sce, ob)) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static void give_base_to_objects( | static void give_base_to_objects( | ||||
| Main *mainvar, Scene *scene, SceneLayer *scene_layer, Library *lib, const short flag) | Main *mainvar, Scene *scene, ViewLayer *view_layer, Library *lib, const short flag) | ||||
| { | { | ||||
| Object *ob; | Object *ob; | ||||
| Base *base; | Base *base; | ||||
| SceneCollection *scene_collection = NULL; | SceneCollection *scene_collection = NULL; | ||||
| const bool is_link = (flag & FILE_LINK) != 0; | const bool is_link = (flag & FILE_LINK) != 0; | ||||
| BLI_assert(scene); | BLI_assert(scene); | ||||
| Show All 10 Lines | if ((ob->id.tag & LIB_TAG_INDIRECT) && (ob->id.tag & LIB_TAG_PRE_EXISTING) == 0) { | ||||
| * (see T27437). */ | * (see T27437). */ | ||||
| do_it = true; | do_it = true; | ||||
| } | } | ||||
| if (do_it) { | if (do_it) { | ||||
| CLAMP_MIN(ob->id.us, 0); | CLAMP_MIN(ob->id.us, 0); | ||||
| if (scene_collection == NULL) { | if (scene_collection == NULL) { | ||||
| scene_collection = get_scene_collection_active_or_create(scene, scene_layer, FILE_ACTIVE_COLLECTION); | scene_collection = get_scene_collection_active_or_create(scene, view_layer, FILE_ACTIVE_COLLECTION); | ||||
| } | } | ||||
| BKE_collection_object_add(scene, scene_collection, ob); | BKE_collection_object_add(scene, scene_collection, ob); | ||||
| base = BKE_scene_layer_base_find(scene_layer, ob); | base = BKE_view_layer_base_find(view_layer, ob); | ||||
| BKE_scene_object_base_flag_sync_from_base(base); | BKE_scene_object_base_flag_sync_from_base(base); | ||||
| if (flag & FILE_AUTOSELECT) { | if (flag & FILE_AUTOSELECT) { | ||||
| /* Note that link_object_postprocess() already checks for FILE_AUTOSELECT flag, | /* Note that link_object_postprocess() already checks for FILE_AUTOSELECT flag, | ||||
| * but it will miss objects from non-instanciated groups... */ | * but it will miss objects from non-instanciated groups... */ | ||||
| if (base->flag & BASE_SELECTABLED) { | if (base->flag & BASE_SELECTABLED) { | ||||
| base->flag |= BASE_SELECTED; | base->flag |= BASE_SELECTED; | ||||
| BKE_scene_object_base_flag_sync_from_base(base); | BKE_scene_object_base_flag_sync_from_base(base); | ||||
| } | } | ||||
| /* Do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level. */ | /* Do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level. */ | ||||
| } | } | ||||
| ob->id.tag &= ~LIB_TAG_INDIRECT; | ob->id.tag &= ~LIB_TAG_INDIRECT; | ||||
| ob->id.tag |= LIB_TAG_EXTERN; | ob->id.tag |= LIB_TAG_EXTERN; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void give_base_to_groups( | static void give_base_to_groups( | ||||
| Main *mainvar, Scene *scene, SceneLayer *scene_layer, Library *UNUSED(lib), const short UNUSED(flag)) | Main *mainvar, Scene *scene, ViewLayer *view_layer, Library *UNUSED(lib), const short UNUSED(flag)) | ||||
| { | { | ||||
| Group *group; | Group *group; | ||||
| Base *base; | Base *base; | ||||
| Object *ob; | Object *ob; | ||||
| SceneCollection *scene_collection; | SceneCollection *scene_collection; | ||||
| /* If the group is empty this function is not even called, so it's safe to ensure a collection at this point. */ | /* If the group is empty this function is not even called, so it's safe to ensure a collection at this point. */ | ||||
| scene_collection = get_scene_collection_active_or_create(scene, scene_layer, FILE_ACTIVE_COLLECTION); | scene_collection = get_scene_collection_active_or_create(scene, view_layer, FILE_ACTIVE_COLLECTION); | ||||
| /* Give all objects which are tagged a base. */ | /* Give all objects which are tagged a base. */ | ||||
| for (group = mainvar->group.first; group; group = group->id.next) { | for (group = mainvar->group.first; group; group = group->id.next) { | ||||
| if (group->id.tag & LIB_TAG_DOIT) { | if (group->id.tag & LIB_TAG_DOIT) { | ||||
| /* Any indirect group should not have been tagged. */ | /* Any indirect group should not have been tagged. */ | ||||
| BLI_assert((group->id.tag & LIB_TAG_INDIRECT) == 0); | BLI_assert((group->id.tag & LIB_TAG_INDIRECT) == 0); | ||||
| /* BKE_object_add(...) messes with the selection. */ | /* BKE_object_add(...) messes with the selection. */ | ||||
| ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name + 2); | ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name + 2); | ||||
| ob->type = OB_EMPTY; | ob->type = OB_EMPTY; | ||||
| BKE_collection_object_add(scene, scene_collection, ob); | BKE_collection_object_add(scene, scene_collection, ob); | ||||
| base = BKE_scene_layer_base_find(scene_layer, ob); | base = BKE_view_layer_base_find(view_layer, ob); | ||||
| if (base->flag & BASE_SELECTABLED) { | if (base->flag & BASE_SELECTABLED) { | ||||
| base->flag |= BASE_SELECTED; | base->flag |= BASE_SELECTED; | ||||
| } | } | ||||
| BKE_scene_object_base_flag_sync_from_base(base); | BKE_scene_object_base_flag_sync_from_base(base); | ||||
| DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); | DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); | ||||
| scene_layer->basact = base; | view_layer->basact = base; | ||||
| /* Assign the group. */ | /* Assign the group. */ | ||||
| ob->dup_group = group; | ob->dup_group = group; | ||||
| ob->transflag |= OB_DUPLIGROUP; | ob->transflag |= OB_DUPLIGROUP; | ||||
| copy_v3_v3(ob->loc, scene->cursor); | copy_v3_v3(ob->loc, scene->cursor); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | static ID *link_named_part( | ||||
| } | } | ||||
| /* if we found the id but the id is NULL, this is really bad */ | /* if we found the id but the id is NULL, this is really bad */ | ||||
| BLI_assert(!((bhead != NULL) && (id == NULL))); | BLI_assert(!((bhead != NULL) && (id == NULL))); | ||||
| return id; | return id; | ||||
| } | } | ||||
| static SceneCollection *get_scene_collection_active_or_create(struct Scene *scene, struct SceneLayer *scene_layer, const short flag) | static SceneCollection *get_scene_collection_active_or_create(struct Scene *scene, struct ViewLayer *view_layer, const short flag) | ||||
| { | { | ||||
| LayerCollection *lc = NULL; | LayerCollection *lc = NULL; | ||||
| if (flag & FILE_ACTIVE_COLLECTION) { | if (flag & FILE_ACTIVE_COLLECTION) { | ||||
| lc = BKE_layer_collection_get_active_ensure(scene, scene_layer); | lc = BKE_layer_collection_get_active_ensure(scene, view_layer); | ||||
| } | } | ||||
| else { | else { | ||||
| SceneCollection *sc = BKE_collection_add(scene, NULL, NULL); | SceneCollection *sc = BKE_collection_add(scene, NULL, NULL); | ||||
| lc = BKE_collection_link(scene_layer, sc); | lc = BKE_collection_link(view_layer, sc); | ||||
| } | } | ||||
| return lc->scene_collection; | return lc->scene_collection; | ||||
| } | } | ||||
| static void link_object_postprocess(ID *id, Scene *scene, SceneLayer *scene_layer, const short flag) | static void link_object_postprocess(ID *id, Scene *scene, ViewLayer *view_layer, const short flag) | ||||
| { | { | ||||
| if (scene) { | if (scene) { | ||||
| /* link to scene */ | /* link to scene */ | ||||
| Base *base; | Base *base; | ||||
| Object *ob; | Object *ob; | ||||
| SceneCollection *sc; | SceneCollection *sc; | ||||
| ob = (Object *)id; | ob = (Object *)id; | ||||
| ob->mode = OB_MODE_OBJECT; | ob->mode = OB_MODE_OBJECT; | ||||
| sc = get_scene_collection_active_or_create(scene, scene_layer, flag); | sc = get_scene_collection_active_or_create(scene, view_layer, flag); | ||||
| BKE_collection_object_add(scene, sc, ob); | BKE_collection_object_add(scene, sc, ob); | ||||
| base = BKE_scene_layer_base_find(scene_layer, ob); | base = BKE_view_layer_base_find(view_layer, ob); | ||||
| BKE_scene_object_base_flag_sync_from_base(base); | BKE_scene_object_base_flag_sync_from_base(base); | ||||
| if (flag & FILE_AUTOSELECT) { | if (flag & FILE_AUTOSELECT) { | ||||
| if (base->flag & BASE_SELECTABLED) { | if (base->flag & BASE_SELECTABLED) { | ||||
| base->flag |= BASE_SELECTED; | base->flag |= BASE_SELECTED; | ||||
| BKE_scene_object_base_flag_sync_from_base(base); | BKE_scene_object_base_flag_sync_from_base(base); | ||||
| } | } | ||||
| /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */ | /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */ | ||||
| Show All 33 Lines | if (id) { | ||||
| BLI_assert(id->us == 0); | BLI_assert(id->us == 0); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static ID *link_named_part_ex( | static ID *link_named_part_ex( | ||||
| Main *mainl, FileData *fd, const short idcode, const char *name, const short flag, | Main *mainl, FileData *fd, const short idcode, const char *name, const short flag, | ||||
| Scene *scene, SceneLayer *scene_layer, const bool use_placeholders, const bool force_indirect) | Scene *scene, ViewLayer *view_layer, const bool use_placeholders, const bool force_indirect) | ||||
| { | { | ||||
| ID *id = link_named_part(mainl, fd, idcode, name, use_placeholders, force_indirect); | ID *id = link_named_part(mainl, fd, idcode, name, use_placeholders, force_indirect); | ||||
| if (id && (GS(id->name) == ID_OB)) { /* loose object: give a base */ | if (id && (GS(id->name) == ID_OB)) { /* loose object: give a base */ | ||||
| link_object_postprocess(id, scene, scene_layer, flag); | link_object_postprocess(id, scene, view_layer, flag); | ||||
| } | } | ||||
| else if (id && (GS(id->name) == ID_GR)) { | else if (id && (GS(id->name) == ID_GR)) { | ||||
| /* tag as needing to be instantiated */ | /* tag as needing to be instantiated */ | ||||
| if (flag & FILE_GROUP_INSTANCE) | if (flag & FILE_GROUP_INSTANCE) | ||||
| id->tag |= LIB_TAG_DOIT; | id->tag |= LIB_TAG_DOIT; | ||||
| } | } | ||||
| return id; | return id; | ||||
| Show All 27 Lines | |||||
| * \param v3d The active View3D (only to define active layers for instantiated objects & groups, can be NULL). | * \param v3d The active View3D (only to define active layers for instantiated objects & groups, can be NULL). | ||||
| * \param use_placeholders If true, generate a placeholder (empty ID) if not found in current lib file. | * \param use_placeholders If true, generate a placeholder (empty ID) if not found in current lib file. | ||||
| * \param force_indirect If true, force loaded ID to be tagged as LIB_TAG_INDIRECT (used in reload context only). | * \param force_indirect If true, force loaded ID to be tagged as LIB_TAG_INDIRECT (used in reload context only). | ||||
| * \return the linked ID when found. | * \return the linked ID when found. | ||||
| */ | */ | ||||
| ID *BLO_library_link_named_part_ex( | ID *BLO_library_link_named_part_ex( | ||||
| Main *mainl, BlendHandle **bh, | Main *mainl, BlendHandle **bh, | ||||
| const short idcode, const char *name, const short flag, | const short idcode, const char *name, const short flag, | ||||
| Scene *scene, SceneLayer *scene_layer, | Scene *scene, ViewLayer *view_layer, | ||||
| const bool use_placeholders, const bool force_indirect) | const bool use_placeholders, const bool force_indirect) | ||||
| { | { | ||||
| FileData *fd = (FileData*)(*bh); | FileData *fd = (FileData*)(*bh); | ||||
| return link_named_part_ex(mainl, fd, idcode, name, flag, scene, scene_layer, use_placeholders, force_indirect); | return link_named_part_ex(mainl, fd, idcode, name, flag, scene, view_layer, use_placeholders, force_indirect); | ||||
| } | } | ||||
| static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id) | static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id) | ||||
| { | { | ||||
| BHead *bhead = NULL; | BHead *bhead = NULL; | ||||
| const bool is_valid = BKE_idcode_is_linkable(GS(id->name)) || ((id->tag & LIB_TAG_EXTERN) == 0); | const bool is_valid = BKE_idcode_is_linkable(GS(id->name)) || ((id->tag & LIB_TAG_EXTERN) == 0); | ||||
| if (fd) { | if (fd) { | ||||
| ▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | for (ID *id = lbarray[i]->first, *idnext; id; id = idnext) { | ||||
| BLI_remlink(lbarray[i], id); | BLI_remlink(lbarray[i], id); | ||||
| BLI_addtail(lbarray_newid[i], id); | BLI_addtail(lbarray_newid[i], id); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* scene and v3d may be NULL. */ | /* scene and v3d may be NULL. */ | ||||
| static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene *scene, SceneLayer *scene_layer) | static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene *scene, ViewLayer *view_layer) | ||||
| { | { | ||||
| Main *mainvar; | Main *mainvar; | ||||
| Library *curlib; | Library *curlib; | ||||
| /* expander now is callback function */ | /* expander now is callback function */ | ||||
| BLO_main_expander(expand_doit_library); | BLO_main_expander(expand_doit_library); | ||||
| /* make main consistent */ | /* make main consistent */ | ||||
| Show All 39 Lines | static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene *scene, ViewLayer *view_layer) | ||||
| lib_verify_nodetree(mainvar, false); | lib_verify_nodetree(mainvar, false); | ||||
| fix_relpaths_library(G.main->name, mainvar); /* make all relative paths, relative to the open blend file */ | fix_relpaths_library(G.main->name, mainvar); /* make all relative paths, relative to the open blend file */ | ||||
| /* Give a base to loose objects. If group append, do it for objects too. | /* Give a base to loose objects. If group append, do it for objects too. | ||||
| * Only directly linked objects & groups are instantiated by `BLO_library_link_named_part_ex()` & co, | * Only directly linked objects & groups are instantiated by `BLO_library_link_named_part_ex()` & co, | ||||
| * here we handle indirect ones and other possible edge-cases. */ | * here we handle indirect ones and other possible edge-cases. */ | ||||
| if (scene) { | if (scene) { | ||||
| give_base_to_objects(mainvar, scene, scene_layer, curlib, flag); | give_base_to_objects(mainvar, scene, view_layer, curlib, flag); | ||||
| if (flag & FILE_GROUP_INSTANCE) { | if (flag & FILE_GROUP_INSTANCE) { | ||||
| give_base_to_groups(mainvar, scene, scene_layer, curlib, flag); | give_base_to_groups(mainvar, scene, view_layer, curlib, flag); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* printf("library_append_end, scene is NULL (objects wont get bases)\n"); */ | /* printf("library_append_end, scene is NULL (objects wont get bases)\n"); */ | ||||
| } | } | ||||
| /* clear group instantiating tag */ | /* clear group instantiating tag */ | ||||
| BKE_main_id_tag_listbase(&(mainvar->group), LIB_TAG_DOIT, false); | BKE_main_id_tag_listbase(&(mainvar->group), LIB_TAG_DOIT, false); | ||||
| Show All 9 Lines | |||||
| * Finalize linking from a given .blend file (library). | * Finalize linking from a given .blend file (library). | ||||
| * Optionally instance the indirect object/group in the scene when the flags are set. | * Optionally instance the indirect object/group in the scene when the flags are set. | ||||
| * \note Do not use \a bh after calling this function, it may frees it. | * \note Do not use \a bh after calling this function, it may frees it. | ||||
| * | * | ||||
| * \param mainl The main database to link from (not the active one). | * \param mainl The main database to link from (not the active one). | ||||
| * \param bh The blender file handle (WARNING! may be freed by this function!). | * \param bh The blender file handle (WARNING! may be freed by this function!). | ||||
| * \param flag Options for linking, used for instantiating. | * \param flag Options for linking, used for instantiating. | ||||
| * \param scene The scene in which to instantiate objects/groups (if NULL, no instantiation is done). | * \param scene The scene in which to instantiate objects/groups (if NULL, no instantiation is done). | ||||
| * \param scene_layer The scene layer in which to instantiate objects/groups (if NULL, no instantiation is done). | * \param view_layer The scene layer in which to instantiate objects/groups (if NULL, no instantiation is done). | ||||
| */ | */ | ||||
| void BLO_library_link_end(Main *mainl, BlendHandle **bh, short flag, Scene *scene, SceneLayer *scene_layer) | void BLO_library_link_end(Main *mainl, BlendHandle **bh, short flag, Scene *scene, ViewLayer *view_layer) | ||||
| { | { | ||||
| FileData *fd = (FileData*)(*bh); | FileData *fd = (FileData*)(*bh); | ||||
| library_link_end(mainl, &fd, flag, scene, scene_layer); | library_link_end(mainl, &fd, flag, scene, view_layer); | ||||
| *bh = (BlendHandle*)fd; | *bh = (BlendHandle*)fd; | ||||
| } | } | ||||
| void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname) | void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname) | ||||
| { | { | ||||
| return read_struct(fd, bh, blockname); | return read_struct(fd, bh, blockname); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 239 Lines • Show Last 20 Lines | |||||