/* return success (1) */ int BKE_copybuffer_paste(bContext *C, char *libname, ReportList *reports) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(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 flag_all_listbases_ids(LIB_LINK_TAG, 0) is called after! */ flag_all_listbases_ids(LIB_PRE_EXISTING, 1); /* here appending/linking starts */ mainl = BLO_library_append_begin(bmain, &bh, libname); BLO_library_append_all(mainl, bh); BLO_library_append_end(C, mainl, &bh, 0, 0); /* mark all library linked objects to be updated */ recalc_all_library_objects(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, 1); /* important we unset, otherwise these object wont * link into other scenes from this blend file */ flag_all_listbases_ids(LIB_PRE_EXISTING, 0); /* recreate dependency graph to include new objects */ DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); BLO_blendhandle_close(bh); /* remove library... */ return 1; }
static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args)) { Main *bmain = CTX_data_main(BPy_GetContext()); Main *mainl = NULL; int err = 0; flag_all_listbases_ids(LIB_PRE_EXISTING, 1); /* here appending/linking starts */ mainl = BLO_library_append_begin(bmain, &(self->blo_handle), self->relpath); { 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 *ls = PyDict_GetItemString(self->dict, name_plural); // printf("lib: %s\n", name_plural); if (ls && PyList_Check(ls)) { /* loop */ Py_ssize_t size = PyList_GET_SIZE(ls); Py_ssize_t i; PyObject *item; const char *item_str; for (i = 0; i < size; i++) { item = PyList_GET_ITEM(ls, i); item_str = _PyUnicode_AsString(item); // printf(" %s\n", item_str); if (item_str) { ID *id = BLO_library_append_named_part(mainl, &(self->blo_handle), item_str, code); if (id) { #ifdef USE_RNA_DATABLOCKS PointerRNA id_ptr; RNA_id_pointer_create(id, &id_ptr); Py_DECREF(item); item = pyrna_struct_CreatePyObject(&id_ptr); #endif } else { bpy_lib_exit_warn_idname(self, name_plural, item_str); /* just warn for now */ /* err = -1; */ #ifdef USE_RNA_DATABLOCKS item = Py_None; Py_INCREF(item); #endif } /* ID or None */ } else { /* XXX, could complain about this */ bpy_lib_exit_warn_type(self, item); PyErr_Clear(); #ifdef USE_RNA_DATABLOCKS item = Py_None; Py_INCREF(item); #endif } #ifdef USE_RNA_DATABLOCKS PyList_SET_ITEM(ls, i, item); #endif } } } } } if (err == -1) { /* exception raised above, XXX, this leaks some memory */ BLO_blendhandle_close(self->blo_handle); self->blo_handle = NULL; flag_all_listbases_ids(LIB_PRE_EXISTING, 0); return NULL; } else { Library *lib = mainl->curlib; /* newly added lib, assign before append end */ BLO_library_append_end(NULL, mainl, &(self->blo_handle), 0, self->flag); BLO_blendhandle_close(self->blo_handle); self->blo_handle = NULL; { /* copied from wm_operator.c */ /* mark all library linked objects to be updated */ recalc_all_library_objects(G.main); /* append, rather than linking */ if ((self->flag & FILE_LINK) == 0) { BKE_library_make_local(bmain, lib, 1); } } flag_all_listbases_ids(LIB_PRE_EXISTING, 0); Py_RETURN_NONE; } }
bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options) { Main *main_newlib; /* stored as a dynamic 'main' until we free it */ Main *main_tmp= NULL; /* created only for linking, then freed */ LinkNode *names = NULL; int idcode= BKE_idcode_from_name(group); short flag= 0; /* don't need any special options */ ReportList reports; static char err_local[255]; /* only scene and mesh supported right now */ if (idcode!=ID_SCE && idcode!=ID_ME &&idcode!=ID_AC) { snprintf(err_local, sizeof(err_local), "invalid ID type given \"%s\"\n", group); *err_str= err_local; BLO_blendhandle_close(bpy_openlib); return false; } if (GetMainDynamicPath(path)) { snprintf(err_local, sizeof(err_local), "blend file already open \"%s\"\n", path); *err_str= err_local; BLO_blendhandle_close(bpy_openlib); return false; } if (bpy_openlib==NULL) { snprintf(err_local, sizeof(err_local), "could not open blendfile \"%s\"\n", path); *err_str= err_local; return false; } main_newlib= (Main *)MEM_callocN( sizeof(Main), "BgeMain"); BKE_reports_init(&reports, RPT_STORE); /* here appending/linking starts */ main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path); int totnames_dummy; names = BLO_blendhandle_get_datablock_names( bpy_openlib, idcode, &totnames_dummy); int i=0; LinkNode *n= names; while(n) { BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, idcode); n= (LinkNode *)n->next; i++; } BLI_linklist_free(names, free); /* free linklist *and* each node's data */ BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag); /* now do another round of linking for Scenes so all actions are properly loaded */ if (idcode==ID_SCE && options & LIB_LOAD_LOAD_ACTIONS) { main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path); int totnames_dummy; names = BLO_blendhandle_get_datablock_names( bpy_openlib, ID_AC, &totnames_dummy); int i=0; LinkNode *n= names; while(n) { BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, ID_AC); n= (LinkNode *)n->next; i++; } BLI_linklist_free(names, free); /* free linklist *and* each node's data */ BLO_library_append_end(NULL, main_tmp, &bpy_openlib, ID_AC, flag); } BLO_blendhandle_close(bpy_openlib); BKE_reports_clear(&reports); /* done linking */ /* needed for lookups*/ GetMainDynamic().push_back(main_newlib); strncpy(main_newlib->name, path, sizeof(main_newlib->name)); if (idcode==ID_ME) { /* Convert all new meshes into BGE meshes */ ID* mesh; for (mesh= (ID *)main_newlib->mesh.first; mesh; mesh= (ID *)mesh->next ) { if (options & LIB_LOAD_VERBOSE) printf("MeshName: %s\n", mesh->name+2); RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this); scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); } } else if (idcode==ID_AC) { /* Convert all actions */ ID *action; for (action= (ID *)main_newlib->action.first; action; action= (ID *)action->next) { if (options & LIB_LOAD_VERBOSE) printf("ActionName: %s\n", action->name+2); scene_merge->GetLogicManager()->RegisterActionName(action->name+2, action); } } else if (idcode==ID_SCE) { /* Merge all new linked in scene into the existing one */ ID *scene; for (scene= (ID *)main_newlib->scene.first; scene; scene= (ID *)scene->next ) { if (options & LIB_LOAD_VERBOSE) printf("SceneName: %s\n", scene->name+2); /* merge into the base scene */ KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene); scene_merge->MergeScene(other); // RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene delete other; } /* Now handle all the actions */ if (options & LIB_LOAD_LOAD_ACTIONS) { ID *action; for (action= (ID *)main_newlib->action.first; action; action= (ID *)action->next) { if (options & LIB_LOAD_VERBOSE) printf("ActionName: %s\n", action->name+2); scene_merge->GetLogicManager()->RegisterActionName(action->name+2, action); } } } return true; }
KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options) { Main *main_newlib; /* stored as a dynamic 'main' until we free it */ const int idcode = BKE_idcode_from_name(group); ReportList reports; static char err_local[255]; // TIMEIT_START(bge_link_blend_file); KX_LibLoadStatus *status; /* only scene and mesh supported right now */ if (idcode != ID_SCE && idcode != ID_ME && idcode != ID_AC) { snprintf(err_local, sizeof(err_local), "invalid ID type given \"%s\"\n", group); *err_str = err_local; BLO_blendhandle_close(bpy_openlib); return NULL; } if (GetMainDynamicPath(path)) { snprintf(err_local, sizeof(err_local), "blend file already open \"%s\"\n", path); *err_str = err_local; BLO_blendhandle_close(bpy_openlib); return NULL; } if (bpy_openlib == NULL) { snprintf(err_local, sizeof(err_local), "could not open blendfile \"%s\"\n", path); *err_str = err_local; return NULL; } main_newlib = BKE_main_new(); BKE_reports_init(&reports, RPT_STORE); short flag = 0; /* don't need any special options */ /* created only for linking, then freed */ Main *main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path); load_datablocks(main_tmp, bpy_openlib, path, idcode); if (idcode == ID_SCE && options & LIB_LOAD_LOAD_SCRIPTS) { load_datablocks(main_tmp, bpy_openlib, path, ID_TXT); } /* now do another round of linking for Scenes so all actions are properly loaded */ if (idcode == ID_SCE && options & LIB_LOAD_LOAD_ACTIONS) { load_datablocks(main_tmp, bpy_openlib, path, ID_AC); } BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag); BLO_blendhandle_close(bpy_openlib); BKE_reports_clear(&reports); /* done linking */ /* needed for lookups*/ GetMainDynamic().push_back(main_newlib); BLI_strncpy(main_newlib->name, path, sizeof(main_newlib->name)); status = new KX_LibLoadStatus(this, m_ketsjiEngine, scene_merge, path); if (idcode == ID_ME) { /* Convert all new meshes into BGE meshes */ ID *mesh; for (mesh = (ID *)main_newlib->mesh.first; mesh; mesh = (ID *)mesh->next ) { if (options & LIB_LOAD_VERBOSE) printf("MeshName: %s\n", mesh->name + 2); RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this, false); // For now only use the libloading option for scenes, which need to handle materials/shaders scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(), meshobj); } } else if (idcode == ID_AC) { /* Convert all actions */ ID *action; for (action= (ID *)main_newlib->action.first; action; action = (ID *)action->next) { if (options & LIB_LOAD_VERBOSE) printf("ActionName: %s\n", action->name + 2); scene_merge->GetLogicManager()->RegisterActionName(action->name + 2, action); } } else if (idcode == ID_SCE) { /* Merge all new linked in scene into the existing one */ ID *scene; // scenes gets deleted by the thread when it's done using it (look in async_convert()) vector<Scene *> *scenes = (options & LIB_LOAD_ASYNC) ? new vector<Scene *>() : NULL; for (scene = (ID *)main_newlib->scene.first; scene; scene = (ID *)scene->next ) { if (options & LIB_LOAD_VERBOSE) printf("SceneName: %s\n", scene->name + 2); if (options & LIB_LOAD_ASYNC) { scenes->push_back((Scene *)scene); } else { /* merge into the base scene */ KX_Scene* other = m_ketsjiEngine->CreateScene((Scene *)scene, true); scene_merge->MergeScene(other); // RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene delete other; } } if (options & LIB_LOAD_ASYNC) { pthread_t id; status->SetData(scenes); pthread_create(&id, NULL, &async_convert, (void *)status); m_threadinfo->threads.push_back(id); } #ifdef WITH_PYTHON /* Handle any text datablocks */ if (options & LIB_LOAD_LOAD_SCRIPTS) addImportMain(main_newlib); #endif /* Now handle all the actions */ if (options & LIB_LOAD_LOAD_ACTIONS) { ID *action; for (action = (ID *)main_newlib->action.first; action; action = (ID *)action->next) { if (options & LIB_LOAD_VERBOSE) printf("ActionName: %s\n", action->name + 2); scene_merge->GetLogicManager()->RegisterActionName(action->name + 2, action); } } } if (!(options & LIB_LOAD_ASYNC)) status->Finish(); // TIMEIT_END(bge_link_blend_file); m_status_map[main_newlib->name] = status; return status; }