bool KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options) { BlendHandle *bpy_openlib = BLO_blendhandle_from_file((char *)path, NULL); // Error checking is done in LinkBlendFile return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str, options); }
static PyObject *bpy_lib_enter(BPy_Library *self) { PyObject *ret; BPy_Library *self_from; PyObject *from_dict = _PyDict_NewPresized(MAX_LIBARRAY); ReportList reports; BKE_reports_init(&reports, RPT_STORE); self->blo_handle = BLO_blendhandle_from_file(self->abspath, &reports); if (self->blo_handle == NULL) { if (BPy_reports_to_error(&reports, PyExc_IOError, true) != -1) { PyErr_Format(PyExc_IOError, "load: %s failed to open blend file", self->abspath); } return NULL; } else { int i = 0, code; while ((code = BKE_idcode_iter_step(&i))) { if (BKE_idcode_is_linkable(code)) { const char *name_plural = BKE_idcode_to_name_plural(code); PyObject *str = PyUnicode_FromString(name_plural); PyObject *item; PyDict_SetItem(self->dict, str, item = PyList_New(0)); Py_DECREF(item); PyDict_SetItem(from_dict, str, item = _bpy_names(self, code)); Py_DECREF(item); Py_DECREF(str); } } } /* create a dummy */ self_from = PyObject_New(BPy_Library, &bpy_lib_Type); BLI_strncpy(self_from->relpath, self->relpath, sizeof(self_from->relpath)); BLI_strncpy(self_from->abspath, self->abspath, sizeof(self_from->abspath)); self_from->blo_handle = NULL; self_from->flag = 0; self_from->dict = from_dict; /* owns the dict */ /* return pair */ ret = PyTuple_New(2); PyTuple_SET_ITEMS(ret, (PyObject *)self_from, (PyObject *)self); Py_INCREF(self); BKE_reports_clear(&reports); return ret; }
/* return success (1) */ int BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, ReportList *reports) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); Main *mainl = NULL; Library *lib; BlendHandle *bh; bh = BLO_blendhandle_from_file(libname, reports); if (bh == NULL) { /* error reports will have been made by BLO_blendhandle_from_file() */ return 0; } BKE_scene_base_deselect_all(scene); /* tag everything, all untagged data can be made local * its also generally useful to know what is new * * take extra care BKE_main_id_flag_all(bmain, LIB_TAG_PRE_EXISTING, false) is called after! */ BKE_main_id_flag_all(bmain, LIB_TAG_PRE_EXISTING, true); /* here appending/linking starts */ mainl = BLO_library_link_begin(bmain, &bh, libname); BLO_library_link_all(mainl, bh, flag, scene, v3d); BLO_library_link_end(mainl, &bh, flag, scene, v3d); /* mark all library linked objects to be updated */ BKE_main_lib_objects_recalc_all(bmain); IMB_colormanagement_check_file_config(bmain); /* append, rather than linking */ lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath)); BKE_library_make_local(bmain, lib, true, false); /* important we unset, otherwise these object wont * link into other scenes from this blend file */ BKE_main_id_flag_all(bmain, LIB_TAG_PRE_EXISTING, false); /* recreate dependency graph to include new objects */ DAG_relations_tag_update(bmain); BLO_blendhandle_close(bh); /* remove library... */ return 1; }
bool BKE_copybuffer_read(Main *bmain_dst, const char *libname, ReportList *reports) { BlendHandle *bh = BLO_blendhandle_from_file(libname, reports); if (bh == NULL) { /* Error reports will have been made by BLO_blendhandle_from_file(). */ return false; } /* Here appending/linking starts. */ Main *mainl = BLO_library_link_begin(bmain_dst, &bh, libname); BLO_library_link_copypaste(mainl, bh); BLO_library_link_end(mainl, &bh, 0, NULL, NULL); /* Mark all library linked objects to be updated. */ BKE_main_lib_objects_recalc_all(bmain_dst); IMB_colormanagement_check_file_config(bmain_dst); /* Append, rather than linking. */ Library *lib = BLI_findstring(&bmain_dst->library, libname, offsetof(Library, filepath)); BKE_library_make_local(bmain_dst, lib, true, false); /* Important we unset, otherwise these object wont * link into other scenes from this blend file. */ BKE_main_id_tag_all(bmain_dst, LIB_TAG_PRE_EXISTING, false); BLO_blendhandle_close(bh); return true; }
void filelist_from_library(struct FileList* filelist) { LinkNode *l, *names, *previews; struct ImBuf* ima; int ok, i, nprevs, nnames, idcode; char filename[FILE_MAX]; char dir[FILE_MAX], group[GROUP_MAX]; /* name test */ ok= filelist_islibrary(filelist, dir, group); if (!ok) { /* free */ if (filelist->libfiledata) BLO_blendhandle_close(filelist->libfiledata); filelist->libfiledata= NULL; return; } BLI_strncpy(filename, G.main->name, sizeof(filename)); /* there we go */ /* for the time being only read filedata when libfiledata==0 */ if (filelist->libfiledata == NULL) { filelist->libfiledata= BLO_blendhandle_from_file(dir, NULL); if (filelist->libfiledata == NULL) return; } idcode= groupname_to_code(group); /* memory for strings is passed into filelist[i].relname * and freed in freefilelist */ if (idcode) { previews= BLO_blendhandle_get_previews(filelist->libfiledata, idcode, &nprevs); names= BLO_blendhandle_get_datablock_names(filelist->libfiledata, idcode, &nnames); /* ugh, no rewind, need to reopen */ BLO_blendhandle_close(filelist->libfiledata); filelist->libfiledata= BLO_blendhandle_from_file(dir, NULL); } else { previews= NULL; nprevs= 0; names= BLO_blendhandle_get_linkable_groups(filelist->libfiledata); nnames= BLI_linklist_length(names); } filelist->numfiles= nnames + 1; filelist->filelist= malloc(filelist->numfiles * sizeof(*filelist->filelist)); memset(filelist->filelist, 0, filelist->numfiles * sizeof(*filelist->filelist)); filelist->filelist[0].relname= BLI_strdup(".."); filelist->filelist[0].type |= S_IFDIR; for (i=0, l= names; i<nnames; i++, l= l->next) { char *blockname= l->link; filelist->filelist[i + 1].relname= BLI_strdup(blockname); if (idcode) { filelist->filelist[i + 1].type |= S_IFREG; } else { filelist->filelist[i + 1].type |= S_IFDIR; } } if (previews && (nnames != nprevs)) { printf("filelist_from_library: error, found %d items, %d previews\n", nnames, nprevs); } else if (previews) { for (i=0, l= previews; i<nnames; i++, l= l->next) { PreviewImage *img= l->link; if (img) { unsigned int w = img->w[ICON_SIZE_PREVIEW]; unsigned int h = img->h[ICON_SIZE_PREVIEW]; unsigned int *rect = img->rect[ICON_SIZE_PREVIEW]; /* first allocate imbuf for copying preview into it */ if (w > 0 && h > 0 && rect) { ima = IMB_allocImBuf(w, h, 32, IB_rect); memcpy(ima->rect, rect, w*h*sizeof(unsigned int)); filelist->filelist[i + 1].image = ima; filelist->filelist[i + 1].flags = IMAGEFILE; } } } } BLI_linklist_free(names, free); if (previews) BLI_linklist_free(previews, BKE_previewimg_freefunc); filelist_sort(filelist, FILE_SORT_ALPHA); BLI_strncpy(G.main->name, filename, sizeof(filename)); // prevent G.main->name to change filelist->filter = 0; filelist_filter(filelist); }
/* Does not fix anything, but checks that all linked data-blocks are still valid (i.e. pointing to the right library). */ bool BLO_main_validate_libraries(struct Main *bmain, struct ReportList *reports) { ListBase mainlist; bool is_valid = true; BKE_main_lock(bmain); blo_split_main(&mainlist, bmain); ListBase *lbarray[MAX_LIBARRAY]; int i = set_listbasepointers(bmain, lbarray); while (i--) { for (ID *id = lbarray[i]->first; id != NULL; id = id->next) { if (id->lib != NULL) { is_valid = false; BKE_reportf(reports, RPT_ERROR, "ID %s is in local database while being linked from library %s!\n", id->name, id->lib->name); } } } for (Main *curmain = bmain->next; curmain != NULL; curmain = curmain->next) { Library *curlib = curmain->curlib; if (curlib == NULL) { BKE_reportf(reports, RPT_ERROR, "Library database with NULL library datablock!\n"); continue; } BKE_library_filepath_set(bmain, curlib, curlib->name); BlendHandle *bh = BLO_blendhandle_from_file(curlib->filepath, reports); if (bh == NULL) { BKE_reportf(reports, RPT_ERROR, "Library ID %s not found at expected path %s!\n", curlib->id.name, curlib->filepath); continue; } i = set_listbasepointers(curmain, lbarray); while (i--) { ID *id = lbarray[i]->first; if (id == NULL) { continue; } if (GS(id->name) == ID_LI) { is_valid = false; BKE_reportf(reports, RPT_ERROR, "Library ID %s in library %s, this should not happen!\n", id->name, curlib->name); continue; } int totnames = 0; LinkNode *names = BLO_blendhandle_get_datablock_names(bh, GS(id->name), &totnames); for (; id != NULL; id = id->next) { if (id->lib == NULL) { is_valid = false; BKE_reportf(reports, RPT_ERROR, "ID %s has NULL lib pointer while being in library %s!\n", id->name, curlib->name); continue; } if (id->lib != curlib) { is_valid = false; BKE_reportf(reports, RPT_ERROR, "ID %s has mismatched lib pointer!\n", id->name); continue; } LinkNode *name = names; for (; name; name = name->next) { char *str_name = (char *)name->link; if (id->name[2] == str_name[0] && STREQ(str_name, id->name + 2)) { break; } } if (name == NULL) { is_valid = false; BKE_reportf(reports, RPT_ERROR, "ID %s not found in library %s anymore!\n", id->name, id->lib->name); continue; } } BLI_linklist_free(names, free); } BLO_blendhandle_close(bh); } blo_join_main(&mainlist); BLI_assert(BLI_listbase_is_single(&mainlist)); BLI_assert(mainlist.first == (void *)bmain); BKE_main_unlock(bmain); return is_valid; }