diff --git a/source/blender/editors/render/render_opengl.cc b/source/blender/editors/render/render_opengl.cc index 410eb6f5408..36789fd2976 100644 --- a/source/blender/editors/render/render_opengl.cc +++ b/source/blender/editors/render/render_opengl.cc @@ -127,9 +127,6 @@ struct OGLRender : public RenderJobBase { int totvideos = 0; - /* For only rendering frames that have a key in animation data. */ - BLI_bitmap *render_frames = nullptr; - /* quick lookup */ int view_id = 0; @@ -520,183 +517,6 @@ static void screen_opengl_render_apply(OGLRender *oglrender) } } -static void gather_frames_to_render_for_adt(const OGLRender *oglrender, const AnimData *adt) -{ - if (adt == nullptr || adt->action == nullptr) { - return; - } - - Scene *scene = oglrender->scene; - int frame_start = PSFRA; - int frame_end = PEFRA; - - for (const FCurve *fcu : blender::animrig::legacy::fcurves_for_assigned_action(adt)) { - if (fcu->driver != nullptr || fcu->fpt != nullptr) { - /* Drivers have values for any point in time, so to get "the keyed frames" they are - * useless. Same for baked FCurves, they also have keys for every frame, which is not - * useful for rendering the keyed subset of the frames. */ - continue; - } - - bool found = false; /* Not interesting, we just want a starting point for the for-loop. */ - int key_index = BKE_fcurve_bezt_binarysearch_index( - fcu->bezt, frame_start, fcu->totvert, &found); - for (; key_index < fcu->totvert; key_index++) { - BezTriple *bezt = &fcu->bezt[key_index]; - /* The frame range to render uses integer frame numbers, and the frame - * step is also an integer, so we always render on the frame. */ - int frame_nr = round_fl_to_int(bezt->vec[1][0]); - - /* (frame_nr < frame_start) cannot happen because of the binary search above. */ - BLI_assert(frame_nr >= frame_start); - if (frame_nr > frame_end) { - break; - } - BLI_BITMAP_ENABLE(oglrender->render_frames, frame_nr - frame_start); - } - } -} - -static void gather_frames_to_render_for_grease_pencil(const OGLRender *oglrender, - const bGPdata *gp) -{ - if (gp == nullptr) { - return; - } - - Scene *scene = oglrender->scene; - int frame_start = PSFRA; - int frame_end = PEFRA; - - LISTBASE_FOREACH (const bGPDlayer *, gp_layer, &gp->layers) { - LISTBASE_FOREACH (const bGPDframe *, gp_frame, &gp_layer->frames) { - if (gp_frame->framenum < frame_start || gp_frame->framenum > frame_end) { - continue; - } - BLI_BITMAP_ENABLE(oglrender->render_frames, gp_frame->framenum - frame_start); - } - } -} - -static int gather_frames_to_render_for_id(LibraryIDLinkCallbackData *cb_data) -{ - ID **id_p = cb_data->id_pointer; - if (*id_p == nullptr) { - return IDWALK_RET_NOP; - } - ID *id = *id_p; - - ID *self_id = cb_data->self_id; - const LibraryForeachIDCallbackFlag cb_flag = cb_data->cb_flag; - if (cb_flag == IDWALK_CB_LOOPBACK || id == self_id) { - /* IDs may end up referencing themselves one way or the other, and those - * (the self_id ones) have always already been processed. */ - return IDWALK_RET_STOP_RECURSION; - } - - OGLRender *oglrender = static_cast(cb_data->user_data); - - /* Whitelist of datablocks to follow pointers into. */ - const ID_Type id_type = GS(id->name); - switch (id_type) { - /* Whitelist: */ - case ID_ME: /* Mesh */ - case ID_CU_LEGACY: /* Curve */ - case ID_MB: /* MetaBall */ - case ID_MA: /* Material */ - case ID_TE: /* Tex (Texture) */ - case ID_IM: /* Image */ - case ID_LT: /* Lattice */ - case ID_LA: /* Light */ - case ID_CA: /* Camera */ - case ID_KE: /* Key (shape key) */ - case ID_VF: /* VFont (Vector Font) */ - case ID_TXT: /* Text */ - case ID_SPK: /* Speaker */ - case ID_SO: /* Sound */ - case ID_AR: /* bArmature */ - case ID_NT: /* bNodeTree */ - case ID_PA: /* ParticleSettings */ - case ID_MC: /* MovieClip */ - case ID_MSK: /* Mask */ - case ID_LP: /* LightProbe */ - case ID_CV: /* Curves */ - case ID_PT: /* PointCloud */ - case ID_VO: /* Volume */ - break; - - /* Blacklist: */ - case ID_SCE: /* Scene */ - case ID_LI: /* Library */ - case ID_OB: /* Object */ - case ID_WO: /* World */ - case ID_SCR: /* Screen */ - case ID_GR: /* Group */ - case ID_AC: /* bAction */ - case ID_BR: /* Brush */ - case ID_WM: /* WindowManager */ - case ID_LS: /* FreestyleLineStyle */ - case ID_PAL: /* Palette */ - case ID_PC: /* PaintCurve */ - case ID_CF: /* CacheFile */ - case ID_WS: /* WorkSpace */ - /* Only follow pointers to specific datablocks, to avoid ending up in - * unrelated datablocks and exploding the number of blocks we follow. If the - * frames of the animation of certain objects should be taken into account, - * they should have been selected by the user. */ - return IDWALK_RET_STOP_RECURSION; - - /* Special cases: */ - case ID_GD_LEGACY: /* bGPdata, (Grease Pencil) */ - /* In addition to regular ID's animdata, GreasePencil uses a specific frame-based animation - * system that requires specific handling here. */ - gather_frames_to_render_for_grease_pencil(oglrender, (bGPdata *)id); - break; - case ID_GP: - /* TODO: gather frames. */ - break; - } - - AnimData *adt = BKE_animdata_from_id(id); - gather_frames_to_render_for_adt(oglrender, adt); - - return IDWALK_RET_NOP; -} - -/** - * Collect the frame numbers for which selected objects have keys in the animation data. - * The frames ares stored in #OGLRender.render_frames. - * - * Note that this follows all pointers to ID blocks, only filtering on ID type, - * so it will pick up keys from pointers in custom properties as well. - */ -static void gather_frames_to_render(bContext *C, OGLRender *oglrender) -{ - Scene *scene = oglrender->scene; - int frame_start = PSFRA; - int frame_end = PEFRA; - - /* Will be freed in screen_opengl_render_end(). */ - oglrender->render_frames = BLI_BITMAP_NEW(frame_end - frame_start + 1, - "OGLRender::render_frames"); - - /* The first frame should always be rendered, otherwise there is nothing to write to file. */ - BLI_BITMAP_ENABLE(oglrender->render_frames, 0); - - CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { - ID *id = &ob->id; - - /* Gather the frames from the object animation data. */ - AnimData *adt = BKE_animdata_from_id(id); - gather_frames_to_render_for_adt(oglrender, adt); - - /* Gather the frames from linked data-blocks (materials, shape-keys, etc.). */ - BKE_library_foreach_ID_link( - nullptr, id, gather_frames_to_render_for_id, oglrender, IDWALK_RECURSE); - } - CTX_DATA_END; -} - static bool screen_opengl_render_init(bContext *C, wmOperator *op) { /* new render clears all callbacks */ @@ -717,7 +537,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) int sizex, sizey; bool is_view_context = RNA_boolean_get(op->ptr, "view_context"); const bool is_animation = RNA_boolean_get(op->ptr, "animation"); - const bool is_render_keyed_only = RNA_boolean_get(op->ptr, "render_keyed_only"); const bool is_write_still = RNA_boolean_get(op->ptr, "write_still"); const eImageFormatDepth color_depth = static_cast( (is_animation) ? (eImageFormatDepth)scene->r.im_format.depth : R_IMF_CHAN_DEPTH_32); @@ -857,10 +676,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) oglrender->win = win; if (is_animation) { - if (is_render_keyed_only) { - gather_frames_to_render(C, oglrender); - } - if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { oglrender->task_pool = BLI_task_pool_create_background_serial(oglrender, TASK_PRIORITY_HIGH); } @@ -904,8 +719,6 @@ static void screen_opengl_render_end(OGLRender *oglrender) oglrender->task_pool = nullptr; } - MEM_SAFE_FREE(oglrender->render_frames); - if (!oglrender->movie_writers.is_empty()) { if (BKE_imtype_is_movie(oglrender->scene->r.im_format.imtype)) { for (MovieWriter *writer : oglrender->movie_writers) { @@ -1211,12 +1024,8 @@ static bool screen_opengl_render_anim_step(OGLRender *oglrender) BKE_scene_camera_switch_update(scene); } - if (oglrender->render_frames == nullptr || - BLI_BITMAP_TEST_BOOL(oglrender->render_frames, scene->r.cfra - PSFRA)) - { - /* render into offscreen buffer */ - screen_opengl_render_apply(oglrender); - } + /* render into offscreen buffer */ + screen_opengl_render_apply(oglrender); /* save to disk */ rr = RE_AcquireResultRead(oglrender->re); @@ -1393,13 +1202,6 @@ static std::string screen_opengl_render_get_description(bContext * /*C*/, if (!RNA_boolean_get(ptr, "animation")) { return ""; } - - if (RNA_boolean_get(ptr, "render_keyed_only")) { - return TIP_( - "Render the viewport for the animation range of this scene, but only render keyframes of " - "selected objects"); - } - return TIP_("Render the viewport for the animation range of this scene"); } @@ -1428,14 +1230,6 @@ void RENDER_OT_opengl(wmOperatorType *ot) "Render files from the animation range of this scene"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, - "render_keyed_only", - false, - "Render Keyframes Only", - "Render only those frames where selected objects have a key in their " - "animation data. Only used when rendering animation"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean( ot->srna, "sequencer", false, "Sequencer", "Render using the sequencer's OpenGL display"); RNA_def_property_flag(prop, PROP_SKIP_SAVE);