/** * \see #wm_file_write wraps #BLO_write_file in a similar way. */ int wm_homefile_write_exec(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); char filepath[FILE_MAX]; int fileflags; BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); /* check current window and close it if temp */ if (win && win->screen->temp) wm_window_close(C, wm, win); /* update keymaps in user preferences */ WM_keyconfig_update(wm); BLI_make_file_string("/", filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); printf("trying to save homefile at %s ", filepath); ED_editors_flush_edits(C, false); /* force save as regular blend file */ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_HISTORY); if (BLO_write_file(CTX_data_main(C), filepath, fileflags | G_FILE_USERPREFS, op->reports, NULL) == 0) { printf("fail\n"); return OPERATOR_CANCELLED; } printf("ok\n"); G.save_over = 0; BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_POST); return OPERATOR_FINISHED; }
static int flyEnd(bContext *C, FlyInfo *fly) { wmWindow *win; RegionView3D *rv3d; if (fly->state == FLY_RUNNING) return OPERATOR_RUNNING_MODAL; #ifdef NDOF_FLY_DEBUG puts("\n-- fly end --"); #endif win = CTX_wm_window(C); rv3d = fly->rv3d; WM_event_remove_timer(CTX_wm_manager(C), win, fly->timer); ED_region_draw_cb_exit(fly->ar->type, fly->draw_handle_pixel); ED_view3d_cameracontrol_release(fly->v3d_camera_control, fly->state == FLY_CANCEL); rv3d->rflag &= ~RV3D_NAVIGATING; #ifdef WITH_INPUT_NDOF if (fly->ndof) MEM_freeN(fly->ndof); #endif if (fly->state == FLY_CONFIRM) { MEM_freeN(fly); return OPERATOR_FINISHED; } MEM_freeN(fly); return OPERATOR_CANCELLED; }
static void view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); ViewZoomData *vpd; op->customdata = vpd = MEM_callocN(sizeof(ViewZoomData), "ClipViewZoomData"); WM_cursor_modal_set(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR); if (U.viewzoom == USER_ZOOM_CONT) { /* needs a timer to continue redrawing */ vpd->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f); vpd->timer_lastdraw = PIL_check_seconds_timer(); } vpd->x = event->x; vpd->y = event->y; vpd->zoom = sc->zoom; vpd->event_type = event->type; ED_clip_mouse_pos(sc, ar, event->mval, vpd->location); WM_event_add_modal_handler(C, op); }
static int node_group_edit_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); const char *node_idname = group_node_idname(C); bNode *gnode; const bool exit = RNA_boolean_get(op->ptr, "exit"); ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); gnode = node_group_get_active(C, node_idname); if (gnode && !exit) { bNodeTree *ngroup = (bNodeTree *)gnode->id; if (ngroup) ED_node_tree_push(snode, ngroup, gnode); } else ED_node_tree_pop(snode); WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL); return OPERATOR_FINISHED; }
void ED_editors_init(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); Main *bmain = CTX_data_main(C); Scene *sce = CTX_data_scene(C); Object *ob, *obact = (sce && sce->basact) ? sce->basact->object : NULL; ID *data; /* This is called during initialization, so we don't want to store any reports */ ReportList *reports = CTX_wm_reports(C); int reports_flag_prev = reports->flag & ~RPT_STORE; SWAP(int, reports->flag, reports_flag_prev); /* toggle on modes for objects that were saved with these enabled. for * e.g. linked objects we have to ensure that they are actually the * active object in this scene. */ for (ob = bmain->object.first; ob; ob = ob->id.next) { int mode = ob->mode; if (!ELEM(mode, OB_MODE_OBJECT, OB_MODE_POSE)) { ob->mode = OB_MODE_OBJECT; data = ob->data; if (ob == obact && !ob->id.lib && !(data && data->lib)) ED_object_toggle_modes(C, mode); } } /* image editor paint mode */ if (sce) { ED_space_image_paint_update(wm, sce->toolsettings); } SWAP(int, reports->flag, reports_flag_prev); }
static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) { char newname[FILE_MAX + 12]; char orgname[FILE_MAX + 12]; char filename[FILE_MAX + 12]; wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C); ARegion *ar = CTX_wm_region(C); BLI_make_file_string(G.main->name, orgname, sfile->params->dir, oldname); BLI_strncpy(filename, sfile->params->renameedit, sizeof(filename)); BLI_filename_make_safe(filename); BLI_make_file_string(G.main->name, newname, sfile->params->dir, filename); if (!STREQ(orgname, newname)) { if (!BLI_exists(newname)) { BLI_rename(orgname, newname); /* to make sure we show what is on disk */ ED_fileselect_clear(wm, sfile); } ED_region_tag_redraw(ar); } }
void ED_preview_kill_jobs(const struct bContext *C) { wmWindowManager *wm= CTX_wm_manager(C); if(wm) WM_jobs_kill(wm, NULL, common_preview_startjob); }
/** * \note doesn't run exit() call #WM_exit() for that. */ void WM_exit_ext(bContext *C, const bool do_python) { wmWindowManager *wm = C ? CTX_wm_manager(C) : NULL; /* first wrap up running stuff, we assume only the active WM is running */ /* modal handlers are on window level freed, others too? */ /* note; same code copied in wm_files.c */ if (C && wm) { wmWindow *win; if (!G.background) { struct MemFile *undo_memfile = wm->undo_stack ? ED_undosys_stack_memfile_get_active(wm->undo_stack) : NULL; if ((U.uiflag2 & USER_KEEP_SESSION) || (undo_memfile != NULL)) { /* save the undo state as quit.blend */ char filename[FILE_MAX]; bool has_edited; int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_HISTORY); BLI_make_file_string("/", filename, BKE_tempdir_base(), BLENDER_QUIT_FILE); has_edited = ED_editors_flush_edits(C, false); if ((has_edited && BLO_write_file(CTX_data_main(C), filename, fileflags, NULL, NULL)) || (undo_memfile && BLO_memfile_write_file(undo_memfile, filename))) { printf("Saved session recovery to '%s'\n", filename); } } } WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { CTX_wm_window_set(C, win); /* needed by operator close callbacks */ WM_event_remove_handlers(C, &win->handlers); WM_event_remove_handlers(C, &win->modalhandlers); ED_screen_exit(C, win, win->screen); } } BKE_addon_pref_type_free(); wm_operatortype_free(); wm_dropbox_free(); WM_menutype_free(); WM_uilisttype_free(); /* all non-screen and non-space stuff editors did, like editmode */ if (C) ED_editors_exit(C); ED_undosys_type_free(); // XXX // BIF_GlobalReebFree(); // BIF_freeRetarget(); BIF_freeTemplates(C); free_openrecent(); BKE_mball_cubeTable_free(); /* render code might still access databases */ RE_FreeAllRender(); RE_engines_exit(); ED_preview_free_dbase(); /* frees a Main dbase, before BKE_blender_free! */ if (C && wm) wm_free_reports(C); /* before BKE_blender_free! - since the ListBases get freed there */ BKE_sequencer_free_clipboard(); /* sequencer.c */ BKE_tracking_clipboard_free(); BKE_mask_clipboard_free(); BKE_vfont_clipboard_free(); #ifdef WITH_COMPOSITOR COM_deinitialize(); #endif BKE_blender_free(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); ANIM_fcurves_copybuf_free(); ANIM_drivers_copybuf_free(); ANIM_driver_vars_copybuf_free(); ANIM_fmodifiers_copybuf_free(); ED_gpencil_anim_copybuf_free(); ED_gpencil_strokes_copybuf_free(); BKE_node_clipboard_clear(); BLF_exit(); #ifdef WITH_INTERNATIONAL BLF_free_unifont(); BLF_free_unifont_mono(); BLT_lang_free(); #endif ANIM_keyingset_infos_exit(); // free_txt_data(); #ifdef WITH_PYTHON /* option not to close python so we can use 'atexit' */ if (do_python && ((C == NULL) || CTX_py_init_get(C))) { /* XXX - old note */ /* before BKE_blender_free so py's gc happens while library still exists */ /* needed at least for a rare sigsegv that can happen in pydrivers */ /* Update for blender 2.5, move after BKE_blender_free because blender now holds references to PyObject's * so decref'ing them after python ends causes bad problems every time * the pyDriver bug can be fixed if it happens again we can deal with it then */ BPY_python_end(); } #else (void)do_python; #endif if (!G.background) { #ifdef WITH_OPENSUBDIV BKE_subsurf_osd_cleanup(); #endif GPU_global_buffer_pool_free(); GPU_free_unused_buffers(G_MAIN); GPU_exit(); } ED_file_exit(); /* for fsmenu */ UI_exit(); BKE_blender_userdef_data_free(&U, false); RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */ wm_ghost_exit(); CTX_free(C); #ifdef WITH_GAMEENGINE SYS_DeleteSystem(SYS_GetSystem()); #endif GHOST_DisposeSystemPaths(); DNA_sdna_current_free(); BLI_threadapi_exit(); /* No need to call this early, rather do it late so that other pieces of Blender using sound may exit cleanly, * see also T50676. */ BKE_sound_exit(); CLG_exit(); BKE_blender_atexit(); if (MEM_get_memory_blocks_in_use() != 0) { size_t mem_in_use = MEM_get_memory_in_use() + MEM_get_memory_in_use(); printf("Error: Not freed memory blocks: %u, total unfreed memory %f MB\n", MEM_get_memory_blocks_in_use(), (double)mem_in_use / 1024 / 1024); MEM_printmemlist(); } wm_autosave_delete(); BKE_tempdir_session_purge(); }
bool WM_init_game(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win; ScrArea *sa; ARegion *ar = NULL; Scene *scene = CTX_data_scene(C); if (!scene) { /* XXX, this should not be needed. */ Main *bmain = CTX_data_main(C); scene = bmain->scene.first; } win = wm->windows.first; /* first to get a valid window */ if (win) CTX_wm_window_set(C, win); sa = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0); ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); /* if we have a valid 3D view */ if (sa && ar) { ARegion *arhide; CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* disable quad view */ if (ar->alignment == RGN_ALIGN_QSPLIT) WM_operator_name_call(C, "SCREEN_OT_region_quadview", WM_OP_EXEC_DEFAULT, NULL); /* toolbox, properties panel and header are hidden */ for (arhide = sa->regionbase.first; arhide; arhide = arhide->next) { if (arhide->regiontype != RGN_TYPE_WINDOW) { if (!(arhide->flag & RGN_FLAG_HIDDEN)) { ED_region_toggle_hidden(C, arhide); } } } /* full screen the area */ if (!sa->full) { ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); } /* Fullscreen */ if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) { WM_operator_name_call(C, "WM_OT_window_fullscreen_toggle", WM_OP_EXEC_DEFAULT, NULL); wm_get_screensize(&ar->winrct.xmax, &ar->winrct.ymax); ar->winx = ar->winrct.xmax + 1; ar->winy = ar->winrct.ymax + 1; } else { GHOST_RectangleHandle rect = GHOST_GetClientBounds(win->ghostwin); ar->winrct.ymax = GHOST_GetHeightRectangle(rect); ar->winrct.xmax = GHOST_GetWidthRectangle(rect); ar->winx = ar->winrct.xmax + 1; ar->winy = ar->winrct.ymax + 1; GHOST_DisposeRectangle(rect); } WM_operator_name_call(C, "VIEW3D_OT_game_start", WM_OP_EXEC_DEFAULT, NULL); BKE_sound_exit(); return true; } else { ReportTimerInfo *rti; BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found, game auto start is not possible"); /* After adding the report to the global list, reset the report timer. */ WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); /* Records time since last report was added */ wm->reports.reporttimer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER, 0.02); rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo"); wm->reports.reporttimer->customdata = rti; return false; } }
/* only called once, for startup */ void WM_init(bContext *C, int argc, const char **argv) { if (!G.background) { wm_ghost_init(C); /* note: it assigns C to ghost! */ wm_init_cursor_data(); } GHOST_CreateSystemPaths(); BKE_addon_pref_type_init(); wm_operatortype_init(); wm_operatortypes_register(); WM_menutype_init(); WM_uilisttype_init(); ED_undosys_type_init(); BKE_library_callback_free_window_manager_set(wm_close_and_free); /* library.c */ BKE_library_callback_free_notifier_reference_set(WM_main_remove_notifier_reference); /* library.c */ BKE_library_callback_remap_editor_id_reference_set(WM_main_remap_editor_id_reference); /* library.c */ BKE_blender_callback_test_break_set(wm_window_testbreak); /* blender.c */ BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap); /* screen.c */ DAG_editors_update_cb(ED_render_id_flush_update, ED_render_scene_update, ED_render_scene_update_pre); /* depsgraph.c */ ED_spacetypes_init(); /* editors/space_api/spacetype.c */ ED_file_init(); /* for fsmenu */ ED_node_init_butfuncs(); BLF_init(); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */ BLT_lang_init(); /* Must call first before doing any .blend file reading, since versionning code may create new IDs... See T57066. */ BLT_lang_set(NULL); /* reports cant be initialized before the wm, * but keep before file reading, since that may report errors */ wm_init_reports(C); /* get the default database, plus a wm */ wm_homefile_read(C, NULL, G.factory_startup, false, true, NULL, WM_init_state_app_template_get()); /* Call again to set from userpreferences... */ BLT_lang_set(NULL); if (!G.background) { #ifdef WITH_INPUT_NDOF /* sets 3D mouse deadzone */ WM_ndof_deadzone_set(U.ndof_deadzone); #endif GPU_init(); GPU_set_mipmap(G_MAIN, !(U.gameflags & USER_DISABLE_MIPMAP)); GPU_set_linear_mipmap(true); GPU_set_anisotropic(G_MAIN, U.anisotropic_filter); GPU_set_gpu_mipmapping(G_MAIN, U.use_gpu_mipmap); #ifdef WITH_OPENSUBDIV BKE_subsurf_osd_init(); #endif UI_init(); } else { /* Note: Currently only inits icons, which we now want in background mode too * (scripts could use those in background processing...). * In case we do more later, we may need to pass a 'background' flag. * Called from 'UI_init' above */ BKE_icons_init(1); } ED_spacemacros_init(); /* note: there is a bug where python needs initializing before loading the * startup.blend because it may contain PyDrivers. It also needs to be after * initializing space types and other internal data. * * However cant redo this at the moment. Solution is to load python * before wm_homefile_read() or make py-drivers check if python is running. * Will try fix when the crash can be repeated. - campbell. */ #ifdef WITH_PYTHON BPY_context_set(C); /* necessary evil */ BPY_python_start(argc, argv); BPY_python_reset(C); #else (void)argc; /* unused */ (void)argv; /* unused */ #endif if (!G.background && !wm_start_with_console) GHOST_toggleConsole(3); clear_matcopybuf(); ED_render_clear_mtex_copybuf(); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); wm_history_file_read(); /* allow a path of "", this is what happens when making a new file */ #if 0 if (BKE_main_blendfile_path_from_global()[0] == '\0') BLI_make_file_string("/", G_MAIN->name, BKE_appdir_folder_default(), "untitled.blend"); #endif BLI_strncpy(G.lib, BKE_main_blendfile_path_from_global(), sizeof(G.lib)); #ifdef WITH_COMPOSITOR if (1) { extern void *COM_linker_hack; COM_linker_hack = COM_execute; } #endif /* load last session, uses regular file reading so it has to be in end (after init py etc) */ if (U.uiflag2 & USER_KEEP_SESSION) { /* calling WM_recover_last_session(C, NULL) has been moved to creator.c */ /* that prevents loading both the kept session, and the file on the command line */ } else { Main *bmain = CTX_data_main(C); /* note, logic here is from wm_file_read_post, * call functions that depend on Python being initialized. */ /* normally 'wm_homefile_read' will do this, * however python is not initialized when called from this function. * * unlikely any handlers are set but its possible, * note that recovering the last session does its own callbacks. */ CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); BLI_callback_exec(bmain, NULL, BLI_CB_EVT_VERSION_UPDATE); BLI_callback_exec(bmain, NULL, BLI_CB_EVT_LOAD_POST); wm_file_read_report(C, bmain); if (!G.background) { CTX_wm_window_set(C, NULL); } } }
/** * Logic shared between #WM_file_read & #wm_homefile_read, * updates to make after reading a file. */ static void wm_file_read_post(bContext *C, bool is_startup_file) { bool addons_loaded = false; wmWindowManager *wm = CTX_wm_manager(C); if (!G.background) { /* remove windows which failed to be added via WM_check */ wm_window_ghostwindows_remove_invalid(C, wm); } CTX_wm_window_set(C, wm->windows.first); ED_editors_init(C); DAG_on_visible_update(CTX_data_main(C), true); #ifdef WITH_PYTHON if (is_startup_file) { /* possible python hasn't been initialized */ if (CTX_py_init_get(C)) { /* sync addons, these may have changed from the defaults */ BPY_execute_string(C, "__import__('addon_utils').reset_all()"); BPY_python_reset(C); addons_loaded = true; } } else { /* run any texts that were loaded in and flagged as modules */ BPY_python_reset(C); addons_loaded = true; } #else UNUSED_VARS(is_startup_file); #endif /* WITH_PYTHON */ WM_operatortype_last_properties_clear_all(); /* important to do before NULL'ing the context */ BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_VERSION_UPDATE); BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); /* would otherwise be handled by event loop */ if (G.background) { Main *bmain = CTX_data_main(C); BKE_scene_update_tagged(bmain->eval_ctx, bmain, CTX_data_scene(C)); } WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL); /* report any errors. * currently disabled if addons aren't yet loaded */ if (addons_loaded) { wm_file_read_report(C); } if (!G.background) { /* in background mode this makes it hard to load * a blend file and do anything since the screen * won't be set to a valid value again */ CTX_wm_window_set(C, NULL); /* exits queues */ } if (!G.background) { // undo_editmode_clear(); BKE_undo_reset(); BKE_undo_write(C, "original"); /* save current state */ } }
int wm_stereo3d_set_exec(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win_src = CTX_wm_window(C); wmWindow *win_dst = NULL; const bool is_fullscreen = WM_window_is_fullscreen(win_src); char prev_display_mode = win_src->stereo3d_format->display_mode; Stereo3dData *s3dd; bool ok = true; if (G.background) return OPERATOR_CANCELLED; if (op->customdata == NULL) { /* no invoke means we need to set the operator properties here */ wm_stereo3d_set_init(C, op); wm_stereo3d_set_properties(C, op); } s3dd = op->customdata; *win_src->stereo3d_format = s3dd->stereo3d_format; if (prev_display_mode == S3D_DISPLAY_PAGEFLIP && prev_display_mode != win_src->stereo3d_format->display_mode) { /* in case the hardward supports pageflip but not the display */ if ((win_dst = wm_window_copy_test(C, win_src))) { /* pass */ } else { BKE_report(op->reports, RPT_ERROR, "Failed to create a window without quad-buffer support, you may experience flickering"); ok = false; } } else if (win_src->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) { /* ED_screen_duplicate() can't handle other cases yet T44688 */ if (win_src->screen->state != SCREENNORMAL) { BKE_report(op->reports, RPT_ERROR, "Failed to switch to Time Sequential mode when in fullscreen"); ok = false; } /* pageflip requires a new window to be created with the proper OS flags */ else if ((win_dst = wm_window_copy_test(C, win_src))) { if (wm_stereo3d_quadbuffer_supported()) { BKE_report(op->reports, RPT_INFO, "Quad-buffer window successfully created"); } else { wm_window_close(C, wm, win_dst); win_dst = NULL; BKE_report(op->reports, RPT_ERROR, "Quad-buffer not supported by the system"); ok = false; } } else { BKE_report(op->reports, RPT_ERROR, "Failed to create a window compatible with the time sequential display method"); ok = false; } } if (wm_stereo3d_is_fullscreen_required(s3dd->stereo3d_format.display_mode)) { if (!is_fullscreen) { BKE_report(op->reports, RPT_INFO, "Stereo 3D Mode requires the window to be fullscreen"); } } MEM_freeN(op->customdata); if (ok) { if (win_dst) { wm_window_close(C, wm, win_src); } WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; } else { /* without this, the popup won't be freed freed properly T44688 */ CTX_wm_window_set(C, win_src); win_src->stereo3d_format->display_mode = prev_display_mode; return OPERATOR_CANCELLED; } }
/* only meant for timer usage */ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { ScrArea *sa = CTX_wm_area(C); SpaceFile *sfile = CTX_wm_space_file(C); ARegion *ar, *oldar = CTX_wm_region(C); int offset; int numfiles, numfiles_layout; int edit_idx = 0; int i; /* escape if not our timer */ if (sfile->smoothscroll_timer == NULL || sfile->smoothscroll_timer != event->customdata) return OPERATOR_PASS_THROUGH; numfiles = filelist_numfiles(sfile->files); /* check if we are editing a name */ for (i = 0; i < numfiles; ++i) { if (filelist_is_selected(sfile->files, i, CHECK_ALL) ) { edit_idx = i; break; } } /* if we are not editing, we are done */ if (0 == edit_idx) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_PASS_THROUGH; } /* we need the correct area for scrolling */ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (!ar || ar->regiontype != RGN_TYPE_WINDOW) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_PASS_THROUGH; } offset = ED_fileselect_layout_offset(sfile->layout, (int)ar->v2d.cur.xmin, (int)-ar->v2d.cur.ymax); if (offset < 0) offset = 0; /* scroll offset is the first file in the row/column we are editing in */ if (sfile->scroll_offset == 0) { if (sfile->layout->flag & FILE_LAYOUT_HOR) { sfile->scroll_offset = (edit_idx / sfile->layout->rows) * sfile->layout->rows; if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->rows; } else { sfile->scroll_offset = (edit_idx / sfile->layout->columns) * sfile->layout->columns; if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->columns; } } numfiles_layout = ED_fileselect_layout_numfiles(sfile->layout, ar); /* check if we have reached our final scroll position */ if ( (sfile->scroll_offset >= offset) && (sfile->scroll_offset < offset + numfiles_layout) ) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_FINISHED; } /* temporarily set context to the main window region, * so the scroll operators work */ CTX_wm_region_set(C, ar); /* scroll one step in the desired direction */ if (sfile->scroll_offset < offset) { if (sfile->layout->flag & FILE_LAYOUT_HOR) { WM_operator_name_call(C, "VIEW2D_OT_scroll_left", 0, NULL); } else { WM_operator_name_call(C, "VIEW2D_OT_scroll_up", 0, NULL); } } else { if (sfile->layout->flag & FILE_LAYOUT_HOR) { WM_operator_name_call(C, "VIEW2D_OT_scroll_right", 0, NULL); } else { WM_operator_name_call(C, "VIEW2D_OT_scroll_down", 0, NULL); } } ED_region_tag_redraw(ar); /* and restore context */ CTX_wm_region_set(C, oldar); return OPERATOR_FINISHED; }
/* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */ void ED_gpencil_draw_2dimage(const bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); bGPdata *gpd; int offsx, offsy, sizex, sizey; int dflag = GP_DRAWDATA_NOSTATUS; gpd = ED_gpencil_data_get_active(C); // XXX if (gpd == NULL) return; /* calculate rect */ switch (sa->spacetype) { case SPACE_IMAGE: /* image */ case SPACE_CLIP: /* clip */ { /* just draw using standard scaling (settings here are currently ignored anyways) */ /* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */ offsx = 0; offsy = 0; sizex = ar->winx; sizey = ar->winy; wmOrtho2(ar->v2d.cur.xmin, ar->v2d.cur.xmax, ar->v2d.cur.ymin, ar->v2d.cur.ymax); dflag |= GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_IEDITHACK; break; } case SPACE_SEQ: /* sequence */ { /* just draw using standard scaling (settings here are currently ignored anyways) */ offsx = 0; offsy = 0; sizex = ar->winx; sizey = ar->winy; /* NOTE: I2D was used in 2.4x, but the old settings for that have been deprecated * and everything moved to standard View2d */ dflag |= GP_DRAWDATA_ONLYV2D; break; } default: /* for spacetype not yet handled */ offsx = 0; offsy = 0; sizex = ar->winx; sizey = ar->winy; dflag |= GP_DRAWDATA_ONLYI2D; break; } if (ED_screen_animation_playing(wm)) { /* don't show onionskins during animation playback/scrub (i.e. it obscures the poses) * OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes) */ dflag |= GP_DRAWDATA_NO_ONIONS; } /* draw it! */ gp_draw_data_all(scene, gpd, offsx, offsy, sizex, sizey, CFRA, dflag, sa->spacetype); }
static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { wmWindowManager *wm = CTX_wm_manager(C); ReportList *reports = CTX_wm_reports(C); Report *report; ReportTimerInfo *rti; float progress = 0.0, color_progress = 0.0; float neutral_col[3] = {0.35, 0.35, 0.35}; float neutral_gray = 0.6; float timeout = 0.0, color_timeout = 0.0; int send_note = 0; /* escape if not our timer */ if ((reports->reporttimer == NULL) || (reports->reporttimer != event->customdata) || ((report = BKE_reports_last_displayable(reports)) == NULL) /* may have been deleted */ ) { return OPERATOR_PASS_THROUGH; } rti = (ReportTimerInfo *)reports->reporttimer->customdata; timeout = (report->type & RPT_ERROR_ALL) ? ERROR_TIMEOUT : INFO_TIMEOUT; color_timeout = (report->type & RPT_ERROR_ALL) ? ERROR_COLOR_TIMEOUT : INFO_COLOR_TIMEOUT; /* clear the report display after timeout */ if ((float)reports->reporttimer->duration > timeout) { WM_event_remove_timer(wm, NULL, reports->reporttimer); reports->reporttimer = NULL; WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL); return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); } if (rti->widthfac == 0.0f) { /* initialize colors based on report type */ if (report->type & RPT_ERROR_ALL) { rti->col[0] = 1.0; rti->col[1] = 0.2; rti->col[2] = 0.0; } else if (report->type & RPT_WARNING_ALL) { rti->col[0] = 1.0; rti->col[1] = 1.0; rti->col[2] = 0.0; } else if (report->type & RPT_INFO_ALL) { rti->col[0] = 0.3; rti->col[1] = 0.45; rti->col[2] = 0.7; } rti->grayscale = 0.75; rti->widthfac = 1.0; } progress = (float)reports->reporttimer->duration / timeout; color_progress = (float)reports->reporttimer->duration / color_timeout; /* save us from too many draws */ if (color_progress <= 1.0f) { send_note = 1; /* fade colors out sharply according to progress through fade-out duration */ interp_v3_v3v3(rti->col, rti->col, neutral_col, color_progress); rti->grayscale = interpf(neutral_gray, rti->grayscale, color_progress); } /* collapse report at end of timeout */ if (progress * timeout > timeout - COLLAPSE_TIMEOUT) { rti->widthfac = (progress * timeout - (timeout - COLLAPSE_TIMEOUT)) / COLLAPSE_TIMEOUT; rti->widthfac = 1.0f - rti->widthfac; send_note = 1; } if (send_note) { WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL); } return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); }
static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) { wmWindow *win = CTX_wm_window(C); walk->rv3d = CTX_wm_region_view3d(C); walk->v3d = CTX_wm_view3d(C); walk->ar = CTX_wm_region(C); walk->scene = CTX_data_scene(C); #ifdef NDOF_WALK_DEBUG puts("\n-- walk begin --"); #endif /* sanity check: for rare but possible case (if lib-linking the camera fails) */ if ((walk->rv3d->persp == RV3D_CAMOB) && (walk->v3d->camera == NULL)) { walk->rv3d->persp = RV3D_PERSP; } if (walk->rv3d->persp == RV3D_CAMOB && walk->v3d->camera->id.lib) { BKE_report(op->reports, RPT_ERROR, "Cannot navigate a camera from an external library"); return false; } if (ED_view3d_offset_lock_check(walk->v3d, walk->rv3d)) { BKE_report(op->reports, RPT_ERROR, "Cannot navigate when the view offset is locked"); return false; } if (walk->rv3d->persp == RV3D_CAMOB && walk->v3d->camera->constraints.first) { BKE_report(op->reports, RPT_ERROR, "Cannot navigate an object with constraints"); return false; } walk->state = WALK_RUNNING; if (fabsf(U.walk_navigation.walk_speed - userdef_speed) > 0.1f) { base_speed = U.walk_navigation.walk_speed; userdef_speed = U.walk_navigation.walk_speed; } walk->speed = 0.0f; walk->is_fast = false; walk->is_slow = false; walk->grid = (walk->scene->unit.system == USER_UNIT_NONE) ? 1.f : 1.f / walk->scene->unit.scale_length; /* user preference settings */ walk->teleport.duration = U.walk_navigation.teleport_time; walk->mouse_speed = U.walk_navigation.mouse_speed; if ((U.walk_navigation.flag & USER_WALK_GRAVITY)) walk_navigation_mode_set(C, op, walk, WALK_MODE_GRAVITY); else walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE); walk->view_height = U.walk_navigation.view_height; walk->jump_height = U.walk_navigation.jump_height; walk->speed = U.walk_navigation.walk_speed; walk->speed_factor = U.walk_navigation.walk_speed_factor; walk->gravity_state = WALK_GRAVITY_STATE_OFF; if ((walk->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)) { walk->gravity = fabsf(walk->scene->physics_settings.gravity[2]); } else { walk->gravity = 9.80668f; /* m/s2 */ } walk->is_reversed = ((U.walk_navigation.flag & USER_WALK_MOUSE_REVERSE) != 0); #ifdef USE_TABLET_SUPPORT walk->is_cursor_first = true; walk->is_cursor_absolute = false; #endif walk->active_directions = 0; #ifdef NDOF_WALK_DRAW_TOOMUCH walk->redraw = 1; #endif zero_v3(walk->dvec_prev); walk->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f); walk->ndof = NULL; walk->time_lastdraw = PIL_check_seconds_timer(); walk->draw_handle_pixel = ED_region_draw_cb_activate(walk->ar->type, drawWalkPixel, walk, REGION_DRAW_POST_PIXEL); walk->rv3d->rflag |= RV3D_NAVIGATING; walk->v3d_camera_control = ED_view3d_cameracontrol_acquire( walk->scene, walk->v3d, walk->rv3d, (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); /* center the mouse */ walk->center_mval[0] = walk->ar->winx * 0.5f; walk->center_mval[1] = walk->ar->winy * 0.5f; #ifdef USE_PIXELSIZE_NATIVE_SUPPORT walk->center_mval[0] += walk->ar->winrct.xmin; walk->center_mval[1] += walk->ar->winrct.ymin; WM_cursor_compatible_xy(win, &walk->center_mval[0], &walk->center_mval[1]); walk->center_mval[0] -= walk->ar->winrct.xmin; walk->center_mval[1] -= walk->ar->winrct.ymin; #endif copy_v2_v2_int(walk->prev_mval, walk->center_mval); WM_cursor_warp(win, walk->ar->winrct.xmin + walk->center_mval[0], walk->ar->winrct.ymin + walk->center_mval[1]); /* remove the mouse cursor temporarily */ WM_cursor_modal_set(win, CURSOR_NONE); return 1; }
static int flyEnd(bContext *C, FlyInfo *fly) { RegionView3D *rv3d = fly->rv3d; View3D *v3d = fly->v3d; float upvec[3]; if (fly->state == FLY_RUNNING) return OPERATOR_RUNNING_MODAL; #ifdef NDOF_FLY_DEBUG puts("\n-- fly end --"); #endif WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), fly->timer); ED_region_draw_cb_exit(fly->ar->type, fly->draw_handle_pixel); rv3d->dist = fly->dist_backup; if (fly->state == FLY_CANCEL) { /* Revert to original view? */ if (fly->persp_backup == RV3D_CAMOB) { /* a camera view */ Object *ob_back; ob_back = (fly->root_parent) ? fly->root_parent : fly->v3d->camera; /* store the original camera loc and rot */ BKE_object_tfm_restore(ob_back, fly->obtfm); DAG_id_tag_update(&ob_back->id, OB_RECALC_OB); } else { /* Non Camera we need to reset the view back to the original location bacause the user canceled*/ copy_qt_qt(rv3d->viewquat, fly->rot_backup); rv3d->persp = fly->persp_backup; } /* always, is set to zero otherwise */ copy_v3_v3(rv3d->ofs, fly->ofs_backup); } else if (fly->persp_backup == RV3D_CAMOB) { /* camera */ DAG_id_tag_update(fly->root_parent ? &fly->root_parent->id : &v3d->camera->id, OB_RECALC_OB); /* always, is set to zero otherwise */ copy_v3_v3(rv3d->ofs, fly->ofs_backup); } else { /* not camera */ /* Apply the fly mode view */ /* restore the dist */ float mat[3][3]; upvec[0] = upvec[1] = 0; upvec[2] = fly->dist_backup; /* x and y are 0 */ copy_m3_m4(mat, rv3d->viewinv); mul_m3_v3(mat, upvec); add_v3_v3(rv3d->ofs, upvec); /* Done with correcting for the dist */ } if (fly->is_ortho_cam) { ((Camera *)fly->v3d->camera->data)->type = CAM_ORTHO; } rv3d->rflag &= ~RV3D_NAVIGATING; //XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */ if (fly->obtfm) MEM_freeN(fly->obtfm); if (fly->ndof) MEM_freeN(fly->ndof); if (fly->state == FLY_CONFIRM) { MEM_freeN(fly); return OPERATOR_FINISHED; } MEM_freeN(fly); return OPERATOR_CANCELLED; }
static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event) { wmWindow *win = CTX_wm_window(C); float upvec[3]; /* tmp */ float mat[3][3]; fly->rv3d = CTX_wm_region_view3d(C); fly->v3d = CTX_wm_view3d(C); fly->ar = CTX_wm_region(C); fly->scene = CTX_data_scene(C); #ifdef NDOF_FLY_DEBUG puts("\n-- fly begin --"); #endif /* sanity check: for rare but possible case (if lib-linking the camera fails) */ if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) { fly->rv3d->persp = RV3D_PERSP; } if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->id.lib) { BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library"); return false; } if (ED_view3d_offset_lock_check(fly->v3d, fly->rv3d)) { BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view offset is locked"); return false; } if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->constraints.first) { BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints"); return false; } fly->state = FLY_RUNNING; fly->speed = 0.0f; fly->axis = 2; fly->pan_view = false; fly->xlock = FLY_AXISLOCK_STATE_OFF; fly->zlock = FLY_AXISLOCK_STATE_OFF; fly->xlock_momentum = 0.0f; fly->zlock_momentum = 0.0f; fly->grid = 1.0f; fly->use_precision = false; fly->use_freelook = false; #ifdef NDOF_FLY_DRAW_TOOMUCH fly->redraw = 1; #endif zero_v3(fly->dvec_prev); fly->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f); copy_v2_v2_int(fly->mval, event->mval); fly->ndof = NULL; fly->time_lastdraw = fly->time_lastwheel = PIL_check_seconds_timer(); fly->draw_handle_pixel = ED_region_draw_cb_activate(fly->ar->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL); fly->rv3d->rflag |= RV3D_NAVIGATING; /* so we draw the corner margins */ /* detect weather to start with Z locking */ upvec[0] = 1.0f; upvec[1] = 0.0f; upvec[2] = 0.0f; copy_m3_m4(mat, fly->rv3d->viewinv); mul_m3_v3(mat, upvec); if (fabsf(upvec[2]) < 0.1f) { fly->zlock = FLY_AXISLOCK_STATE_IDLE; } upvec[0] = 0; upvec[1] = 0; upvec[2] = 0; fly->persp_backup = fly->rv3d->persp; fly->dist_backup = fly->rv3d->dist; /* check for flying ortho camera - which we cant support well * we _could_ also check for an ortho camera but this is easier */ if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->rv3d->is_persp == false)) { ((Camera *)fly->v3d->camera->data)->type = CAM_PERSP; fly->is_ortho_cam = true; } if (fly->rv3d->persp == RV3D_CAMOB) { Object *ob_back; if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (fly->root_parent = fly->v3d->camera->parent)) { while (fly->root_parent->parent) fly->root_parent = fly->root_parent->parent; ob_back = fly->root_parent; } else { ob_back = fly->v3d->camera; } /* store the original camera loc and rot */ fly->obtfm = BKE_object_tfm_backup(ob_back); BKE_object_where_is_calc(fly->scene, fly->v3d->camera); negate_v3_v3(fly->rv3d->ofs, fly->v3d->camera->obmat[3]); fly->rv3d->dist = 0.0; } else { /* perspective or ortho */ if (fly->rv3d->persp == RV3D_ORTHO) fly->rv3d->persp = RV3D_PERSP; /* if ortho projection, make perspective */ copy_qt_qt(fly->rot_backup, fly->rv3d->viewquat); copy_v3_v3(fly->ofs_backup, fly->rv3d->ofs); /* the dist defines a vector that is infront of the offset * to rotate the view about. * this is no good for fly mode because we * want to rotate about the viewers center. * but to correct the dist removal we must * alter offset so the view doesn't jump. */ fly->rv3d->dist = 0.0f; upvec[2] = fly->dist_backup; /* x and y are 0 */ mul_m3_v3(mat, upvec); sub_v3_v3(fly->rv3d->ofs, upvec); /* Done with correcting for the dist */ } /* center the mouse, probably the UI mafia are against this but without its quite annoying */ WM_cursor_warp(win, fly->ar->winrct.xmin + fly->ar->winx / 2, fly->ar->winrct.ymin + fly->ar->winy / 2); return 1; }
static int load_file(int UNUSED(argc), const char **argv, void *data) { bContext *C = data; /* Make the path absolute because its needed for relative linked blends to be found */ char filename[FILE_MAX]; /* note, we could skip these, but so far we always tried to load these files */ if (argv[0][0] == '-') { fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]); } BLI_strncpy(filename, argv[0], sizeof(filename)); BLI_path_cwd(filename); if (G.background) { int retval = BKE_read_file(C, filename, NULL); /* we successfully loaded a blend file, get sure that * pointcache works */ if (retval != BKE_READ_FILE_FAIL) { wmWindowManager *wm = CTX_wm_manager(C); /* special case, 2.4x files */ if (wm == NULL && CTX_data_main(C)->wm.first == NULL) { extern void wm_add_default(bContext *C); /* wm_add_default() needs the screen to be set. */ CTX_wm_screen_set(C, CTX_data_main(C)->screen.first); wm_add_default(C); } CTX_wm_manager_set(C, NULL); /* remove wm to force check */ WM_check(C); G.relbase_valid = 1; if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */ DAG_on_visible_update(CTX_data_main(C), TRUE); } else { /* failed to load file, stop processing arguments */ return -1; } /* WM_file_read() runs normally but since we're in background mode do here */ #ifdef WITH_PYTHON /* run any texts that were loaded in and flagged as modules */ BPY_python_reset(C); #endif /* happens for the UI on file reading too (huh? (ton))*/ // XXX BKE_reset_undo(); // BKE_write_undo("original"); /* save current state */ } else { /* we are not running in background mode here, but start blender in UI mode with * a file - this should do everything a 'load file' does */ ReportList reports; BKE_reports_init(&reports, RPT_PRINT); WM_file_autoexec_init(filename); WM_file_read(C, filename, &reports); BKE_reports_clear(&reports); } G.file_loaded = 1; return 0; }
/* using context, starts job */ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event) { /* new render clears all callbacks */ Main *mainp; Scene *scene = CTX_data_scene(C); SceneRenderLayer *srl = NULL; View3D *v3d = CTX_wm_view3d(C); Render *re; wmJob *wm_job; RenderJob *rj; Image *ima; int jobflag; const short is_animation = RNA_boolean_get(op->ptr, "animation"); const short is_write_still = RNA_boolean_get(op->ptr, "write_still"); struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; const char *name; Object *active_object = CTX_data_active_object(C); /* only one render job at a time */ if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) return OPERATOR_CANCELLED; if (!RE_is_rendering_allowed(scene, camera_override, op->reports)) { return OPERATOR_CANCELLED; } if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) { BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected"); return OPERATOR_CANCELLED; } /* stop all running jobs, except screen one. currently previews frustrate Render */ WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C)); /* get main */ if (G.debug_value == 101) { /* thread-safety experiment, copy main from the undo buffer */ mainp = BKE_undo_get_main(&scene); } else mainp = CTX_data_main(C); /* cancel animation playback */ if (ED_screen_animation_playing(CTX_wm_manager(C))) ED_screen_animation_play(C, 0, 0); /* handle UI stuff */ WM_cursor_wait(1); /* flush multires changes (for sculpt) */ multires_force_render_update(active_object); /* flush changes from dynamic topology sculpt */ sculptsession_bm_to_me_for_render(active_object); /* cleanup sequencer caches before starting user triggered render. * otherwise, invalidated cache entries can make their way into * the output rendering. We can't put that into RE_BlenderFrame, * since sequence rendering can call that recursively... (peter) */ BKE_sequencer_cache_cleanup(); /* get editmode results */ ED_object_editmode_load(CTX_data_edit_object(C)); // store spare // get view3d layer, local layer, make this nice api call to render // store spare /* ensure at least 1 area shows result */ render_view_open(C, event->x, event->y); jobflag = WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS; /* custom scene and single layer re-render */ screen_render_scene_layer_set(op, mainp, &scene, &srl); if (RNA_struct_property_is_set(op->ptr, "layer")) jobflag |= WM_JOB_SUSPEND; /* job custom data */ rj = MEM_callocN(sizeof(RenderJob), "render job"); rj->main = mainp; rj->scene = scene; rj->win = CTX_wm_window(C); rj->srl = srl; rj->camera_override = camera_override; rj->lay = scene->lay; rj->anim = is_animation; rj->write_still = is_write_still && !is_animation; rj->iuser.scene = scene; rj->iuser.ok = 1; rj->reports = op->reports; if (v3d) { rj->lay = v3d->lay; if (v3d->localvd) rj->lay |= v3d->localvd->lay; } /* setup job */ if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render"; else name = "Render"; wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, name, jobflag, WM_JOB_TYPE_RENDER); WM_jobs_customdata_set(wm_job, rj, render_freejob); WM_jobs_timer(wm_job, 0.2, NC_SCENE | ND_RENDER_RESULT, 0); WM_jobs_callbacks(wm_job, render_startjob, NULL, NULL, render_endjob); /* get a render result image, and make sure it is empty */ ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); BKE_image_backup_render(rj->scene, ima); rj->image = ima; /* setup new render */ re = RE_NewRender(scene->id.name); RE_test_break_cb(re, rj, render_breakjob); RE_draw_lock_cb(re, rj, render_drawlock); RE_display_draw_cb(re, rj, image_rect_update); RE_stats_draw_cb(re, rj, image_renderinfo_cb); RE_progress_cb(re, rj, render_progress_update); rj->re = re; G.is_break = FALSE; /* store actual owner of job, so modal operator could check for it, * the reason of this is that active scene could change when rendering * several layers from compositor [#31800] */ op->customdata = scene; WM_jobs_start(CTX_wm_manager(C), wm_job); WM_cursor_wait(0); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); /* we set G.is_rendering here already instead of only in the job, this ensure * main loop or other scene updates are disabled in time, since they may * have started before the job thread */ G.is_rendering = TRUE; /* add modal handler for ESC */ WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; }
wmKeyMap *WM_keymap_find_all(const bContext *C, const char *idname, int spaceid, int regionid) { wmWindowManager *wm= CTX_wm_manager(C); return WM_keymap_list_find(&wm->userconf->keymaps, idname, spaceid, regionid); }
static void wm_undo_kill_callback(bContext *C) { WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C)); }
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing) { /* context values */ struct wmWindowManager *wm= CTX_wm_manager(C); struct wmWindow *win= CTX_wm_window(C); struct Scene *startscene= CTX_data_scene(C); struct Main* maggie1= CTX_data_main(C); RAS_Rect area_rect; area_rect.SetLeft(cam_frame->xmin); area_rect.SetBottom(cam_frame->ymin); area_rect.SetRight(cam_frame->xmax); area_rect.SetTop(cam_frame->ymax); int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; Main* blenderdata = maggie1; char* startscenename = startscene->id.name+2; char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE]; STR_String exitstring = ""; BlendFileData *bfd= NULL; BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); BLI_strncpy(oldsce, G.main->name, sizeof(oldsce)); #ifdef WITH_PYTHON resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path setGamePythonPath(G.main->name); // Acquire Python's GIL (global interpreter lock) // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */ #endif bgl::InitExtensions(true); // VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable int disableVBO = (U.gameflags & USER_DISABLE_VBO); U.gameflags |= USER_DISABLE_VBO; // Globals to be carried on over blender files GlobalSettings gs; gs.matmode= startscene->gm.matmode; gs.glslflag= startscene->gm.flag; do { View3D *v3d= CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0); bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0) && GPU_display_list_support(); #ifdef WITH_PYTHON bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0); #endif // bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0); bool mouse_state = (startscene->gm.flag & GAME_SHOW_MOUSE) != 0; bool restrictAnimFPS = (startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES) != 0; short drawtype = v3d->drawtype; /* we do not support material mode in game engine, force change to texture mode */ if (drawtype == OB_MATERIAL) drawtype = OB_TEXTURE; if (animation_record) usefixed= false; /* override since you don't want to run full-speed for sim recording */ // create the canvas and rasterizer RAS_ICanvas* canvas = new KX_BlenderCanvas(wm, win, area_rect, ar); // default mouse state set on render panel if (mouse_state) canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); else canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); // Setup vsync int previous_vsync = 0; canvas->GetSwapInterval(previous_vsync); if (startscene->gm.vsync == VSYNC_ADAPTIVE) canvas->SetSwapInterval(-1); else canvas->SetSwapInterval((startscene->gm.vsync == VSYNC_ON) ? 1 : 0); RAS_IRasterizer* rasterizer = NULL; //Don't use displaylists with VBOs //If auto starts using VBOs, make sure to check for that here if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO) rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage); else rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage); RAS_IRasterizer::MipmapOption mipmapval = rasterizer->GetMipmapping(); // create the inputdevices KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice(); // create a networkdevice NG_NetworkDeviceInterface* networkdevice = new NG_LoopBackNetworkDeviceInterface(); // // create a ketsji/blendersystem (only needed for timing and stuff) KX_BlenderSystem* kxsystem = new KX_BlenderSystem(); // create the ketsjiengine KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); // set the devices ketsjiengine->SetKeyboardDevice(keyboarddevice); ketsjiengine->SetMouseDevice(mousedevice); ketsjiengine->SetNetworkDevice(networkdevice); ketsjiengine->SetCanvas(canvas); ketsjiengine->SetRasterizer(rasterizer); ketsjiengine->SetUseFixedTime(usefixed); ketsjiengine->SetTimingDisplay(frameRate, profile, properties); ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey)); //set the global settings (carried over if restart/load new files) ketsjiengine->SetGlobalSettings(&gs); #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #endif //lock frame and camera enabled - storing global values int tmp_lay= startscene->lay; Object *tmp_camera = startscene->camera; if (v3d->scenelock==0) { startscene->lay= v3d->lay; startscene->camera= v3d->camera; } // some blender stuff float camzoom; int draw_letterbox = 0; if (rv3d->persp==RV3D_CAMOB) { if (startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */ camzoom = 1.0f; draw_letterbox = 1; } else { camzoom = 1.0f / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom); } } else { camzoom = 2.0; } rasterizer->SetDrawingMode(drawtype); ketsjiengine->SetCameraZoom(camzoom); // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) { exitrequested = KX_EXIT_REQUEST_NO_REQUEST; if (bfd) BLO_blendfiledata_free(bfd); char basedpath[FILE_MAX]; // base the actuator filename with respect // to the original file working directory if (exitstring != "") BLI_strncpy(basedpath, exitstring.ReadPtr(), sizeof(basedpath)); // load relative to the last loaded file, this used to be relative // to the first file but that makes no sense, relative paths in // blend files should be relative to that file, not some other file // that happened to be loaded first BLI_path_abs(basedpath, pathname); bfd = load_game_data(basedpath); // if it wasn't loaded, try it forced relative if (!bfd) { // just add "//" in front of it char temppath[FILE_MAX] = "//"; BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); } // if we got a loaded blendfile, proceed if (bfd) { blenderdata = bfd->main; startscenename = bfd->curscene->id.name + 2; if (blenderdata) { BLI_strncpy(G.main->name, blenderdata->name, sizeof(G.main->name)); BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); #ifdef WITH_PYTHON setGamePythonPath(G.main->name); #endif } } // else forget it, we can't find it else { exitrequested = KX_EXIT_REQUEST_QUIT_GAME; } } Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2); if (scene) { int startFrame = scene->r.cfra; ketsjiengine->SetAnimRecordMode(animation_record, startFrame); // Quad buffered needs a special window. if (scene->gm.stereoflag == STEREO_ENABLED) { if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode); rasterizer->SetEyeSeparation(scene->gm.eyeseparation); } rasterizer->SetBackColor(scene->gm.framing.col); } if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) { if (rv3d->persp != RV3D_CAMOB) { ketsjiengine->EnableCameraOverride(startscenename); ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO)); ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat)); ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat)); ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); ketsjiengine->SetCameraOverrideLens(v3d->lens); } // create a scene converter, create and convert the startingscene KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine); ketsjiengine->SetSceneConverter(sceneconverter); if (always_use_expand_framing) sceneconverter->SetAlwaysUseExpandFraming(true); bool usemat = false, useglslmat = false; if (GLEW_ARB_multitexture && GLEW_VERSION_1_1) usemat = true; if (GPU_glsl_support()) useglslmat = true; else if (gs.matmode == GAME_MAT_GLSL) usemat = false; if (usemat) sceneconverter->SetMaterials(true); if (useglslmat && (gs.matmode == GAME_MAT_GLSL)) sceneconverter->SetGLSLMaterials(true); if (scene->gm.flag & GAME_NO_MATERIAL_CACHING) sceneconverter->SetCacheMaterials(false); KX_Scene* startscene = new KX_Scene(keyboarddevice, mousedevice, networkdevice, startscenename, scene, canvas); #ifdef WITH_PYTHON // some python things PyObject *gameLogic, *gameLogic_keys; setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL); #endif // WITH_PYTHON //initialize Dome Settings if (scene->gm.stereoflag == STEREO_DOME) ketsjiengine->InitDome(scene->gm.dome.res, scene->gm.dome.mode, scene->gm.dome.angle, scene->gm.dome.resbuf, scene->gm.dome.tilt, scene->gm.dome.warptext); // initialize 3D Audio Settings AUD_I3DDevice* dev = AUD_get3DDevice(); if (dev) { dev->setSpeedOfSound(scene->audio.speed_of_sound); dev->setDopplerFactor(scene->audio.doppler_factor); dev->setDistanceModel(AUD_DistanceModel(scene->audio.distance_model)); } // from see blender.c: // FIXME: this version patching should really be part of the file-reading code, // but we still get too many unrelated data-corruption crashes otherwise... if (blenderdata->versionfile < 250) do_versions_ipos_to_animato(blenderdata); if (sceneconverter) { // convert and add scene sceneconverter->ConvertScene( startscene, rasterizer, canvas); ketsjiengine->AddScene(startscene); // init the rasterizer rasterizer->Init(); // start the engine ketsjiengine->StartEngine(true); // Set the animation playback rate for ipo's and actions // the framerate below should patch with FPS macro defined in blendef.h // Could be in StartEngine set the framerate, we need the scene to do this ketsjiengine->SetAnimFrameRate(FPS); #ifdef WITH_PYTHON char *python_main = NULL; pynextframestate.state = NULL; pynextframestate.func = NULL; python_main = KX_GetPythonMain(scene); // the mainloop printf("\nBlender Game Engine Started\n"); if (python_main) { char *python_code = KX_GetPythonCode(blenderdata, python_main); if (python_code) { ketsjinextframestate.ketsjiengine = ketsjiengine; ketsjinextframestate.C = C; ketsjinextframestate.win = win; ketsjinextframestate.scene = scene; ketsjinextframestate.ar = ar; ketsjinextframestate.keyboarddevice = keyboarddevice; ketsjinextframestate.mousedevice = mousedevice; ketsjinextframestate.draw_letterbox = draw_letterbox; pynextframestate.state = &ketsjinextframestate; pynextframestate.func = &BL_KetsjiPyNextFrame; printf("Yielding control to Python script '%s'...\n", python_main); PyRun_SimpleString(python_code); printf("Exit Python script '%s'\n", python_main); MEM_freeN(python_code); } } else #endif /* WITH_PYTHON */ { while (!exitrequested) { exitrequested = BL_KetsjiNextFrame(ketsjiengine, C, win, scene, ar, keyboarddevice, mousedevice, draw_letterbox); } } printf("Blender Game Engine Finished\n"); exitstring = ketsjiengine->GetExitString(); #ifdef WITH_PYTHON if (python_main) MEM_freeN(python_main); #endif /* WITH_PYTHON */ gs = *(ketsjiengine->GetGlobalSettings()); // when exiting the mainloop #ifdef WITH_PYTHON // Clears the dictionary by hand: // This prevents, extra references to global variables // inside the GameLogic dictionary when the python interpreter is finalized. // which allows the scene to safely delete them :) // see: (space.c)->start_game //PyDict_Clear(PyModule_GetDict(gameLogic)); // Keep original items, means python plugins will autocomplete members PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic)); const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new); Py_ssize_t listIndex; for (listIndex=0; listIndex < numitems; listIndex++) { PyObject *item = PyList_GET_ITEM(gameLogic_keys_new, listIndex); if (!PySequence_Contains(gameLogic_keys, item)) { PyDict_DelItem( PyModule_GetDict(gameLogic), item); } } Py_DECREF(gameLogic_keys_new); gameLogic_keys_new = NULL; #endif ketsjiengine->StopEngine(); #ifdef WITH_PYTHON exitGamePythonScripting(); #endif networkdevice->Disconnect(); } if (sceneconverter) { delete sceneconverter; sceneconverter = NULL; } #ifdef WITH_PYTHON Py_DECREF(gameLogic_keys); gameLogic_keys = NULL; #endif } //lock frame and camera enabled - restoring global values if (v3d->scenelock==0) { startscene->lay= tmp_lay; startscene->camera= tmp_camera; } if (exitrequested != KX_EXIT_REQUEST_OUTSIDE) { // set the cursor back to normal canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); // set mipmap setting back to its original value rasterizer->SetMipmapping(mipmapval); } // clean up some stuff if (ketsjiengine) { delete ketsjiengine; ketsjiengine = NULL; } if (kxsystem) { delete kxsystem; kxsystem = NULL; } if (networkdevice) { delete networkdevice; networkdevice = NULL; } if (keyboarddevice) { delete keyboarddevice; keyboarddevice = NULL; } if (mousedevice) { delete mousedevice; mousedevice = NULL; } if (rasterizer) { delete rasterizer; rasterizer = NULL; } if (canvas) { canvas->SetSwapInterval(previous_vsync); // Set the swap interval back delete canvas; canvas = NULL; } // stop all remaining playing sounds AUD_getDevice()->stopAll(); } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); if (!disableVBO) U.gameflags &= ~USER_DISABLE_VBO; if (bfd) BLO_blendfiledata_free(bfd); BLI_strncpy(G.main->name, oldsce, sizeof(G.main->name)); #ifdef WITH_PYTHON Py_DECREF(pyGlobalDict); // Release Python's GIL PyGILState_Release(gilstate); #endif }
static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, short do_job) { Scene *scene= CTX_data_scene(C); int i; FluidsimSettings *domainSettings; char debugStrBuffer[256]; int gridlevels = 0; const char *relbase= modifier_path_relbase(fsDomain); const char *strEnvName = "BLENDER_ELBEEMDEBUG"; // from blendercall.cpp const char *suffixConfigTmp = FLUID_SUFFIX_CONFIG_TMP; const char *suffixSurface = FLUID_SUFFIX_SURFACE; char targetDir[FILE_MAX]; // store & modify output settings char targetFile[FILE_MAX]; // temp. store filename from targetDir for access int outStringsChanged = 0; // modified? copy back before baking float domainMat[4][4]; float invDomMat[4][4]; int noFrames; int origFrame = scene->r.cfra; FluidAnimChannels *channels = MEM_callocN(sizeof(FluidAnimChannels), "fluid domain animation channels"); ListBase *fobjects = MEM_callocN(sizeof(ListBase), "fluid objects"); FluidsimModifierData *fluidmd = NULL; Mesh *mesh = NULL; FluidBakeJob *fb; elbeemSimulationSettings *fsset= MEM_callocN(sizeof(elbeemSimulationSettings), "Fluid sim settings"); fb= MEM_callocN(sizeof(FluidBakeJob), "fluid bake job"); if (getenv(strEnvName)) { int dlevel = atoi(getenv(strEnvName)); elbeemSetDebugLevel(dlevel); BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer), "fluidsimBake::msg: Debug messages activated due to envvar '%s'\n", strEnvName); elbeemDebugOut(debugStrBuffer); } /* make sure it corresponds to startFrame setting (old: noFrames = scene->r.efra - scene->r.sfra +1) */; noFrames = scene->r.efra - 0; if (noFrames<=0) { BKE_report(reports, RPT_ERROR, "No frames to export (check your animation range settings)"); fluidbake_free_data(channels, fobjects, fsset, fb); return 0; } /* check scene for sane object/modifier settings */ if (!fluid_validate_scene(reports, scene, fsDomain)) { fluidbake_free_data(channels, fobjects, fsset, fb); return 0; } /* these both have to be valid, otherwise we wouldn't be here */ fluidmd = (FluidsimModifierData *)modifiers_findByType(fsDomain, eModifierType_Fluidsim); domainSettings = fluidmd->fss; mesh = fsDomain->data; domainSettings->bakeStart = 1; domainSettings->bakeEnd = scene->r.efra; // calculate bounding box fluid_get_bb(mesh->mvert, mesh->totvert, fsDomain->obmat, domainSettings->bbStart, domainSettings->bbSize); // reset last valid frame domainSettings->lastgoodframe = -1; /* delete old baked files */ fluidsim_delete_until_lastframe(domainSettings, relbase); /* rough check of settings... */ if (domainSettings->previewresxyz > domainSettings->resolutionxyz) { BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer), "fluidsimBake::warning - Preview (%d) >= Resolution (%d)... setting equal.\n", domainSettings->previewresxyz, domainSettings->resolutionxyz); elbeemDebugOut(debugStrBuffer); domainSettings->previewresxyz = domainSettings->resolutionxyz; } // set adaptive coarsening according to resolutionxyz // this should do as an approximation, with in/outflow // doing this more accurate would be overkill // perhaps add manual setting? if (domainSettings->maxRefine <0) { if (domainSettings->resolutionxyz>128) { gridlevels = 2; } else if (domainSettings->resolutionxyz > 64) { gridlevels = 1; } else { gridlevels = 0; } } else { gridlevels = domainSettings->maxRefine; } BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer), "fluidsimBake::msg: Baking %s, refine: %d\n", fsDomain->id.name, gridlevels); elbeemDebugOut(debugStrBuffer); /* ******** prepare output file paths ******** */ outStringsChanged = fluid_init_filepaths(fsDomain, targetDir, targetFile, debugStrBuffer); channels->length = scene->r.efra; // DG TODO: why using endframe and not "noFrames" here? .. because "noFrames" is buggy too? (not using sfra) channels->aniFrameTime = (double)((double)domainSettings->animEnd - (double)domainSettings->animStart) / (double)noFrames; /* ******** initialize and allocate animation channels ******** */ fluid_init_all_channels(C, fsDomain, domainSettings, channels, fobjects); /* reset to original current frame */ scene->r.cfra = origFrame; ED_update_for_newframe(CTX_data_main(C), scene, 1); /* ******** init domain object's matrix ******** */ copy_m4_m4(domainMat, fsDomain->obmat); if (!invert_m4_m4(invDomMat, domainMat)) { BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer), "fluidsimBake::error - Invalid obj matrix?\n"); elbeemDebugOut(debugStrBuffer); BKE_report(reports, RPT_ERROR, "Invalid object matrix"); fluidbake_free_data(channels, fobjects, fsset, fb); return 0; } /* ******** start writing / exporting ******** */ // use .tmp, don't overwrite/delete original file BLI_join_dirfile(targetFile, sizeof(targetFile), targetDir, suffixConfigTmp); // make sure these directories exist as well if (outStringsChanged) { BLI_make_existing_file(targetFile); } /* ******** export domain to elbeem ******** */ elbeemResetSettings(fsset); fsset->version = 1; fsset->threads = (domainSettings->threads == 0) ? BKE_scene_num_threads(scene) : domainSettings->threads; // setup global settings copy_v3_v3(fsset->geoStart, domainSettings->bbStart); copy_v3_v3(fsset->geoSize, domainSettings->bbSize); // simulate with 50^3 fsset->resolutionxyz = (int)domainSettings->resolutionxyz; fsset->previewresxyz = (int)domainSettings->previewresxyz; fsset->realsize = get_fluid_size_m(scene, fsDomain, domainSettings); fsset->viscosity = get_fluid_viscosity(domainSettings); get_fluid_gravity(fsset->gravity, scene, domainSettings); // simulate 5 frames, each 0.03 seconds, output to ./apitest_XXX.bobj.gz fsset->animStart = domainSettings->animStart; fsset->aniFrameTime = channels->aniFrameTime; fsset->noOfFrames = noFrames; // is otherwise subtracted in parser BLI_join_dirfile(targetFile, sizeof(targetFile), targetDir, suffixSurface); // defaults for compressibility and adaptive grids fsset->gstar = domainSettings->gstar; fsset->maxRefine = domainSettings->maxRefine; // check <-> gridlevels fsset->generateParticles = domainSettings->generateParticles; fsset->numTracerParticles = domainSettings->generateTracers; fsset->surfaceSmoothing = domainSettings->surfaceSmoothing; fsset->surfaceSubdivs = domainSettings->surfaceSubdivs; fsset->farFieldSize = domainSettings->farFieldSize; BLI_strncpy(fsset->outputPath, targetFile, sizeof(fsset->outputPath)); // domain channels fsset->channelSizeFrameTime = fsset->channelSizeViscosity = fsset->channelSizeGravity = channels->length; fsset->channelFrameTime = channels->DomainTime; fsset->channelViscosity = channels->DomainViscosity; fsset->channelGravity = channels->DomainGravity; fsset->runsimCallback = &runSimulationCallback; fsset->runsimUserData = fb; if (domainSettings->typeFlags & OB_FSBND_NOSLIP) fsset->domainobsType = FLUIDSIM_OBSTACLE_NOSLIP; else if (domainSettings->typeFlags&OB_FSBND_PARTSLIP) fsset->domainobsType = FLUIDSIM_OBSTACLE_PARTSLIP; else if (domainSettings->typeFlags&OB_FSBND_FREESLIP) fsset->domainobsType = FLUIDSIM_OBSTACLE_FREESLIP; fsset->domainobsPartslip = domainSettings->partSlipValue; /* use domainobsType also for surface generation flag (bit: >=64) */ if (domainSettings->typeFlags & OB_FSSG_NOOBS) fsset->mFsSurfGenSetting = FLUIDSIM_FSSG_NOOBS; else fsset->mFsSurfGenSetting = 0; // "normal" mode fsset->generateVertexVectors = (domainSettings->domainNovecgen==0); // init blender domain transform matrix { int j; for (i=0; i<4; i++) { for (j=0; j<4; j++) { fsset->surfaceTrafo[i*4+j] = invDomMat[j][i]; } } } /* ******** init solver with settings ******** */ elbeemInit(); elbeemAddDomain(fsset); /* ******** export all fluid objects to elbeem ******** */ export_fluid_objects(fobjects, scene, channels->length); /* custom data for fluid bake job */ fb->settings = fsset; if (do_job) { wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Fluid Simulation", WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_SIM_FLUID); /* setup job */ WM_jobs_customdata_set(wm_job, fb, fluidbake_free); WM_jobs_timer(wm_job, 0.1, NC_SCENE|ND_FRAME, NC_SCENE|ND_FRAME); WM_jobs_callbacks(wm_job, fluidbake_startjob, NULL, NULL, fluidbake_endjob); WM_jobs_start(CTX_wm_manager(C), wm_job); } else { short dummy_stop = 0, dummy_do_update = 0; float dummy_progress = 0.0f; /* blocking, use with exec() */ fluidbake_startjob((void *)fb, &dummy_stop, &dummy_do_update, &dummy_progress); fluidbake_endjob((void *)fb); fluidbake_free((void *)fb); } /* ******** free stored animation data ******** */ fluidbake_free_data(channels, fobjects, NULL, NULL); // elbeemFree(); return 1; }
/* if rect set, do not draw */ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) { wmWindowManager *wm= CTX_wm_manager(C); wmDrag *drag; int cursorx, cursory, x, y; cursorx= win->eventstate->x; cursory= win->eventstate->y; if(rect) { rect->xmin= rect->xmax= cursorx; rect->ymin= rect->ymax= cursory; } /* XXX todo, multiline drag draws... but maybe not, more types mixed wont work well */ glEnable(GL_BLEND); for(drag= wm->drags.first; drag; drag= drag->next) { /* image or icon */ if(drag->imb) { x= cursorx - drag->sx/2; y= cursory - drag->sy/2; if(rect) drag_rect_minmax(rect, x, y, x+drag->sx, y+drag->sy); else { glColor4f(1.0, 1.0, 1.0, 0.65); /* this blends texture */ glaDrawPixelsTexScaled(x, y, drag->imb->x, drag->imb->y, GL_UNSIGNED_BYTE, drag->imb->rect, drag->scale, drag->scale); } } else { x= cursorx - 8; y= cursory - 2; /* icons assumed to be 16 pixels */ if(rect) drag_rect_minmax(rect, x, y, x+16, y+16); else UI_icon_draw_aspect(x, y, drag->icon, 1.0, 0.8); } /* item name */ if(drag->imb) { x= cursorx - drag->sx/2; y= cursory - drag->sy/2 - 16; } else { x= cursorx + 10; y= cursory + 1; } if(rect) { int w= UI_GetStringWidth(wm_drag_name(drag)); drag_rect_minmax(rect, x, y, x+w, y+16); } else { glColor4ub(255, 255, 255, 255); UI_DrawString(x, y, wm_drag_name(drag)); } /* operator name with roundbox */ if(drag->opname[0]) { if(drag->imb) { x= cursorx - drag->sx/2; y= cursory + drag->sy/2 + 4; } else { x= cursorx - 8; y= cursory + 16; } if(rect) { int w= UI_GetStringWidth(wm_drag_name(drag)); drag_rect_minmax(rect, x, y, x+w, y+16); } else wm_drop_operator_draw(drag->opname, x, y); } } glDisable(GL_BLEND); }
void thumbnails_stop(struct FileList* filelist, const struct bContext* C) { WM_jobs_kill(CTX_wm_manager(C), filelist, NULL); }
/** * \see #wm_homefile_write_exec wraps #BLO_write_file in a similar way. */ int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList *reports) { Library *li; int len; int ret = -1; BlendThumbnail *thumb, *main_thumb; ImBuf *ibuf_thumb = NULL; len = strlen(filepath); if (len == 0) { BKE_report(reports, RPT_ERROR, "Path is empty, cannot save"); return ret; } if (len >= FILE_MAX) { BKE_report(reports, RPT_ERROR, "Path too long, cannot save"); return ret; } /* Check if file write permission is ok */ if (BLI_exists(filepath) && !BLI_file_is_writable(filepath)) { BKE_reportf(reports, RPT_ERROR, "Cannot save blend file, path '%s' is not writable", filepath); return ret; } /* note: used to replace the file extension (to ensure '.blend'), * no need to now because the operator ensures, * its handy for scripts to save to a predefined name without blender editing it */ /* send the OnSave event */ for (li = G.main->library.first; li; li = li->id.next) { if (BLI_path_cmp(li->filepath, filepath) == 0) { BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath); return ret; } } /* Call pre-save callbacks befores writing preview, that way you can generate custom file thumbnail... */ BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); /* blend file thumbnail */ /* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */ /* Main now can store a .blend thumbnail, usefull for background mode or thumbnail customization. */ main_thumb = thumb = CTX_data_main(C)->blen_thumb; if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) { ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb); } /* operator now handles overwrite checks */ if (G.fileflags & G_AUTOPACK) { packAll(G.main, reports, false); } /* don't forget not to return without! */ WM_cursor_wait(1); ED_editors_flush_edits(C, false); fileflags |= G_FILE_HISTORY; /* write file history */ /* first time saving */ /* XXX temp solution to solve bug, real fix coming (ton) */ if ((G.main->name[0] == '\0') && !(fileflags & G_FILE_SAVE_COPY)) { BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); } /* XXX temp solution to solve bug, real fix coming (ton) */ G.main->recovered = 0; if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) { const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0); if (!(fileflags & G_FILE_SAVE_COPY)) { G.relbase_valid = 1; BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); /* is guaranteed current file */ G.save_over = 1; /* disable untitled.blend convention */ } BKE_BIT_TEST_SET(G.fileflags, fileflags & G_FILE_COMPRESS, G_FILE_COMPRESS); BKE_BIT_TEST_SET(G.fileflags, fileflags & G_FILE_AUTOPLAY, G_FILE_AUTOPLAY); /* prevent background mode scripts from clobbering history */ if (do_history) { wm_history_file_update(); } BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_POST); /* run this function after because the file cant be written before the blend is */ if (ibuf_thumb) { IMB_thumb_delete(filepath, THB_FAIL); /* without this a failed thumb overrides */ ibuf_thumb = IMB_thumb_create(filepath, THB_LARGE, THB_SOURCE_BLEND, ibuf_thumb); } ret = 0; /* Success. */ } if (ibuf_thumb) { IMB_freeImBuf(ibuf_thumb); } if (thumb && thumb != main_thumb) { MEM_freeN(thumb); } WM_cursor_wait(0); return ret; }
int thumbnails_running(struct FileList* filelist, const struct bContext* C) { return WM_jobs_test(CTX_wm_manager(C), filelist); }
bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) { /* assume automated tasks with background, don't write recent file list */ const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0); bool success = false; int retval; /* so we can get the error message */ errno = 0; WM_cursor_wait(1); BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); UI_view2d_zoom_cache_reset(); /* first try to append data from exotic file formats... */ /* it throws error box when file doesn't exist and returns -1 */ /* note; it should set some error message somewhere... (ton) */ retval = wm_read_exotic(filepath); /* we didn't succeed, now try to read Blender file */ if (retval == BKE_READ_EXOTIC_OK_BLEND) { int G_f = G.f; ListBase wmbase; /* put aside screens to match with persistent windows later */ /* also exit screens and editors */ wm_window_match_init(C, &wmbase); /* confusing this global... */ G.relbase_valid = 1; retval = BKE_read_file(C, filepath, reports); /* when loading startup.blend's, we can be left with a blank path */ if (G.main->name[0]) { G.save_over = 1; } else { G.save_over = 0; G.relbase_valid = 0; } /* this flag is initialized by the operator but overwritten on read. * need to re-enable it here else drivers + registered scripts wont work. */ if (G.f != G_f) { const int flags_keep = (G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF); G.f = (G.f & ~flags_keep) | (G_f & flags_keep); } /* match the read WM with current WM */ wm_window_match_do(C, &wmbase); WM_check(C); /* opens window(s), checks keymaps */ if (retval == BKE_READ_FILE_OK_USERPREFS) { /* in case a userdef is read from regular .blend */ wm_init_userdef(C, false); } if (retval != BKE_READ_FILE_FAIL) { if (do_history) { wm_history_file_update(); } } wm_file_read_post(C, false); success = true; } #if 0 else if (retval == BKE_READ_EXOTIC_OK_OTHER) BKE_undo_write(C, "Import file"); #endif else if (retval == BKE_READ_EXOTIC_FAIL_OPEN) { BKE_reportf(reports, RPT_ERROR, "Cannot read file '%s': %s", filepath, errno ? strerror(errno) : TIP_("unable to open the file")); } else if (retval == BKE_READ_EXOTIC_FAIL_FORMAT) { BKE_reportf(reports, RPT_ERROR, "File format is not supported in file '%s'", filepath); } else if (retval == BKE_READ_EXOTIC_FAIL_PATH) { BKE_reportf(reports, RPT_ERROR, "File path '%s' invalid", filepath); } else { BKE_reportf(reports, RPT_ERROR, "Unknown error loading '%s'", filepath); BLI_assert(!"invalid 'retval'"); } if (success == false) { /* remove from recent files list */ if (do_history) { RecentFile *recent = wm_file_history_find(filepath); if (recent) { wm_history_file_free(recent); wm_history_file_write(); } } } WM_cursor_wait(0); return success; }
static int ocean_bake_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); OceanModifierData *omd = (OceanModifierData *)edit_modifier_property_get(op, ob, eModifierType_Ocean); Scene *scene = CTX_data_scene(C); OceanCache *och; struct Ocean *ocean; int f, cfra, i=0; int free= RNA_boolean_get(op->ptr, "free"); wmJob *steve; OceanBakeJob *oj; if (!omd) return OPERATOR_CANCELLED; if (free) { omd->refresh |= MOD_OCEAN_REFRESH_CLEAR_CACHE; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } och = BKE_init_ocean_cache(omd->cachepath, modifier_path_relbase(ob), omd->bakestart, omd->bakeend, omd->wave_scale, omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution); och->time = MEM_mallocN(och->duration*sizeof(float), "foam bake time"); cfra = scene->r.cfra; /* precalculate time variable before baking */ for (f=omd->bakestart; f<=omd->bakeend; f++) { /* from physics_fluid.c: * XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation, * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ ) * --> BKE_animsys_evaluate_all_animation(G.main, eval_time); * This doesn't work with drivers: * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL); */ /* Modifying the global scene isn't nice, but we can do it in * this part of the process before a threaded job is created */ //scene->r.cfra = f; //ED_update_for_newframe(CTX_data_main(C), scene, CTX_wm_screen(C), 1); /* ok, this doesn't work with drivers, but is way faster. * let's use this for now and hope nobody wants to drive the time value... */ BKE_animsys_evaluate_animdata(scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM); och->time[i] = omd->time; i++; } /* make a copy of ocean to use for baking - threadsafety */ ocean = BKE_add_ocean(); init_ocean_modifier_bake(ocean, omd); /* BKE_bake_ocean(ocean, och); omd->oceancache = och; omd->cached = TRUE; scene->r.cfra = cfra; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); */ /* job stuff */ scene->r.cfra = cfra; /* setup job */ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Ocean Simulation", WM_JOB_PROGRESS); oj= MEM_callocN(sizeof(OceanBakeJob), "ocean bake job"); oj->ocean = ocean; oj->och = och; oj->omd = omd; WM_jobs_customdata(steve, oj, oceanbake_free); WM_jobs_timer(steve, 0.1, NC_OBJECT|ND_MODIFIER, NC_OBJECT|ND_MODIFIER); WM_jobs_callbacks(steve, oceanbake_startjob, NULL, NULL, oceanbake_endjob); WM_jobs_start(CTX_wm_manager(C), steve); return OPERATOR_FINISHED; }