void ED_preview_free_dbase(void) { if (G_pr_main) free_main(G_pr_main); if (G_pr_main_cycles) free_main(G_pr_main_cycles); }
static void render_endjob(void *rjv) { RenderJob *rj= rjv; /* this render may be used again by the sequencer without the active 'Render' where the callbacks * would be re-assigned. assign dummy callbacks to avoid referencing freed renderjobs bug [#24508] */ RE_InitRenderCB(rj->re); if(rj->main != G.main) free_main(rj->main); /* else the frame will not update for the original value */ if(!(rj->scene->r.scemode & R_NO_FRAME_UPDATE)) ED_update_for_newframe(G.main, rj->scene, rj->win->screen, 1); /* XXX above function sets all tags in nodes */ ntreeClearTags(rj->scene->nodetree); /* potentially set by caller */ rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE; if(rj->srl) { NodeTagIDChanged(rj->scene->nodetree, &rj->scene->id); WM_main_add_notifier(NC_NODE|NA_EDITED, rj->scene); } /* XXX render stability hack */ G.rendering = 0; WM_main_add_notifier(NC_WINDOW, NULL); }
int BKE_read_file(bContext *C, const char *filepath, ReportList *reports) { BlendFileData *bfd; int retval = BKE_READ_FILE_OK; if (strstr(filepath, BLENDER_STARTUP_FILE) == NULL) /* don't print user-pref loading */ printf("read blend: %s\n", filepath); bfd = BLO_read_from_file(filepath, reports); if (bfd) { if (bfd->user) retval = BKE_READ_FILE_OK_USERPREFS; if (0 == handle_subversion_warning(bfd->main, reports)) { free_main(bfd->main); MEM_freeN(bfd); bfd = NULL; retval = BKE_READ_FILE_FAIL; } else setup_app_data(C, bfd, filepath); // frees BFD } else BKE_reports_prependf(reports, "Loading '%s' failed: ", filepath); return (bfd ? retval : BKE_READ_FILE_FAIL); }
static void clear_global(void) { // extern short winqueue_break; /* screen.c */ free_main(G.main); /* free all lib data */ // free_vertexpaint(); G.main = NULL; }
KX_BlenderSceneConverter::~KX_BlenderSceneConverter() { // clears meshes, and hashmaps from blender to gameengine data int i; // delete sumoshapes int numAdtLists = m_map_blender_to_gameAdtList.size(); for (i=0; i<numAdtLists; i++) { BL_InterpolatorList *adtList= *m_map_blender_to_gameAdtList.at(i); delete (adtList); } vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itw = m_worldinfos.begin(); while (itw != m_worldinfos.end()) { delete (*itw).second; itw++; } vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin(); while (itp != m_polymaterials.end()) { delete (*itp).second; itp++; } // delete after RAS_IPolyMaterial vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin(); while (itmat != m_materials.end()) { delete (*itmat).second; itmat++; } vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itm = m_meshobjects.begin(); while (itm != m_meshobjects.end()) { delete (*itm).second; itm++; } #ifdef USE_BULLET KX_ClearBulletSharedShapes(); #endif /* free any data that was dynamically loaded */ for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) { Main *main= *it; free_main(main); } m_DynamicMaggie.clear(); }
/* only to be called on exit blender */ void free_blender(void) { /* samples are in a global list..., also sets G.main->sound->sample NULL */ free_main(G.main); G.main= NULL; BKE_spacetypes_free(); /* after free main, it uses space callbacks */ IMB_exit(); BLI_cb_finalize(); seq_stripelem_cache_destruct(); free_nodesystem(); }
int main (int argc, char **argv) { struct main_pars pars = init_main_pars(argc, argv); COND_VAR_INIT(sync_barrier); MUTEX_INIT(main_lock); TRACE_INIT(); run_main(pars); free_main(pars); TRACE_END(); return 0; }
/* only read the userdef from a .blend */ int BKE_read_file_userdef(const char *filepath, ReportList *reports) { BlendFileData *bfd; int retval = 0; bfd = BLO_read_from_file(filepath, reports); if (bfd->user) { retval = BKE_READ_FILE_OK_USERPREFS; /* only here free userdef themes... */ BKE_userdef_free(); U = *bfd->user; MEM_freeN(bfd->user); } free_main(bfd->main); MEM_freeN(bfd); return retval; }
static void render_endjob(void *rjv) { RenderJob *rj = rjv; /* this render may be used again by the sequencer without the active 'Render' where the callbacks * would be re-assigned. assign dummy callbacks to avoid referencing freed renderjobs bug [#24508] */ RE_InitRenderCB(rj->re); if (rj->main != G.main) free_main(rj->main); /* else the frame will not update for the original value */ if (rj->anim && !(rj->scene->r.scemode & R_NO_FRAME_UPDATE)) { /* possible this fails of loading new file while rendering */ if (G.main->wm.first) { ED_update_for_newframe(G.main, rj->scene, 1); } } /* XXX above function sets all tags in nodes */ ntreeCompositClearTags(rj->scene->nodetree); /* potentially set by caller */ rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE; if (rj->srl) { nodeUpdateID(rj->scene->nodetree, &rj->scene->id); WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene); } /* XXX render stability hack */ G.is_rendering = FALSE; WM_main_add_notifier(NC_SCENE | ND_RENDER_RESULT, NULL); /* Partial render result will always update display buffer * for first render layer only. This is nice because you'll * see render progress during rendering, but it ends up in * wrong display buffer shown after rendering. * * The code below will mark display buffer as invalid after * rendering in case multiple layers were rendered, which * ensures display buffer matches render layer after * rendering. * * Perhaps proper way would be to toggle active render * layer in image editor and job, so we always display * layer being currently rendered. But this is not so much * trivial at this moment, especially because of external * engine API, so lets use simple and robust way for now * - sergey - */ if (rj->scene->r.layers.first != rj->scene->r.layers.last) { void *lock; Image *ima = rj->image; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock); if (ibuf) ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; BKE_image_release_ibuf(ima, ibuf, lock); } }
void ED_preview_free_dbase(void) { if(pr_main) free_main(pr_main); }
/* Note m_map_*** are all ok and don't need to be freed * most are temp and NewRemoveObject frees m_map_gameobject_to_blender */ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie) { int maggie_index= -1; int i=0; if (maggie==NULL) return false; /* tag all false except the one we remove */ for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) { Main *main= *it; if (main != maggie) { tag_main(main, 0); } else { maggie_index= i; } i++; } /* should never happen but just to be safe */ if (maggie_index == -1) return false; m_DynamicMaggie.erase(m_DynamicMaggie.begin() + maggie_index); tag_main(maggie, 1); /* free all tagged objects */ KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); int numScenes = scenes->size(); for (int scene_idx=0;scene_idx<numScenes;scene_idx++) { KX_Scene* scene = scenes->at(scene_idx); if (IS_TAGGED(scene->GetBlenderScene())) { RemoveScene(scene); // XXX - not tested yet scene_idx--; numScenes--; } else { /* in case the mesh might be refered to later */ { CTR_Map<STR_HashedString,void*> &mapStringToMeshes = scene->GetLogicManager()->GetMeshMap(); for (int i=0; i<mapStringToMeshes.size(); i++) { RAS_MeshObject *meshobj= (RAS_MeshObject *) *mapStringToMeshes.at(i); if (meshobj && IS_TAGGED(meshobj->GetMesh())) { STR_HashedString mn = meshobj->GetName(); mapStringToMeshes.remove(mn); m_map_mesh_to_gamemesh.remove(CHashedPtr(meshobj->GetMesh())); i--; } } } /* Now unregister actions */ { CTR_Map<STR_HashedString,void*> &mapStringToActions = scene->GetLogicManager()->GetActionMap(); for (int i=0; i<mapStringToActions.size(); i++) { ID *action= (ID*) *mapStringToActions.at(i); if (IS_TAGGED(action)) { STR_HashedString an = action->name+2; mapStringToActions.remove(an); i--; } } } //scene->FreeTagged(); /* removed tagged objects and meshes*/ CListValue *obj_lists[] = {scene->GetObjectList(), scene->GetInactiveList(), NULL}; for (int ob_ls_idx=0; obj_lists[ob_ls_idx]; ob_ls_idx++) { CListValue *obs= obj_lists[ob_ls_idx]; RAS_MeshObject* mesh; for (int ob_idx = 0; ob_idx < obs->GetCount(); ob_idx++) { KX_GameObject* gameobj = (KX_GameObject*)obs->GetValue(ob_idx); if (IS_TAGGED(gameobj->GetBlenderObject())) { int size_before = obs->GetCount(); /* Eventually calls RemoveNodeDestructObject * frees m_map_gameobject_to_blender from UnregisterGameObject */ scene->RemoveObject(gameobj); if (size_before != obs->GetCount()) ob_idx--; else { printf("ERROR COULD NOT REMOVE \"%s\"\n", gameobj->GetName().ReadPtr()); } } else { /* free the mesh, we could be referecing a linked one! */ int mesh_index= gameobj->GetMeshCount(); while(mesh_index--) { mesh= gameobj->GetMesh(mesh_index); if (IS_TAGGED(mesh->GetMesh())) { gameobj->RemoveMeshes(); /* XXX - slack, should only remove meshes that are library items but mostly objects only have 1 mesh */ break; } } /* make sure action actuators are not referencing tagged actions */ for (unsigned int act_idx=0; act_idx<gameobj->GetActuators().size(); act_idx++) { if (gameobj->GetActuators()[act_idx]->IsType(SCA_IActuator::KX_ACT_ACTION)) { BL_ActionActuator *act = (BL_ActionActuator*)gameobj->GetActuators()[act_idx]; if (IS_TAGGED(act->GetAction())) act->SetAction(NULL); } } } } } } } int size; // delete the entities of this scene /* TODO - */ #if 0 vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit; size = m_worldinfos.size(); for (i=0, worldit=m_worldinfos.begin(); i<size; ) { if ((*worldit).second) { delete (*worldit).second; *worldit = m_worldinfos.back(); m_worldinfos.pop_back(); size--; } else { i++; worldit++; } } #endif /* Worlds don't reference original blender data so we need to make a set from them */ typedef std::set<KX_WorldInfo*> KX_WorldInfoSet; KX_WorldInfoSet worldset; for (int scene_idx=0;scene_idx<numScenes;scene_idx++) { KX_Scene* scene = scenes->at(scene_idx); if (scene->GetWorldInfo()) worldset.insert( scene->GetWorldInfo() ); } vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit; size = m_worldinfos.size(); for (i=0, worldit=m_worldinfos.begin(); i<size; ) { if ((*worldit).second && (worldset.count((*worldit).second)) == 0) { delete (*worldit).second; *worldit = m_worldinfos.back(); m_worldinfos.pop_back(); size--; } else { i++; worldit++; } } worldset.clear(); /* done freeing the worlds */ vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit; size = m_polymaterials.size(); for (i=0, polymit=m_polymaterials.begin(); i<size; ) { RAS_IPolyMaterial *mat= (*polymit).second; Material *bmat= NULL; /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */ if (mat->GetFlag() & RAS_BLENDERMAT) { KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat); bmat= bl_mat->GetBlenderMaterial(); } else { KX_PolygonMaterial *kx_mat = static_cast<KX_PolygonMaterial*>(mat); bmat= kx_mat->GetBlenderMaterial(); } if (IS_TAGGED(bmat)) { /* only remove from bucket */ ((*polymit).first)->GetBucketManager()->RemoveMaterial(mat); } i++; polymit++; } for (i=0, polymit=m_polymaterials.begin(); i<size; ) { RAS_IPolyMaterial *mat= (*polymit).second; Material *bmat= NULL; /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */ if (mat->GetFlag() & RAS_BLENDERMAT) { KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat); bmat= bl_mat->GetBlenderMaterial(); } else { KX_PolygonMaterial *kx_mat = static_cast<KX_PolygonMaterial*>(mat); bmat= kx_mat->GetBlenderMaterial(); } if (bmat) { //printf("FOUND MAT '%s' !!! ", ((ID*)bmat)->name+2); } else { //printf("LOST MAT !!!"); } if (IS_TAGGED(bmat)) { delete (*polymit).second; *polymit = m_polymaterials.back(); m_polymaterials.pop_back(); size--; //printf("tagged !\n"); } else { i++; polymit++; //printf("(un)tagged !\n"); } } vector<pair<KX_Scene*,BL_Material*> >::iterator matit; size = m_materials.size(); for (i=0, matit=m_materials.begin(); i<size; ) { BL_Material *mat= (*matit).second; if (IS_TAGGED(mat->material)) { delete (*matit).second; *matit = m_materials.back(); m_materials.pop_back(); size--; } else { i++; matit++; } } vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit; size = m_meshobjects.size(); for (i=0, meshit=m_meshobjects.begin(); i<size; ) { RAS_MeshObject *me= (*meshit).second; if (IS_TAGGED(me->GetMesh())) { delete (*meshit).second; *meshit = m_meshobjects.back(); m_meshobjects.pop_back(); size--; } else { i++; meshit++; } } free_main(maggie); return true; }
int main(int argc, char** argv) { int i; int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */ bool error = false; SYS_SystemHandle syshandle = SYS_GetSystem(); bool fullScreen = false; bool fullScreenParFound = false; bool windowParFound = false; #ifdef WIN32 bool closeConsole = true; #endif RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO; bool stereoWindow = false; bool stereoParFound = false; int stereoFlag = STEREO_NOSTEREO; int domeFov = -1; int domeTilt = -200; int domeMode = 0; char* domeWarp = NULL; Text *domeText = NULL; int windowLeft = 100; int windowTop = 100; int windowWidth = 640; int windowHeight = 480; GHOST_TUns32 fullScreenWidth = 0; GHOST_TUns32 fullScreenHeight= 0; int fullScreenBpp = 32; int fullScreenFrequency = 60; GHOST_TEmbedderWindowID parentWindow = 0; bool isBlenderPlayer = false; int validArguments=0; GHOST_TUns16 aasamples = 0; #ifdef __linux__ #ifdef __alpha__ signal (SIGFPE, SIG_IGN); #endif /* __alpha__ */ #endif /* __linux__ */ BLI_where_am_i(bprogname, sizeof(bprogname), argv[0]); #ifdef __APPLE__ // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh) /* IBNibRef nibRef; WindowRef window; OSStatus err; // Create a Nib reference passing the name of the nib file (without the .nib extension) // CreateNibReference only searches into the application bundle. err = ::CreateNibReference(CFSTR("main"), &nibRef); if (err) return -1; // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar // object. This name is set in InterfaceBuilder when the nib is created. err = ::SetMenuBarFromNib(nibRef, CFSTR("MenuBar")); if (err) return -1; // We don't need the nib reference anymore. ::DisposeNibReference(nibRef); */ #endif // __APPLE__ // We don't use threads directly in the BGE, but we need to call this so things like // freeing up GPU_Textures works correctly. BLI_threadapi_init(); RNA_init(); init_nodesystem(); initglobals(); // We load our own G.main, so free the one that initglobals() gives us free_main(G.main); G.main = NULL; IMB_init(); // Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c) BLF_init(11, U.dpi); BLF_lang_init(); BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size); // Parse command line options #if defined(DEBUG) printf("argv[0] = '%s'\n", argv[0]); #endif #ifdef WIN32 if (scr_saver_init(argc, argv)) { switch (scr_saver_mode) { case SCREEN_SAVER_MODE_CONFIGURATION: MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK); break; case SCREEN_SAVER_MODE_PASSWORD: /* This is W95 only, which we currently do not support. Fall-back to normal screen saver behaviour in that case... */ case SCREEN_SAVER_MODE_SAVER: fullScreen = true; fullScreenParFound = true; break; case SCREEN_SAVER_MODE_PREVIEW: /* This will actually be handled somewhere below... */ break; } } #endif // XXX add the ability to change this values to the command line parsing. U.mixbufsize = 2048; U.audiodevice = 2; U.audiorate = 44100; U.audioformat = 0x24; U.audiochannels = 2; // XXX this one too U.anisotropic_filter = 2; sound_init_once(); /* if running blenderplayer the last argument can't be parsed since it has to be the filename. */ isBlenderPlayer = !BLO_is_a_runtime(argv[0]); if (isBlenderPlayer) validArguments = argc - 1; else validArguments = argc; for (i = 1; (i < validArguments) && !error #ifdef WIN32 && scr_saver_mode == SCREEN_SAVER_MODE_NONE #endif ;) { #if defined(DEBUG) printf("argv[%d] = '%s' , %i\n", i, argv[i],argc); #endif if (argv[i][0] == '-') { /* ignore all args after " - ", allow python to have own args */ if (argv[i][1]=='\0') { argc_py_clamped= i; break; } switch (argv[i][1]) { case 'g': // Parse game options { i++; if (i <= validArguments) { char* paramname = argv[i]; // Check for single value versus assignment if (i+1 <= validArguments && (*(argv[i+1]) == '=')) { i++; if (i + 1 <= validArguments) { i++; // Assignment SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i])); SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i])); SYS_WriteCommandLineString(syshandle, paramname, argv[i]); #if defined(DEBUG) printf("%s = '%s'\n", paramname, argv[i]); #endif i++; } else { error = true; printf("error: argument assignment %s without value.\n", paramname); } } else { // SYS_WriteCommandLineInt(syshandle, argv[i++], 1); } } } break; case 'd': i++; G.f |= G_DEBUG; /* std output printf's */ MEM_set_memory_debug(); break; case 'f': i++; fullScreen = true; fullScreenParFound = true; if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-') { fullScreenWidth = atoi(argv[i++]); fullScreenHeight = atoi(argv[i++]); if ((i + 1) <= validArguments && argv[i][0] != '-') { fullScreenBpp = atoi(argv[i++]); if ((i + 1) <= validArguments && argv[i][0] != '-') fullScreenFrequency = atoi(argv[i++]); } } break; case 'w': // Parse window position and size options i++; fullScreen = false; windowParFound = true; if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-') { windowWidth = atoi(argv[i++]); windowHeight = atoi(argv[i++]); if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-') { windowLeft = atoi(argv[i++]); windowTop = atoi(argv[i++]); } } break; case 'h': usage(argv[0], isBlenderPlayer); return 0; break; case 'i': i++; if ( (i + 1) <= validArguments ) parentWindow = atoi(argv[i++]); else { error = true; printf("error: too few options for parent window argument.\n"); } #if defined(DEBUG) printf("XWindows ID = %d\n", parentWindow); #endif // defined(DEBUG) break; case 'm': i++; if ((i+1) <= validArguments ) aasamples = atoi(argv[i++]); break; case 'c': i++; #ifdef WIN32 closeConsole = false; #endif break; case 's': // stereo i++; if ((i + 1) <= validArguments) { stereomode = (RAS_IRasterizer::StereoMode) atoi(argv[i]); if (stereomode < RAS_IRasterizer::RAS_STEREO_NOSTEREO || stereomode >= RAS_IRasterizer::RAS_STEREO_MAXSTEREO) stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO; if(!strcmp(argv[i], "nostereo")) // ok, redundant but clear stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO; // only the hardware pageflip method needs a stereo window else if(!strcmp(argv[i], "hwpageflip")) { stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED; stereoWindow = true; } else if(!strcmp(argv[i], "syncdoubling")) stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW; else if(!strcmp(argv[i], "anaglyph")) stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH; else if(!strcmp(argv[i], "sidebyside")) stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE; else if(!strcmp(argv[i], "vinterlace")) stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE; #if 0 // future stuff else if(!strcmp(argv[i], "stencil") stereomode = RAS_STEREO_STENCIL; #endif i++; stereoParFound = true; stereoFlag = STEREO_ENABLED; } else { error = true; printf("error: too few options for stereo argument.\n"); } break; case 'D': stereoFlag = STEREO_DOME; stereomode = RAS_IRasterizer::RAS_STEREO_DOME; i++; if ((i + 1) <= validArguments) { if(!strcmp(argv[i], "angle")) { i++; domeFov = atoi(argv[i++]); } if(!strcmp(argv[i], "tilt")) { i++; domeTilt = atoi(argv[i++]); } if(!strcmp(argv[i], "warpdata")) { i++; domeWarp = argv[i++]; } if(!strcmp(argv[i], "mode")) { i++; if(!strcmp(argv[i], "fisheye")) domeMode = DOME_FISHEYE; else if(!strcmp(argv[i], "truncatedfront")) domeMode = DOME_TRUNCATED_FRONT; else if(!strcmp(argv[i], "truncatedrear")) domeMode = DOME_TRUNCATED_REAR; else if(!strcmp(argv[i], "cubemap")) domeMode = DOME_ENVMAP; else if(!strcmp(argv[i], "sphericalpanoramic")) domeMode = DOME_PANORAM_SPH; else printf("error: %s is not a valid dome mode.\n", argv[i]); } i++; } break; default: printf("Unknown argument: %s\n", argv[i++]); break; } }