static int rna_Object_update_from_editmode(Object *ob) { if (ob->mode & OB_MODE_EDIT) { return ED_object_editmode_load(ob); } return false; }
/* flush any temp data from object editing to DNA before writing files, * rendering, copying, etc. */ bool ED_editors_flush_edits(const bContext *C, bool for_render) { bool has_edited = false; Object *ob; Main *bmain = CTX_data_main(C); /* loop through all data to find edit mode or object mode, because during * exiting we might not have a context for edit object and multiple sculpt * objects can exist at the same time */ for (ob = bmain->object.first; ob; ob = ob->id.next) { if (ob->mode & OB_MODE_SCULPT) { /* flush multires changes (for sculpt) */ multires_force_update(ob); has_edited = true; if (for_render) { /* flush changes from dynamic topology sculpt */ BKE_sculptsession_bm_to_me_for_render(ob); } else { /* Set reorder=false so that saving the file doesn't reorder * the BMesh's elements */ BKE_sculptsession_bm_to_me(ob, false); } } else if (ob->mode & OB_MODE_EDIT) { /* get editmode results */ has_edited = true; ED_object_editmode_load(ob); } } return has_edited; }
static bool rna_Object_update_from_editmode(Object *ob, Main *bmain) { /* fail gracefully if we aren't in edit-mode. */ const bool result = ED_object_editmode_load(bmain, ob); if (result) { /* Loading edit mesh to mesh changes geometry, and scripts might expect it to be properly * informed about changes. */ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); } return result; }
/* create new mesh with edit mode changes and modifiers applied */ static Mesh *bake_mesh_new_from_object(Main *bmain, Scene *scene, Object *ob) { if (ob->mode & OB_MODE_EDIT) ED_object_editmode_load(ob); Mesh *me = BKE_mesh_new_from_object(bmain, scene, ob, 1, 2, 0, 0); if (me->flag & ME_AUTOSMOOTH) { BKE_mesh_split_faces(me, true); } return me; }
/* flush any temp data from object editing to DNA before writing files, * rendering, copying, etc. */ bool ED_editors_flush_edits(const bContext *C, bool for_render) { bool has_edited = false; Object *ob; Main *bmain = CTX_data_main(C); /* loop through all data to find edit mode or object mode, because during * exiting we might not have a context for edit object and multiple sculpt * objects can exist at the same time */ for (ob = bmain->object.first; ob; ob = ob->id.next) { if (ob->mode & OB_MODE_SCULPT) { /* Don't allow flushing while in the middle of a stroke (frees data in use). * Auto-save prevents this from happening but scripts may cause a flush on saving: T53986. */ if ((ob->sculpt && ob->sculpt->cache) == 0) { /* flush multires changes (for sculpt) */ multires_force_update(ob); has_edited = true; if (for_render) { /* flush changes from dynamic topology sculpt */ BKE_sculptsession_bm_to_me_for_render(ob); } else { /* Set reorder=false so that saving the file doesn't reorder * the BMesh's elements */ BKE_sculptsession_bm_to_me(ob, false); } } } else if (ob->mode & OB_MODE_EDIT) { /* get editmode results */ has_edited = true; ED_object_editmode_load(bmain, ob); } } return has_edited; }
/* flush any temp data from object editing to DNA before writing files, * rendering, copying, etc. */ void ED_editors_flush_edits(const bContext *C, bool for_render) { Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); /* get editmode results */ if (obedit) ED_object_editmode_load(obedit); if (obact && (obact->mode & OB_MODE_SCULPT)) { /* flush multires changes (for sculpt) */ multires_force_update(obact); if (for_render) { /* flush changes from dynamic topology sculpt */ sculptsession_bm_to_me_for_render(obact); } else { /* Set reorder=false so that saving the file doesn't reorder * the BMesh's elements */ sculptsession_bm_to_me(obact, FALSE); } } }
/* 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; }
/* function used for WM_OT_save_mainfile too */ static int wm_collada_export_exec(bContext *C, wmOperator *op) { char filepath[FILE_MAX]; int apply_modifiers; int export_mesh_type; int selected; int include_children; int include_armatures; int include_shapekeys; int deform_bones_only; int include_uv_textures; int include_material_textures; int use_texture_copies; int active_uv_only; int triangulate; int use_object_instantiation; int sort_by_name; int export_transformation_type; int open_sim; int export_count; if (!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); return OPERATOR_CANCELLED; } RNA_string_get(op->ptr, "filepath", filepath); BLI_ensure_extension(filepath, sizeof(filepath), ".dae"); /* Avoid File write exceptions in Collada */ if (!BLI_exists(filepath)) { BLI_make_existing_file(filepath); if (!BLI_file_touch(filepath)) { BKE_report(op->reports, RPT_ERROR, "Can't create export file"); fprintf(stdout, "Collada export: Can not create: %s\n", filepath); return OPERATOR_CANCELLED; } } else if (!BLI_file_is_writable(filepath)) { BKE_report(op->reports, RPT_ERROR, "Can't overwrite export file"); fprintf(stdout, "Collada export: Can not modify: %s\n", filepath); return OPERATOR_CANCELLED; } /* Now the exporter can create and write the export file */ /* Options panel */ apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers"); export_mesh_type = RNA_enum_get(op->ptr, "export_mesh_type_selection"); selected = RNA_boolean_get(op->ptr, "selected"); include_children = RNA_boolean_get(op->ptr, "include_children"); include_armatures = RNA_boolean_get(op->ptr, "include_armatures"); include_shapekeys = RNA_boolean_get(op->ptr, "include_shapekeys"); deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only"); include_uv_textures = RNA_boolean_get(op->ptr, "include_uv_textures"); include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures"); use_texture_copies = RNA_boolean_get(op->ptr, "use_texture_copies"); active_uv_only = RNA_boolean_get(op->ptr, "active_uv_only"); triangulate = RNA_boolean_get(op->ptr, "triangulate"); use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation"); sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name"); export_transformation_type = RNA_enum_get(op->ptr, "export_transformation_type_selection"); open_sim = RNA_boolean_get(op->ptr, "open_sim"); /* get editmode results */ ED_object_editmode_load(CTX_data_edit_object(C)); export_count = collada_export(CTX_data_scene(C), filepath, apply_modifiers, export_mesh_type, selected, include_children, include_armatures, include_shapekeys, deform_bones_only, active_uv_only, include_uv_textures, include_material_textures, use_texture_copies, triangulate, use_object_instantiation, sort_by_name, export_transformation_type, open_sim); if (export_count == 0) { BKE_report(op->reports, RPT_WARNING, "Export file is empty"); return OPERATOR_CANCELLED; } else { char buff[100]; sprintf(buff, "Exported %d Objects", export_count); BKE_report(op->reports, RPT_INFO, buff); return OPERATOR_FINISHED; } }
static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C) { RegionView3D *rv3d = CTX_wm_region_view3d(C); View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); Render *re; rctf viewplane; rcti disprect; float clipsta, clipend; bool orth; int job_update_flag = 0; char name[32]; /* ensure render engine exists */ re = engine->re; if (!re) { sprintf(name, "View3dPreview %p", (void *)ar); re = engine->re = RE_GetRender(name); if (!re) re = engine->re = RE_NewRender(name); engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; } /* check update_flag */ if (engine->update_flag & RE_ENGINE_UPDATE_MA) job_update_flag |= PR_UPDATE_MATERIAL; if (engine->update_flag & RE_ENGINE_UPDATE_OTHER) job_update_flag |= PR_UPDATE_MATERIAL; if (engine->update_flag & RE_ENGINE_UPDATE_DATABASE) { job_update_flag |= PR_UPDATE_DATABASE; /* load editmesh */ if (scene->obedit) ED_object_editmode_load(scene->obedit); } engine->update_flag = 0; /* check if viewport changed */ if (engine->last_winx != ar->winx || engine->last_winy != ar->winy) { engine->last_winx = ar->winx; engine->last_winy = ar->winy; job_update_flag |= PR_UPDATE_RENDERSIZE; } if (compare_m4m4(engine->last_viewmat, rv3d->viewmat, 0.00001f) == 0) { copy_m4_m4(engine->last_viewmat, rv3d->viewmat); job_update_flag |= PR_UPDATE_VIEW; } render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth); if (BLI_rctf_compare(&viewplane, &engine->last_viewplane, 0.00001f) == 0) { engine->last_viewplane = viewplane; job_update_flag |= PR_UPDATE_VIEW; } render_view3d_disprect(scene, ar, v3d, rv3d, &disprect); if (BLI_rcti_compare(&disprect, &engine->last_disprect) == 0) { engine->last_disprect = disprect; job_update_flag |= PR_UPDATE_RENDERSIZE; } /* any changes? go ahead and rerender */ if (job_update_flag) { engine->job_update_flag |= job_update_flag; return true; } return false; }
int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList *reports) { Library *li; int len; int *thumb = NULL; ImBuf *ibuf_thumb = NULL; len = strlen(filepath); if (len == 0) { BKE_report(reports, RPT_ERROR, "Path is empty, cannot save"); return -1; } if (len >= FILE_MAX) { BKE_report(reports, RPT_ERROR, "Path too long, cannot save"); return -1; } /* 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 -1; } } /* blend file thumbnail */ /* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */ if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) { ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb); } BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); /* operator now handles overwrite checks */ if (G.fileflags & G_AUTOPACK) { packAll(G.main, reports); } ED_object_editmode_load(CTX_data_edit_object(C)); ED_sculpt_force_update(C); /* don't forget not to return without! */ WM_cursor_wait(1); 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)) { 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 */ } if (fileflags & G_FILE_COMPRESS) G.fileflags |= G_FILE_COMPRESS; else G.fileflags &= ~G_FILE_COMPRESS; if (fileflags & G_FILE_AUTOPLAY) G.fileflags |= G_FILE_AUTOPLAY; else G.fileflags &= ~G_FILE_AUTOPLAY; /* prevent background mode scripts from clobbering history */ if (!G.background) { write_history(); } 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_NORMAL, THB_SOURCE_BLEND, ibuf_thumb); IMB_freeImBuf(ibuf_thumb); } if (thumb) MEM_freeN(thumb); } else { if (ibuf_thumb) IMB_freeImBuf(ibuf_thumb); if (thumb) MEM_freeN(thumb); WM_cursor_wait(0); return -1; } WM_cursor_wait(0); return 0; }
static int rna_Object_update_from_editmode(Object *ob) { return ED_object_editmode_load(ob); }