diff --git a/source/blender/editors/animation/keyframes_general.cc b/source/blender/editors/animation/keyframes_general.cc index 75ae78f7d23..3549e55ea34 100644 --- a/source/blender/editors/animation/keyframes_general.cc +++ b/source/blender/editors/animation/keyframes_general.cc @@ -1971,7 +1971,7 @@ static void paste_animedit_keys_fcurve(FCurve *fcu, BezTriple bezt_copy = *bezt; if (flip) { - do_curve_mirror_flippping(*fcu, bezt_copy); + do_curve_mirror_flippping(fcurve_in_copy_buffer, bezt_copy); } add_v2_v2(bezt_copy.vec[0], offset); diff --git a/source/blender/editors/curves/intern/curves_data.cc b/source/blender/editors/curves/intern/curves_data.cc index f5ae554f01d..fa73bf394dd 100644 --- a/source/blender/editors/curves/intern/curves_data.cc +++ b/source/blender/editors/curves/intern/curves_data.cc @@ -22,22 +22,44 @@ Vector> get_curves_positions_for_write(bke::CurvesGeometry & return positions_per_attribute; } -void transverts_from_curves_positions_create(bke::CurvesGeometry &curves, TransVertStore *tvs) +void transverts_from_curves_positions_create(bke::CurvesGeometry &curves, + TransVertStore *tvs, + const bool skip_handles) { + const Span selection_names = ed::curves::get_curves_selection_attribute_names(curves); + IndexMaskMemory memory; - IndexMask selection = retrieve_selected_points(curves, memory); - MutableSpan positions = curves.positions_for_write(); + std::array selection; + for (const int i : selection_names.index_range()) { + selection[i] = ed::curves::retrieve_selected_points(curves, selection_names[i], memory); + } - tvs->transverts = static_cast( - MEM_calloc_arrayN(selection.size(), sizeof(TransVert), __func__)); - tvs->transverts_tot = selection.size(); + if (skip_handles) { + /* When the control point is selected, both handles are ignored. */ + selection[1] = IndexMask::from_difference(selection[1], selection[0], memory); + selection[2] = IndexMask::from_difference(selection[2], selection[0], memory); + } - selection.foreach_index(GrainSize(1024), [&](const int64_t i, const int64_t pos) { - TransVert &tv = tvs->transverts[pos]; - tv.loc = positions[i]; - tv.flag = SELECT; - copy_v3_v3(tv.oldloc, tv.loc); - }); + const int size = selection[0].size() + selection[1].size() + selection[2].size(); + if (size == 0) { + return; + } + + tvs->transverts = static_cast(MEM_calloc_arrayN(size, sizeof(TransVert), __func__)); + tvs->transverts_tot = size; + + int offset = 0; + const Vector> positions = ed::curves::get_curves_positions_for_write(curves); + for (const int attribute_i : positions.index_range()) { + selection[attribute_i].foreach_index(GrainSize(1024), [&](const int64_t i, const int64_t pos) { + TransVert &tv = tvs->transverts[pos + offset]; + tv.loc = positions[attribute_i][i]; + tv.flag = SELECT; + copy_v3_v3(tv.oldloc, tv.loc); + }); + + offset += selection[attribute_i].size(); + } } float (*point_normals_array_create(const Curves *curves_id))[3] diff --git a/source/blender/editors/include/ED_curves.hh b/source/blender/editors/include/ED_curves.hh index 6512a1ea0fc..63e5f5a520d 100644 --- a/source/blender/editors/include/ED_curves.hh +++ b/source/blender/editors/include/ED_curves.hh @@ -119,7 +119,9 @@ void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob); * `ED_transverts_create_from_obedit` in `view3d_snap.cc`). * \note The `TransVert` elements in \a tvs are expected to write to the positions of \a curves. */ -void transverts_from_curves_positions_create(bke::CurvesGeometry &curves, TransVertStore *tvs); +void transverts_from_curves_positions_create(bke::CurvesGeometry &curves, + TransVertStore *tvs, + const bool skip_handles); /* -------------------------------------------------------------------- */ /** \name Poll Functions diff --git a/source/blender/editors/render/render_opengl.cc b/source/blender/editors/render/render_opengl.cc index 3c9da1794b2..bc02ecfa906 100644 --- a/source/blender/editors/render/render_opengl.cc +++ b/source/blender/editors/render/render_opengl.cc @@ -694,6 +694,8 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); + ScrArea *prev_area = CTX_wm_area(C); + ARegion *prev_region = CTX_wm_region(C); GPUOffScreen *ofs; OGLRender *oglrender; int sizex, sizey; @@ -717,6 +719,12 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) return false; } + 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 false; + } + if (is_sequencer) { is_view_context = false; } @@ -733,12 +741,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) } } - 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 false; - } - /* stop all running jobs, except screen one. currently previews frustrate Render */ WM_jobs_kill_all_except(wm, CTX_wm_screen(C)); @@ -757,6 +759,8 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) if (!ofs) { BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out); + CTX_wm_area_set(C, prev_area); + CTX_wm_region_set(C, prev_region); return false; } @@ -851,6 +855,9 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) } } + CTX_wm_area_set(C, prev_area); + CTX_wm_region_set(C, prev_region); + return true; } diff --git a/source/blender/editors/util/ed_transverts.cc b/source/blender/editors/util/ed_transverts.cc index 4bc322eca46..9f9028f0015 100644 --- a/source/blender/editors/util/ed_transverts.cc +++ b/source/blender/editors/util/ed_transverts.cc @@ -514,7 +514,8 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, const Object *obedit, } else if (obedit->type == OB_CURVES) { Curves *curves_id = static_cast(obedit->data); - blender::ed::curves::transverts_from_curves_positions_create(curves_id->geometry.wrap(), tvs); + blender::ed::curves::transverts_from_curves_positions_create( + curves_id->geometry.wrap(), tvs, ((mode & TM_SKIP_HANDLES) != 0)); } else if (obedit->type == OB_POINTCLOUD) { PointCloud *pointcloud = static_cast(obedit->data);