int id_unlink(ID *id, int test) { Main *mainlib = G.main; ListBase *lb; switch (GS(id->name)) { case ID_TXT: if (test) return 1; BKE_text_unlink(mainlib, (Text *)id); break; case ID_GR: if (test) return 1; BKE_group_unlink((Group *)id); break; case ID_OB: if (test) return 1; BKE_object_unlink((Object *)id); break; } if (id->us == 0) { if (test) return 1; lb = which_libbase(mainlib, GS(id->name)); BKE_libblock_free(lb, id); return 1; } return 0; }
bool id_unlink(ID *id, int test) { Main *mainlib = G.main; short type = GS(id->name); switch (type) { case ID_TXT: if (test) return true; BKE_text_unlink(mainlib, (Text *)id); break; case ID_GR: if (test) return true; BKE_group_unlink((Group *)id); break; case ID_OB: if (test) return true; BKE_object_unlink((Object *)id); break; } if (id->us == 0) { if (test) return true; BKE_libblock_free(mainlib, id); return true; } return false; }
BL_ArmatureObject::~BL_ArmatureObject() { BL_ArmatureConstraint* constraint; while ((constraint = m_controlledConstraints.Remove()) != NULL) { delete constraint; } BL_ArmatureChannel* channel; while ((channel = static_cast<BL_ArmatureChannel*>(m_poseChannels.Remove())) != NULL) { delete channel; } if (m_objArma) { BKE_libblock_free(G.main, m_objArma->data); BKE_libblock_free(G.main, m_objArma); } }
bSound *sound_new_limiter(struct Main *bmain, bSound *source, float start, float end) { bSound *sound = NULL; char name[MAX_ID_NAME + 5]; strcpy(name, "lim_"); strcpy(name + 4, source->id.name); sound = BKE_libblock_alloc(bmain, ID_SO, name); sound->child_sound = source; sound->start = start; sound->end = end; sound->type = SOUND_TYPE_LIMITER; sound_load(bmain, sound); if (!sound->playback_handle) { BKE_libblock_free(bmain, sound); sound = NULL; } return sound; }
bSound *sound_new_file(struct Main *bmain, const char *filename) { bSound *sound = NULL; char str[FILE_MAX]; char *path; size_t len; BLI_strncpy(str, filename, sizeof(str)); path = /*bmain ? bmain->name :*/ G.main->name; BLI_path_abs(str, path); len = strlen(filename); while (len > 0 && filename[len - 1] != '/' && filename[len - 1] != '\\') len--; sound = BKE_libblock_alloc(bmain, ID_SO, filename + len); BLI_strncpy(sound->name, filename, FILE_MAX); /* sound->type = SOUND_TYPE_FILE; */ /* XXX unused currently */ sound_load(bmain, sound); if (!sound->playback_handle) { BKE_libblock_free(bmain, sound); sound = NULL; } return sound; }
void BKE_sound_delete(struct Main *bmain, bSound *sound) { if (sound) { BKE_sound_free(sound); BKE_libblock_free(bmain, sound); } }
void sound_delete(struct Main *bmain, struct bSound *sound) { if (sound) { BKE_sound_free(sound); BKE_libblock_free(&bmain->sound, sound); } }
/* memfile is the undo buffer */ int BKE_read_file_from_memfile(bContext *C, MemFile *memfile, ReportList *reports) { BlendFileData *bfd; bfd = BLO_read_from_memfile(CTX_data_main(C), G.main->name, memfile, reports); if (bfd) { /* remove the unused screens and wm */ while (bfd->main->wm.first) BKE_libblock_free(&bfd->main->wm, bfd->main->wm.first); while (bfd->main->screen.first) BKE_libblock_free(&bfd->main->screen, bfd->main->screen.first); setup_app_data(C, bfd, "<memory1>"); } else BKE_reports_prepend(reports, "Loading failed: "); return (bfd ? 1 : 0); }
BlenderStrokeRenderer::~BlenderStrokeRenderer() { if (0 != _textureManager) { delete _textureManager; _textureManager = NULL; } // The freestyle_scene object is not released here. Instead, // the scene is released in free_all_freestyle_renders() in // source/blender/render/intern/source/pipeline.c, after the // compositor has finished. // release objects and data blocks for (Base *b = (Base *)freestyle_scene->base.first; b; b = b->next) { Object *ob = b->object; void *data = ob->data; char *name = ob->id.name; #if 0 if (G.debug & G_DEBUG_FREESTYLE) { cout << "removing " << name[0] << name[1] << ":" << (name+2) << endl; } #endif switch (ob->type) { case OB_MESH: BKE_libblock_free(&freestyle_bmain->object, ob); BKE_libblock_free(&freestyle_bmain->mesh, data); break; case OB_CAMERA: BKE_libblock_free(&freestyle_bmain->object, ob); BKE_libblock_free(&freestyle_bmain->camera, data); freestyle_scene->camera = NULL; break; default: cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":" << (name + 2) << endl; } } BLI_freelistN(&freestyle_scene->base); // release material BKE_libblock_free(&freestyle_bmain->mat, material); }
/* this is event from ghost, or exit-blender op */ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) { wmWindow *tmpwin; bool do_exit = false; /* first check if we have to quit (there are non-temp remaining windows) */ for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) { if (tmpwin == win) continue; if (tmpwin->screen->temp == 0) break; } if (tmpwin == NULL) do_exit = 1; if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) { if (do_exit) { if (!GHOST_confirmQuit(win->ghostwin)) return; } } /* let WM_exit do all freeing, for correct quit.blend save */ if (do_exit) { WM_exit(C); } else { bScreen *screen = win->screen; BLI_remlink(&wm->windows, win); wm_draw_window_clear(win); CTX_wm_window_set(C, win); /* needed by handlers */ WM_event_remove_handlers(C, &win->handlers); WM_event_remove_handlers(C, &win->modalhandlers); /* for regular use this will _never_ be NULL, * however we may be freeing an improperly initialized window. */ if (win->screen) { ED_screen_exit(C, win, win->screen); } wm_window_free(C, wm, win); /* if temp screen, delete it after window free (it stops jobs that can access it) */ if (screen && screen->temp) { Main *bmain = CTX_data_main(C); BKE_libblock_free(bmain, screen); } } }
BL_Action::~BL_Action() { if (m_blendpose) BKE_pose_free(m_blendpose); if (m_blendinpose) BKE_pose_free(m_blendinpose); ClearControllerList(); if (m_tmpaction) { BKE_libblock_free(G.main, m_tmpaction); m_tmpaction = NULL; } }
void BKE_libblock_delete(Main *bmain, void *idv) { ListBase *lbarray[MAX_LIBARRAY]; int base_count, i; base_count = set_listbasepointers(bmain, lbarray); BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); /* First tag all datablocks directly from target lib. * Note that we go forward here, since we want to check dependencies before users (e.g. meshes before objects). * Avoids to have to loop twice. */ for (i = 0; i < base_count; i++) { ListBase *lb = lbarray[i]; ID *id; for (id = lb->first; id; id = id->next) { /* Note: in case we delete a library, we also delete all its datablocks! */ if ((id == (ID *)idv) || (id->lib == (Library *)idv) || (id->tag & LIB_TAG_DOIT)) { id->tag |= LIB_TAG_DOIT; /* Will tag 'never NULL' users of this ID too. * Note that we cannot use BKE_libblock_unlink() here, since it would ignore indirect (and proxy!) * links, this can lead to nasty crashing here in second, actual deleting loop. * Also, this will also flag users of deleted data that cannot be unlinked * (object using deleted obdata, etc.), so that they also get deleted. */ BKE_libblock_remap(bmain, id, NULL, ID_REMAP_FLAG_NEVER_NULL_USAGE | ID_REMAP_FORCE_NEVER_NULL_USAGE); } } } /* In usual reversed order, such that all usage of a given ID, even 'never NULL' ones, have been already cleared * when we reach it (e.g. Objects being processed before meshes, they'll have already released their 'reference' * over meshes when we come to freeing obdata). */ for (i = base_count; i--; ) { ListBase *lb = lbarray[i]; ID *id, *id_next; for (id = lb->first; id; id = id_next) { id_next = id->next; if (id->tag & LIB_TAG_DOIT) { if (id->us != 0) { #ifdef DEBUG_PRINT printf("%s: deleting %s (%d)\n", __func__, id->name, id->us); #endif BLI_assert(id->us == 0); } BKE_libblock_free(bmain, id); } } } }
/* memfile is the undo buffer */ bool BKE_blendfile_read_from_memfile( bContext *C, struct MemFile *memfile, ReportList *reports, int skip_flags) { Main *bmain = CTX_data_main(C); BlendFileData *bfd; bfd = BLO_read_from_memfile(bmain, BKE_main_blendfile_path(bmain), memfile, reports, skip_flags); if (bfd) { /* remove the unused screens and wm */ while (bfd->main->wm.first) BKE_libblock_free(bfd->main, bfd->main->wm.first); while (bfd->main->screen.first) BKE_libblock_free(bfd->main, bfd->main->screen.first); setup_app_data(C, bfd, "<memory1>", reports); } else { BKE_reports_prepend(reports, "Loading failed: "); } return (bfd != NULL); }
/* this is event from ghost, or exit-blender op */ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) { wmWindow *tmpwin; bScreen *screen = win->screen; /* first check if we have any non-temp remaining windows */ if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) { if (wm->windows.first) { for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) { if (tmpwin == win) continue; if (tmpwin->screen->temp == 0) break; } if (tmpwin == NULL) { if (!GHOST_confirmQuit(win->ghostwin)) return; } } } BLI_remlink(&wm->windows, win); wm_draw_window_clear(win); CTX_wm_window_set(C, win); /* needed by handlers */ WM_event_remove_handlers(C, &win->handlers); WM_event_remove_handlers(C, &win->modalhandlers); ED_screen_exit(C, win, win->screen); wm_window_free(C, wm, win); /* if temp screen, delete it after window free (it stops jobs that can access it) */ if (screen->temp) { Main *bmain = CTX_data_main(C); BKE_libblock_free(&bmain->screen, screen); } /* check remaining windows */ if (wm->windows.first) { for (win = wm->windows.first; win; win = win->next) if (win->screen->temp == 0) break; /* in this case we close all */ if (win == NULL) WM_exit(C); } else WM_exit(C); }
void BKE_libblock_free_us(ListBase *lb, void *idv) /* test users */ { ID *id = idv; id->us--; if (id->us < 0) { if (id->lib) printf("ERROR block %s %s users %d\n", id->lib->name, id->name, id->us); else printf("ERROR block %s users %d\n", id->name, id->us); } if (id->us == 0) { if (GS(id->name) == ID_OB) BKE_object_unlink((Object *)id); BKE_libblock_free(lb, id); } }
Object *DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Scene *sce) { const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId(); if (uid_lamp_map.find(lamp_uid) == uid_lamp_map.end()) { fprintf(stderr, "Couldn't find lamp by UID.\n"); return NULL; } Object *ob = bc_add_object(sce, OB_LAMP, NULL); Lamp *la = uid_lamp_map[lamp_uid]; Lamp *old_lamp = (Lamp *)ob->data; ob->data = la; id_us_min(&old_lamp->id); if (old_lamp->id.us == 0) BKE_libblock_free(G.main, old_lamp); return ob; }
Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce) { const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId(); if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) { // fprintf(stderr, "Couldn't find camera by UID.\n"); return NULL; } Object *ob = bc_add_object(sce, OB_CAMERA, NULL); Camera *cam = uid_camera_map[cam_uid]; Camera *old_cam = (Camera *)ob->data; ob->data = cam; id_us_min(&old_cam->id); if (old_cam->id.us == 0) BKE_libblock_free(G.main, old_cam); return ob; }
void free_main(Main *mainvar) { /* also call when reading a file, erase all, etc */ ListBase *lbarray[MAX_LIBARRAY]; int a; a = set_listbasepointers(mainvar, lbarray); while (a--) { ListBase *lb = lbarray[a]; ID *id; while ( (id = lb->first) ) { BKE_libblock_free(lb, id); } } MEM_freeN(mainvar); }
void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce) { Scene *sce1; bScreen *sc; /* check all sets */ for (sce1 = bmain->scene.first; sce1; sce1 = sce1->id.next) if (sce1->set == sce) sce1->set = NULL; /* check render layer nodes in other scenes */ clear_scene_in_nodes(bmain, sce); /* al screens */ for (sc = bmain->screen.first; sc; sc = sc->id.next) if (sc->scene == sce) sc->scene = newsce; BKE_libblock_free(&bmain->scene, sce); }
void BKE_libblock_free_us(Main *bmain, void *idv) /* test users */ { ID *id = idv; id_us_min(id); /* XXX This is a temp (2.77) hack so that we keep same behavior as in 2.76 regarding groups when deleting an object. * Since only 'user_one' usage of objects is groups, and only 'real user' usage of objects is scenes, * removing that 'user_one' tag when there is no more real (scene) users of an object ensures it gets * fully unlinked. * Otherwise, there is no real way to get rid of an object anymore - better handling of this is TODO. */ if ((GS(id->name) == ID_OB) && (id->us == 1)) { id_us_clear_real(id); } if (id->us == 0) { BKE_libblock_unlink(bmain, id, false, false); BKE_libblock_free(bmain, id); } }
bSound *sound_new_buffer(struct Main *bmain, bSound *source) { bSound *sound = NULL; char name[MAX_ID_NAME + 5]; strcpy(name, "buf_"); strcpy(name + 4, source->id.name); sound = BKE_libblock_alloc(bmain, ID_SO, name); sound->child_sound = source; sound->type = SOUND_TYPE_BUFFER; sound_load(bmain, sound); if (!sound->playback_handle) { BKE_libblock_free(bmain, sound); sound = NULL; } return sound; }
static int bake( Render *re, Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports, const ScenePassType pass_type, const int margin, const BakeSaveMode save_mode, const bool is_clear, const bool is_split_materials, const bool is_automatic_name, const bool is_selected_to_active, const bool is_cage, const float cage_extrusion, const int normal_space, const BakeNormalSwizzle normal_swizzle[], const char *custom_cage, const char *filepath, const int width, const int height, const char *identifier, ScrArea *sa, const char *uv_layer) { int op_result = OPERATOR_CANCELLED; bool ok = false; Object *ob_cage = NULL; BakeHighPolyData *highpoly = NULL; int tot_highpoly = 0; char restrict_flag_low = ob_low->restrictflag; char restrict_flag_cage = 0; Mesh *me_low = NULL; Mesh *me_cage = NULL; float *result = NULL; BakePixel *pixel_array_low = NULL; BakePixel *pixel_array_high = NULL; const bool is_save_internal = (save_mode == R_BAKE_SAVE_INTERNAL); const bool is_noncolor = is_noncolor_pass(pass_type); const int depth = RE_pass_depth(pass_type); BakeImages bake_images = {NULL}; size_t num_pixels; int tot_materials; RE_bake_engine_set_engine_parameters(re, bmain, scene); if (!RE_bake_has_engine(re)) { BKE_report(reports, RPT_ERROR, "Current render engine does not support baking"); goto cleanup; } tot_materials = ob_low->totcol; if (uv_layer && uv_layer[0] != '\0') { Mesh *me = (Mesh *)ob_low->data; if (CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer) == -1) { BKE_reportf(reports, RPT_ERROR, "No UV layer named \"%s\" found in the object \"%s\"", uv_layer, ob_low->id.name + 2); goto cleanup; } } if (tot_materials == 0) { if (is_save_internal) { BKE_report(reports, RPT_ERROR, "No active image found, add a material or bake to an external file"); goto cleanup; } else if (is_split_materials) { BKE_report(reports, RPT_ERROR, "No active image found, add a material or bake without the Split Materials option"); goto cleanup; } else { /* baking externally without splitting materials */ tot_materials = 1; } } /* we overallocate in case there is more materials than images */ bake_images.data = MEM_mallocN(sizeof(BakeImage) * tot_materials, "bake images dimensions (width, height, offset)"); bake_images.lookup = MEM_mallocN(sizeof(int) * tot_materials, "bake images lookup (from material to BakeImage)"); build_image_lookup(bmain, ob_low, &bake_images); if (is_save_internal) { num_pixels = initialize_internal_images(&bake_images, reports); if (num_pixels == 0) { goto cleanup; } } else { /* when saving extenally always use the size specified in the UI */ num_pixels = (size_t)width * (size_t)height * bake_images.size; for (int i = 0; i < bake_images.size; i++) { bake_images.data[i].width = width; bake_images.data[i].height = height; bake_images.data[i].offset = (is_split_materials ? num_pixels : 0); bake_images.data[i].image = NULL; } if (!is_split_materials) { /* saving a single image */ for (int i = 0; i < tot_materials; i++) { bake_images.lookup[i] = 0; } } } if (is_selected_to_active) { CollectionPointerLink *link; tot_highpoly = 0; for (link = selected_objects->first; link; link = link->next) { Object *ob_iter = link->ptr.data; if (ob_iter == ob_low) continue; tot_highpoly ++; } if (is_cage && custom_cage[0] != '\0') { ob_cage = BLI_findstring(&bmain->object, custom_cage, offsetof(ID, name) + 2); if (ob_cage == NULL || ob_cage->type != OB_MESH) { BKE_report(reports, RPT_ERROR, "No valid cage object"); goto cleanup; } else { restrict_flag_cage = ob_cage->restrictflag; ob_cage->restrictflag |= OB_RESTRICT_RENDER; } } } pixel_array_low = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly"); pixel_array_high = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly"); result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels"); /* get the mesh as it arrives in the renderer */ me_low = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 0, 0); BKE_mesh_split_faces(me_low); /* populate the pixel array with the face data */ if ((is_selected_to_active && (ob_cage == NULL) && is_cage) == false) RE_bake_pixels_populate(me_low, pixel_array_low, num_pixels, &bake_images, uv_layer); /* else populate the pixel array with the 'cage' mesh (the smooth version of the mesh) */ if (is_selected_to_active) { CollectionPointerLink *link; ModifierData *md, *nmd; ListBase modifiers_tmp, modifiers_original; int i = 0; /* prepare cage mesh */ if (ob_cage) { me_cage = BKE_mesh_new_from_object(bmain, scene, ob_cage, 1, 2, 0, 0); BKE_mesh_split_faces(me_cage); if ((me_low->totpoly != me_cage->totpoly) || (me_low->totloop != me_cage->totloop)) { BKE_report(reports, RPT_ERROR, "Invalid cage object, the cage mesh must have the same number " "of faces as the active object"); goto cleanup; } } else if (is_cage) { modifiers_original = ob_low->modifiers; BLI_listbase_clear(&modifiers_tmp); for (md = ob_low->modifiers.first; md; md = md->next) { /* Edge Split cannot be applied in the cage, * the cage is supposed to have interpolated normals * between the faces unless the geometry is physically * split. So we create a copy of the low poly mesh without * the eventual edge split.*/ if (md->type == eModifierType_EdgeSplit) continue; nmd = modifier_new(md->type); BLI_strncpy(nmd->name, md->name, sizeof(nmd->name)); modifier_copyData(md, nmd); BLI_addtail(&modifiers_tmp, nmd); } /* temporarily replace the modifiers */ ob_low->modifiers = modifiers_tmp; /* get the cage mesh as it arrives in the renderer */ me_cage = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 0, 0); BKE_mesh_split_faces(me_cage); RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer); } highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects"); /* populate highpoly array */ for (link = selected_objects->first; link; link = link->next) { TriangulateModifierData *tmd; Object *ob_iter = link->ptr.data; if (ob_iter == ob_low) continue; /* initialize highpoly_data */ highpoly[i].ob = ob_iter; highpoly[i].restrict_flag = ob_iter->restrictflag; /* triangulating so BVH returns the primitive_id that will be used for rendering */ highpoly[i].tri_mod = ED_object_modifier_add( reports, bmain, scene, highpoly[i].ob, "TmpTriangulate", eModifierType_Triangulate); tmd = (TriangulateModifierData *)highpoly[i].tri_mod; tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED; tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP; highpoly[i].me = BKE_mesh_new_from_object(bmain, scene, highpoly[i].ob, 1, 2, 0, 0); highpoly[i].ob->restrictflag &= ~OB_RESTRICT_RENDER; BKE_mesh_split_faces(highpoly[i].me); /* lowpoly to highpoly transformation matrix */ copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat); invert_m4_m4(highpoly[i].imat, highpoly[i].obmat); highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->obmat); i++; } BLI_assert(i == tot_highpoly); ob_low->restrictflag |= OB_RESTRICT_RENDER; /* populate the pixel arrays with the corresponding face data for each high poly object */ if (!RE_bake_pixels_populate_from_objects( me_low, pixel_array_low, pixel_array_high, highpoly, tot_highpoly, num_pixels, ob_cage != NULL, cage_extrusion, ob_low->obmat, (ob_cage ? ob_cage->obmat : ob_low->obmat), me_cage)) { BKE_report(reports, RPT_ERROR, "Error handling selected objects"); goto cage_cleanup; } /* the baking itself */ for (i = 0; i < tot_highpoly; i++) { ok = RE_bake_engine(re, highpoly[i].ob, i, pixel_array_high, num_pixels, depth, pass_type, result); if (!ok) { BKE_reportf(reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2); goto cage_cleanup; } } cage_cleanup: /* reverting data back */ if ((ob_cage == NULL) && is_cage) { ob_low->modifiers = modifiers_original; while ((md = BLI_pophead(&modifiers_tmp))) { modifier_free(md); } } if (!ok) { goto cleanup; } } else { /* make sure low poly renders */ ob_low->restrictflag &= ~OB_RESTRICT_RENDER; if (RE_bake_has_engine(re)) { ok = RE_bake_engine(re, ob_low, 0, pixel_array_low, num_pixels, depth, pass_type, result); } else { BKE_report(reports, RPT_ERROR, "Current render engine does not support baking"); goto cleanup; } } /* normal space conversion * the normals are expected to be in world space, +X +Y +Z */ if (ok && pass_type == SCE_PASS_NORMAL) { switch (normal_space) { case R_BAKE_SPACE_WORLD: { /* Cycles internal format */ if ((normal_swizzle[0] == R_BAKE_POSX) && (normal_swizzle[1] == R_BAKE_POSY) && (normal_swizzle[2] == R_BAKE_POSZ)) { break; } else { RE_bake_normal_world_to_world(pixel_array_low, num_pixels, depth, result, normal_swizzle); } break; } case R_BAKE_SPACE_OBJECT: { RE_bake_normal_world_to_object(pixel_array_low, num_pixels, depth, result, ob_low, normal_swizzle); break; } case R_BAKE_SPACE_TANGENT: { if (is_selected_to_active) { RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_low, normal_swizzle, ob_low->obmat); } else { /* from multiresolution */ Mesh *me_nores = NULL; ModifierData *md = NULL; int mode; md = modifiers_findByType(ob_low, eModifierType_Multires); if (md) { mode = md->mode; md->mode &= ~eModifierMode_Render; } me_nores = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 0, 0); BKE_mesh_split_faces(me_nores); RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer); RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_nores, normal_swizzle, ob_low->obmat); BKE_libblock_free(bmain, me_nores); if (md) md->mode = mode; } break; } default: break; } } if (!ok) { BKE_reportf(reports, RPT_ERROR, "Problem baking object \"%s\"", ob_low->id.name + 2); op_result = OPERATOR_CANCELLED; } else { /* save the results */ for (int i = 0; i < bake_images.size; i++) { BakeImage *bk_image = &bake_images.data[i]; if (is_save_internal) { ok = write_internal_bake_pixels( bk_image->image, pixel_array_low + bk_image->offset, result + bk_image->offset * depth, bk_image->width, bk_image->height, margin, is_clear, is_noncolor); /* might be read by UI to set active image for display */ bake_update_image(sa, bk_image->image); if (!ok) { BKE_reportf(reports, RPT_ERROR, "Problem saving the bake map internally for object \"%s\"", ob_low->id.name + 2); op_result = OPERATOR_CANCELLED; } else { BKE_report(reports, RPT_INFO, "Baking map saved to internal image, save it externally or pack it"); op_result = OPERATOR_FINISHED; } } /* save externally */ else { BakeData *bake = &scene->r.bake; char name[FILE_MAX]; BKE_image_path_from_imtype(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false, NULL); if (is_automatic_name) { BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_"); BLI_path_suffix(name, FILE_MAX, identifier, "_"); } if (is_split_materials) { if (bk_image->image) { BLI_path_suffix(name, FILE_MAX, bk_image->image->id.name + 2, "_"); } else { if (ob_low->mat[i]) { BLI_path_suffix(name, FILE_MAX, ob_low->mat[i]->id.name + 2, "_"); } else if (me_low->mat[i]) { BLI_path_suffix(name, FILE_MAX, me_low->mat[i]->id.name + 2, "_"); } else { /* if everything else fails, use the material index */ char tmp[4]; sprintf(tmp, "%d", i % 1000); BLI_path_suffix(name, FILE_MAX, tmp, "_"); } } } /* save it externally */ ok = write_external_bake_pixels( name, pixel_array_low + bk_image->offset, result + bk_image->offset * depth, bk_image->width, bk_image->height, margin, &bake->im_format, is_noncolor); if (!ok) { BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\"", name); op_result = OPERATOR_CANCELLED; } else { BKE_reportf(reports, RPT_INFO, "Baking map written to \"%s\"", name); op_result = OPERATOR_FINISHED; } if (!is_split_materials) { break; } } } } if (is_save_internal) refresh_images(&bake_images); cleanup: if (highpoly) { int i; for (i = 0; i < tot_highpoly; i++) { highpoly[i].ob->restrictflag = highpoly[i].restrict_flag; if (highpoly[i].tri_mod) ED_object_modifier_remove(reports, bmain, highpoly[i].ob, highpoly[i].tri_mod); if (highpoly[i].me) BKE_libblock_free(bmain, highpoly[i].me); } MEM_freeN(highpoly); } ob_low->restrictflag = restrict_flag_low; if (ob_cage) ob_cage->restrictflag = restrict_flag_cage; if (pixel_array_low) MEM_freeN(pixel_array_low); if (pixel_array_high) MEM_freeN(pixel_array_high); if (bake_images.data) MEM_freeN(bake_images.data); if (bake_images.lookup) MEM_freeN(bake_images.lookup); if (result) MEM_freeN(result); if (me_low) BKE_libblock_free(bmain, me_low); if (me_cage) BKE_libblock_free(bmain, me_cage); return op_result; }
/* returns 1 if its OK */ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) { bNodeLink *link, *linkn, *tlink; bNode *node, *nextnode; bNodeTree *ngroup, *wgroup; ListBase anim_basepaths = {NULL, NULL}; ngroup = (bNodeTree *)gnode->id; /* clear new pointers, set in copytree */ for (node = ntree->nodes.first; node; node = node->next) node->new_node = NULL; /* wgroup is a temporary copy of the NodeTree we're merging in * - all of wgroup's nodes are transferred across to their new home * - ngroup (i.e. the source NodeTree) is left unscathed * - temp copy. don't change ID usercount */ wgroup = ntreeCopyTree_ex(ngroup, FALSE); /* Add the nodes into the ntree */ for (node = wgroup->nodes.first; node; node = nextnode) { nextnode = node->next; /* Remove interface nodes. * This also removes remaining links to and from interface nodes. */ if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) { nodeFreeNode(wgroup, node); continue; } /* keep track of this node's RNA "base" path (the part of the path identifying the node) * if the old nodetree has animation data which potentially covers this node */ if (wgroup->adt) { PointerRNA ptr; char *path; RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr); path = RNA_path_from_ID_to_struct(&ptr); if (path) BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); } /* migrate node */ BLI_remlink(&wgroup->nodes, node); BLI_addtail(&ntree->nodes, node); /* ensure unique node name in the node tree */ nodeUniqueName(ntree, node); if (!node->parent) { node->locx += gnode->locx; node->locy += gnode->locy; } node->flag |= NODE_SELECT; } /* Add internal links to the ntree */ for (link = wgroup->links.first; link; link = linkn) { linkn = link->next; BLI_remlink(&wgroup->links, link); BLI_addtail(&ntree->links, link); } /* and copy across the animation, * note that the animation data's action can be NULL here */ if (wgroup->adt) { LinkData *ld, *ldn = NULL; bAction *waction; /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */ waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action); /* now perform the moving */ BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths); /* paths + their wrappers need to be freed */ for (ld = anim_basepaths.first; ld; ld = ldn) { ldn = ld->next; MEM_freeN(ld->data); BLI_freelinkN(&anim_basepaths, ld); } /* free temp action too */ if (waction) { BKE_libblock_free(&G.main->action, waction); } } /* free the group tree (takes care of user count) */ BKE_libblock_free(&G.main->nodetree, wgroup); /* restore external links to and from the gnode */ /* note: the nodes have been copied to intermediate wgroup first (so need to use new_node), * then transferred to ntree (new_node pointers remain valid). */ /* input links */ for (link = ngroup->links.first; link; link = link->next) { if (link->fromnode->type == NODE_GROUP_INPUT) { const char *identifier = link->fromsock->identifier; int num_external_links = 0; /* find external links to this input */ for (tlink = ntree->links.first; tlink; tlink = tlink->next) { if (tlink->tonode == gnode && STREQ(tlink->tosock->identifier, identifier)) { nodeAddLink(ntree, tlink->fromnode, tlink->fromsock, link->tonode->new_node, link->tosock->new_sock); ++num_external_links; } } /* if group output is not externally linked, * convert the constant input value to ensure somewhat consistent behavior */ if (num_external_links == 0) { /* XXX TODO bNodeSocket *sock = node_group_find_input_socket(gnode, identifier); BLI_assert(sock);*/ /* XXX TODO nodeSocketCopy(ntree, link->tosock->new_sock, link->tonode->new_node, ntree, sock, gnode);*/ } } } /* output links */ for (link = ntree->links.first; link; link = link->next) { if (link->fromnode == gnode) { const char *identifier = link->fromsock->identifier; int num_internal_links = 0; /* find internal links to this output */ for (tlink = ngroup->links.first; tlink; tlink = tlink->next) { /* only use active output node */ if (tlink->tonode->type == NODE_GROUP_OUTPUT && (tlink->tonode->flag & NODE_DO_OUTPUT)) { if (STREQ(tlink->tosock->identifier, identifier)) { nodeAddLink(ntree, tlink->fromnode->new_node, tlink->fromsock->new_sock, link->tonode, link->tosock); ++num_internal_links; } } } /* if group output is not internally linked, * convert the constant output value to ensure somewhat consistent behavior */ if (num_internal_links == 0) { /* XXX TODO bNodeSocket *sock = node_group_find_output_socket(gnode, identifier); BLI_assert(sock);*/ /* XXX TODO nodeSocketCopy(ntree, link->tosock, link->tonode, ntree, sock, gnode); */ } } } /* delete the group instance */ nodeFreeNode(ntree, gnode); ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; return 1; }
/** * Update defaults in startup.blend, without having to save and embed the file. * This function can be emptied each time the startup.blend is updated. */ void BLO_update_defaults_startup_blend(Main *bmain) { for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { scene->r.im_format.planes = R_IMF_PLANES_RGBA; scene->r.im_format.compress = 15; for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) { srl->freestyleConfig.sphere_radius = 0.1f; srl->pass_alpha_threshold = 0.5f; } if (scene->toolsettings) { ToolSettings *ts = scene->toolsettings; if (ts->sculpt) { Sculpt *sculpt = ts->sculpt; sculpt->paint.symmetry_flags |= PAINT_SYMM_X; sculpt->flags |= SCULPT_DYNTOPO_COLLAPSE; sculpt->detail_size = 12; } if (ts->gp_sculpt.brush[0].size == 0) { GP_BrushEdit_Settings *gset = &ts->gp_sculpt; GP_EditBrush_Data *brush; brush = &gset->brush[GP_EDITBRUSH_TYPE_SMOOTH]; brush->size = 25; brush->strength = 0.3f; brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE; brush = &gset->brush[GP_EDITBRUSH_TYPE_THICKNESS]; brush->size = 25; brush->strength = 0.5f; brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; brush = &gset->brush[GP_EDITBRUSH_TYPE_STRENGTH]; brush->size = 25; brush->strength = 0.5f; brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; brush = &gset->brush[GP_EDITBRUSH_TYPE_GRAB]; brush->size = 50; brush->strength = 0.3f; brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; brush = &gset->brush[GP_EDITBRUSH_TYPE_PUSH]; brush->size = 25; brush->strength = 0.3f; brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; brush = &gset->brush[GP_EDITBRUSH_TYPE_TWIST]; brush->size = 50; brush->strength = 0.3f; // XXX? brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; brush = &gset->brush[GP_EDITBRUSH_TYPE_PINCH]; brush->size = 50; brush->strength = 0.5f; // XXX? brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; brush = &gset->brush[GP_EDITBRUSH_TYPE_RANDOMIZE]; brush->size = 25; brush->strength = 0.5f; brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; } ts->gpencil_v3d_align = GP_PROJECT_VIEWSPACE; ts->gpencil_v2d_align = GP_PROJECT_VIEWSPACE; ts->gpencil_seq_align = GP_PROJECT_VIEWSPACE; ts->gpencil_ima_align = GP_PROJECT_VIEWSPACE; ParticleEditSettings *pset = &ts->particle; for (int a = 0; a < PE_TOT_BRUSH; a++) { pset->brush[a].strength = 0.5f; } pset->brush[PE_BRUSH_CUT].strength = 1.0f; } scene->gm.lodflag |= SCE_LOD_USE_HYST; scene->gm.scehysteresis = 10; scene->r.ffcodecdata.audio_mixrate = 48000; } for (FreestyleLineStyle *linestyle = bmain->linestyle.first; linestyle; linestyle = linestyle->id.next) { linestyle->flag = LS_SAME_OBJECT | LS_NO_SORTING | LS_TEXTURE; linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA; linestyle->integration_type = LS_INTEGRATION_MEAN; linestyle->texstep = 1.0; linestyle->chain_count = 10; } for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { ScrArea *area; for (area = screen->areabase.first; area; area = area->next) { SpaceLink *space_link; ARegion *ar; for (space_link = area->spacedata.first; space_link; space_link = space_link->next) { if (space_link->spacetype == SPACE_CLIP) { SpaceClip *space_clip = (SpaceClip *) space_link; space_clip->flag &= ~SC_MANUAL_CALIBRATION; } } for (ar = area->regionbase.first; ar; ar = ar->next) { /* Remove all stored panels, we want to use defaults (order, open/closed) as defined by UI code here! */ BLI_freelistN(&ar->panels); /* some toolbars have been saved as initialized, * we don't want them to have odd zoom-level or scrolling set, see: T47047 */ if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS)) { ar->v2d.flag &= ~V2D_IS_INITIALISED; } } } } for (Mesh *me = bmain->mesh.first; me; me = me->id.next) { me->smoothresh = DEG2RADF(180.0f); me->flag &= ~ME_TWOSIDED; } for (Material *mat = bmain->mat.first; mat; mat = mat->id.next) { mat->line_col[0] = mat->line_col[1] = mat->line_col[2] = 0.0f; mat->line_col[3] = 1.0f; } { Object *ob; ob = (Object *)BKE_libblock_find_name_ex(bmain, ID_OB, "Camera"); if (ob) { ob->rot[1] = 0.0f; } } { Brush *br; br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Fill"); if (!br) { br = BKE_brush_add(bmain, "Fill", OB_MODE_TEXTURE_PAINT); br->imagepaint_tool = PAINT_TOOL_FILL; br->ob_mode = OB_MODE_TEXTURE_PAINT; } br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Mask"); if (br) { br->imagepaint_tool = PAINT_TOOL_MASK; br->ob_mode |= OB_MODE_TEXTURE_PAINT; } /* remove polish brush (flatten/contrast does the same) */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Polish"); if (br) { BKE_libblock_free(bmain, br); } /* remove brush brush (huh?) from some modes (draw brushes do the same) */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Brush"); if (br) { BKE_libblock_free(bmain, br); } /* remove draw brush from texpaint (draw brushes do the same) */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Draw"); if (br) { br->ob_mode &= ~OB_MODE_TEXTURE_PAINT; } /* rename twist brush to rotate brush to match rotate tool */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Twist"); if (br) { BKE_libblock_rename(bmain, &br->id, "Rotate"); } /* use original normal for grab brush (otherwise flickers with normal weighting). */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Grab"); if (br) { br->flag |= BRUSH_ORIGINAL_NORMAL; } /* increase strength, better for smoothing method */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Blur"); if (br) { br->alpha = 1.0f; } br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Flatten/Contrast"); if (br) { br->flag |= BRUSH_ACCUMULATE; } } }
/** * Update defaults in startup.blend, without having to save and embed the file. * This function can be emptied each time the startup.blend is updated. */ void BLO_update_defaults_startup_blend(Main *bmain) { Scene *scene; SceneRenderLayer *srl; FreestyleLineStyle *linestyle; Mesh *me; Material *mat; for (scene = bmain->scene.first; scene; scene = scene->id.next) { scene->r.im_format.planes = R_IMF_PLANES_RGBA; scene->r.im_format.compress = 15; for (srl = scene->r.layers.first; srl; srl = srl->next) { srl->freestyleConfig.sphere_radius = 0.1f; srl->pass_alpha_threshold = 0.5f; } if (scene->toolsettings) { ToolSettings *ts = scene->toolsettings; if (ts->sculpt) { Sculpt *sculpt = ts->sculpt; sculpt->paint.symmetry_flags |= PAINT_SYMM_X; sculpt->flags |= SCULPT_DYNTOPO_COLLAPSE; sculpt->detail_size = 12; } } scene->gm.lodflag |= SCE_LOD_USE_HYST; scene->gm.scehysteresis = 10; } for (linestyle = bmain->linestyle.first; linestyle; linestyle = linestyle->id.next) { linestyle->flag = LS_SAME_OBJECT | LS_NO_SORTING | LS_TEXTURE; linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA; linestyle->integration_type = LS_INTEGRATION_MEAN; linestyle->texstep = 1.0; linestyle->chain_count = 10; } { bScreen *screen; for (screen = bmain->screen.first; screen; screen = screen->id.next) { ScrArea *area; for (area = screen->areabase.first; area; area = area->next) { SpaceLink *space_link; ARegion *ar; for (space_link = area->spacedata.first; space_link; space_link = space_link->next) { if (space_link->spacetype == SPACE_CLIP) { SpaceClip *space_clip = (SpaceClip *) space_link; space_clip->flag &= ~SC_MANUAL_CALIBRATION; } } for (ar = area->regionbase.first; ar; ar = ar->next) { /* Remove all stored panels, we want to use defaults (order, open/closed) as defined by UI code here! */ BLI_freelistN(&ar->panels); /* simple fix for 3d view properties scrollbar being not set to top */ if (ar->regiontype == RGN_TYPE_UI) { ar->v2d.cur.ymax = ar->v2d.tot.ymax; ar->v2d.cur.ymin = ar->v2d.cur.ymax - ar->winy; } } } } } for (me = bmain->mesh.first; me; me = me->id.next) { me->smoothresh = DEG2RADF(180.0f); me->flag &= ~ME_TWOSIDED; } for (mat = bmain->mat.first; mat; mat = mat->id.next) { mat->line_col[0] = mat->line_col[1] = mat->line_col[2] = 0.0f; mat->line_col[3] = 1.0f; } { Brush *br; br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Fill"); if (!br) { br = BKE_brush_add(bmain, "Fill"); br->imagepaint_tool = PAINT_TOOL_FILL; br->ob_mode = OB_MODE_TEXTURE_PAINT; } br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Mask"); if (br) { br->imagepaint_tool = PAINT_TOOL_MASK; br->ob_mode |= OB_MODE_TEXTURE_PAINT; } /* remove polish brush (flatten/contrast does the same) */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Polish"); if (br) { BKE_libblock_free(bmain, br); } /* remove brush brush (huh?) from some modes (draw brushes do the same) */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Brush"); if (br) { BKE_libblock_free(bmain, br); } /* remove draw brush from texpaint (draw brushes do the same) */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Draw"); if (br) { br->ob_mode &= ~OB_MODE_TEXTURE_PAINT; } } }
bool BL_Action::Play(const std::string& name, float start, float end, short priority, float blendin, short play_mode, float layer_weight, short ipo_flags, float playback_speed, short blend_mode) { // Only start playing a new action if we're done, or if // the new action has a higher priority if (!IsDone() && priority > m_priority) return false; m_priority = priority; bAction* prev_action = m_action; KX_Scene* kxscene = m_obj->GetScene(); // First try to load the action m_action = (bAction*)kxscene->GetLogicManager()->GetActionByName(name); if (!m_action) { CM_Error("failed to load action: " << name); m_done = true; return false; } // If we have the same settings, don't play again // This is to resolve potential issues with pulses on sensors such as the ones // reported in bug #29412. The fix is here so it works for both logic bricks and Python. // However, this may eventually lead to issues where a user wants to override an already // playing action with the same action and settings. If this becomes an issue, // then this fix may have to be re-evaluated. if (!IsDone() && m_action == prev_action && m_startframe == start && m_endframe == end && m_priority == priority && m_speed == playback_speed) return false; // Keep a copy of the action for threading purposes if (m_tmpaction) { BKE_libblock_free(G.main, m_tmpaction); m_tmpaction = NULL; } m_tmpaction = BKE_action_copy(G.main, m_action); // First get rid of any old controllers ClearControllerList(); // Create an SG_Controller SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, kxscene->GetSceneConverter()); m_sg_contr_list.push_back(sg_contr); m_obj->GetSGNode()->AddSGController(sg_contr); sg_contr->SetObject(m_obj->GetSGNode()); // World sg_contr = BL_CreateWorldIPO(m_action, kxscene->GetBlenderScene()->world, kxscene->GetSceneConverter()); if (sg_contr) { m_sg_contr_list.push_back(sg_contr); m_obj->GetSGNode()->AddSGController(sg_contr); sg_contr->SetObject(m_obj->GetSGNode()); } // Try obcolor sg_contr = BL_CreateObColorIPO(m_action, m_obj, kxscene->GetSceneConverter()); if (sg_contr) { m_sg_contr_list.push_back(sg_contr); m_obj->GetSGNode()->AddSGController(sg_contr); sg_contr->SetObject(m_obj->GetSGNode()); } // Now try materials for (int matidx = 1; matidx <= m_obj->GetBlenderObject()->totcol; ++matidx) { Material *mat = give_current_material(m_obj->GetBlenderObject(), matidx); if (!mat) { continue; } KX_BlenderSceneConverter *converter = kxscene->GetSceneConverter(); RAS_IPolyMaterial *polymat = converter->FindCachedPolyMaterial(kxscene, mat); if (!polymat) { continue; } sg_contr = BL_CreateMaterialIpo(m_action, mat, polymat, m_obj, converter); if (sg_contr) { m_sg_contr_list.push_back(sg_contr); m_obj->GetSGNode()->AddSGController(sg_contr); sg_contr->SetObject(m_obj->GetSGNode()); } } // Extra controllers if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT) { sg_contr = BL_CreateLampIPO(m_action, m_obj, kxscene->GetSceneConverter()); m_sg_contr_list.push_back(sg_contr); m_obj->GetSGNode()->AddSGController(sg_contr); sg_contr->SetObject(m_obj->GetSGNode()); } else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA) { sg_contr = BL_CreateCameraIPO(m_action, m_obj, kxscene->GetSceneConverter()); m_sg_contr_list.push_back(sg_contr); m_obj->GetSGNode()->AddSGController(sg_contr); sg_contr->SetObject(m_obj->GetSGNode()); } m_ipo_flags = ipo_flags; InitIPO(); // Setup blendin shapes/poses if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) { BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj; obj->GetPose(&m_blendinpose); } else { BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj; BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer()); if (shape_deformer && shape_deformer->GetKey()) { obj->GetShape(m_blendinshape); // Now that we have the previous blend shape saved, we can clear out the key to avoid any // further interference. KeyBlock *kb; for (kb=(KeyBlock *)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock *)kb->next) kb->curval = 0.f; } } // Now that we have an action, we have something we can play m_starttime = KX_GetActiveEngine()->GetFrameTime() - kxscene->getSuspendedDelta(); m_startframe = m_localframe = start; m_endframe = end; m_blendin = blendin; m_playmode = play_mode; m_blendmode = blend_mode; m_blendframe = 0.f; m_blendstart = 0.f; m_speed = playback_speed; m_layer_weight = layer_weight; m_done = false; m_appliedToObject = false; m_prevUpdate = -1.0f; return true; }
void free_main(Main *mainvar) { /* also call when reading a file, erase all, etc */ ListBase *lbarray[MAX_LIBARRAY]; int a; a = set_listbasepointers(mainvar, lbarray); while (a--) { ListBase *lb = lbarray[a]; ID *id; while ( (id = lb->first) ) { #if 1 BKE_libblock_free(lb, id); #else /* errors freeing ID's can be hard to track down, * enable this so valgrind will give the line number in its error log */ switch (a) { case 0: BKE_libblock_free(lb, id); break; case 1: BKE_libblock_free(lb, id); break; case 2: BKE_libblock_free(lb, id); break; case 3: BKE_libblock_free(lb, id); break; case 4: BKE_libblock_free(lb, id); break; case 5: BKE_libblock_free(lb, id); break; case 6: BKE_libblock_free(lb, id); break; case 7: BKE_libblock_free(lb, id); break; case 8: BKE_libblock_free(lb, id); break; case 9: BKE_libblock_free(lb, id); break; case 10: BKE_libblock_free(lb, id); break; case 11: BKE_libblock_free(lb, id); break; case 12: BKE_libblock_free(lb, id); break; case 13: BKE_libblock_free(lb, id); break; case 14: BKE_libblock_free(lb, id); break; case 15: BKE_libblock_free(lb, id); break; case 16: BKE_libblock_free(lb, id); break; case 17: BKE_libblock_free(lb, id); break; case 18: BKE_libblock_free(lb, id); break; case 19: BKE_libblock_free(lb, id); break; case 20: BKE_libblock_free(lb, id); break; case 21: BKE_libblock_free(lb, id); break; case 22: BKE_libblock_free(lb, id); break; case 23: BKE_libblock_free(lb, id); break; case 24: BKE_libblock_free(lb, id); break; case 25: BKE_libblock_free(lb, id); break; case 26: BKE_libblock_free(lb, id); break; case 27: BKE_libblock_free(lb, id); break; case 28: BKE_libblock_free(lb, id); break; case 29: BKE_libblock_free(lb, id); break; case 30: BKE_libblock_free(lb, id); break; case 31: BKE_libblock_free(lb, id); break; case 32: BKE_libblock_free(lb, id); break; default: BLI_assert(0); break; } #endif } } MEM_freeN(mainvar); }
Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, bool isController, std::map<COLLADAFW::UniqueId, Material *>& uid_material_map, std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map) { const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId(); // check if node instanciates controller or geometry if (isController) { geom_uid = armature_importer->get_geometry_uid(*geom_uid); if (!geom_uid) { fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n"); return NULL; } } else { if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) { // this could happen if a mesh was not created // (e.g. if it contains unsupported geometry) fprintf(stderr, "Couldn't find a mesh by UID.\n"); return NULL; } } if (!uid_mesh_map[*geom_uid]) return NULL; // name Object const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId(); const char *name = (id.length()) ? id.c_str() : NULL; // add object Object *ob = bc_add_object(scene, OB_MESH, name); bc_set_mark(ob); // used later for material assignement optimization // store object pointer for ArmatureImporter uid_object_map[*geom_uid] = ob; imported_objects.push_back(ob); // replace ob->data freeing the old one Mesh *old_mesh = (Mesh *)ob->data; Mesh *new_mesh = uid_mesh_map[*geom_uid]; BKE_mesh_assign_object(ob, new_mesh); BKE_mesh_calc_normals(new_mesh); if (old_mesh->id.us == 0) BKE_libblock_free(G.main, old_mesh); char layername[100]; layername[0] = '\0'; MTFace *texture_face = NULL; COLLADAFW::MaterialBindingArray& mat_array = geom->getMaterialBindings(); // loop through geom's materials for (unsigned int i = 0; i < mat_array.getCount(); i++) { if (mat_array[i].getReferencedMaterial().isValid()) { texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid, layername, texture_face, material_texture_mapping_map, i); } else { fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str()); } } return ob; }