Add Chromium-only Blender WebEngine parity work
This commit is contained in:
47
blender-5.2.0/source/blender/editors/curve/CMakeLists.txt
Normal file
47
blender-5.2.0/source/blender/editors/curve/CMakeLists.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
# SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(INC
|
||||
../include
|
||||
../../makesrna
|
||||
# RNA_prototypes.hh
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
curve_ops.cc
|
||||
editcurve.cc
|
||||
editcurve_add.cc
|
||||
editcurve_paint.cc
|
||||
editcurve_pen.cc
|
||||
editcurve_query.cc
|
||||
editcurve_select.cc
|
||||
editcurve_undo.cc
|
||||
editfont.cc
|
||||
editfont_undo.cc
|
||||
|
||||
curve_intern.hh
|
||||
)
|
||||
|
||||
set(LIB
|
||||
PRIVATE bf::blenkernel
|
||||
PRIVATE bf::animrig
|
||||
PRIVATE bf::blenlib
|
||||
PRIVATE bf::blentranslation
|
||||
PRIVATE bf::depsgraph
|
||||
PRIVATE bf::dna
|
||||
PRIVATE bf::extern::curve_fit_nd
|
||||
PRIVATE bf::gpu
|
||||
PRIVATE bf::intern::clog
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
PRIVATE bf::windowmanager
|
||||
)
|
||||
|
||||
blender_add_lib(bf_editor_curve "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
# RNA_prototypes.hh
|
||||
add_dependencies(bf_editor_curve bf_rna)
|
||||
254
blender-5.2.0/source/blender/editors/curve/curve_intern.hh
Normal file
254
blender-5.2.0/source/blender/editors/curve/curve_intern.hh
Normal file
@@ -0,0 +1,254 @@
|
||||
/* SPDX-FileCopyrightText: 2008 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edcurve
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/* internal exports only */
|
||||
struct BPoint;
|
||||
struct Base;
|
||||
struct BezTriple;
|
||||
struct Curve;
|
||||
struct EditNurb;
|
||||
struct Nurb;
|
||||
struct Object;
|
||||
struct View3D;
|
||||
struct ViewContext;
|
||||
struct wmKeyConfig;
|
||||
struct wmKeyMap;
|
||||
struct wmOperatorType;
|
||||
|
||||
/* `editfont.cc` */
|
||||
|
||||
enum {
|
||||
DEL_NEXT_CHAR,
|
||||
DEL_PREV_CHAR,
|
||||
DEL_NEXT_WORD,
|
||||
DEL_PREV_WORD,
|
||||
DEL_SELECTION,
|
||||
DEL_NEXT_SEL,
|
||||
DEL_PREV_SEL
|
||||
};
|
||||
enum { CASE_LOWER, CASE_UPPER };
|
||||
enum {
|
||||
LINE_BEGIN,
|
||||
LINE_END,
|
||||
TEXT_BEGIN,
|
||||
TEXT_END,
|
||||
PREV_CHAR,
|
||||
NEXT_CHAR,
|
||||
PREV_WORD,
|
||||
NEXT_WORD,
|
||||
PREV_LINE,
|
||||
NEXT_LINE,
|
||||
PREV_PAGE,
|
||||
NEXT_PAGE
|
||||
};
|
||||
|
||||
enum eVisible_Types {
|
||||
HIDDEN = true,
|
||||
VISIBLE = false,
|
||||
};
|
||||
|
||||
enum eEndPoint_Types {
|
||||
FIRST = true,
|
||||
LAST = false,
|
||||
};
|
||||
|
||||
enum eCurveElem_Types {
|
||||
CURVE_VERTEX = 0,
|
||||
CURVE_SEGMENT,
|
||||
};
|
||||
|
||||
/* internal select utils */
|
||||
/**
|
||||
* Returns 1 in case (de)selection was successful.
|
||||
*/
|
||||
bool select_beztriple(BezTriple *bezt,
|
||||
bool selstatus,
|
||||
eBezTriple_Flag flag,
|
||||
eVisible_Types hidden);
|
||||
/**
|
||||
* Returns 1 in case (de)selection was successful.
|
||||
*/
|
||||
bool select_bpoint(BPoint *bp, bool selstatus, eBezTriple_Flag flag, bool hidden);
|
||||
|
||||
void FONT_OT_text_insert(wmOperatorType *ot);
|
||||
void FONT_OT_line_break(wmOperatorType *ot);
|
||||
|
||||
void FONT_OT_case_toggle(wmOperatorType *ot);
|
||||
void FONT_OT_case_set(wmOperatorType *ot);
|
||||
void FONT_OT_style_toggle(wmOperatorType *ot);
|
||||
void FONT_OT_style_set(wmOperatorType *ot);
|
||||
|
||||
void FONT_OT_select_all(wmOperatorType *ot);
|
||||
|
||||
void FONT_OT_text_copy(wmOperatorType *ot);
|
||||
void FONT_OT_text_cut(wmOperatorType *ot);
|
||||
void FONT_OT_text_paste(wmOperatorType *ot);
|
||||
void FONT_OT_text_paste_from_file(wmOperatorType *ot);
|
||||
void FONT_OT_text_insert_unicode(wmOperatorType *ot);
|
||||
|
||||
void FONT_OT_selection_set(wmOperatorType *ot);
|
||||
void FONT_OT_select_word(wmOperatorType *ot);
|
||||
|
||||
void FONT_OT_move(wmOperatorType *ot);
|
||||
void FONT_OT_move_select(wmOperatorType *ot);
|
||||
void FONT_OT_delete(wmOperatorType *ot);
|
||||
|
||||
void FONT_OT_change_character(wmOperatorType *ot);
|
||||
void FONT_OT_change_spacing(wmOperatorType *ot);
|
||||
|
||||
void FONT_OT_open(wmOperatorType *ot);
|
||||
void FONT_OT_unlink(wmOperatorType *ot);
|
||||
|
||||
void FONT_OT_textbox_add(wmOperatorType *ot);
|
||||
void FONT_OT_textbox_remove(wmOperatorType *ot);
|
||||
|
||||
/* `editcurve.cc` */
|
||||
|
||||
void CURVE_OT_hide(wmOperatorType *ot);
|
||||
void CURVE_OT_reveal(wmOperatorType *ot);
|
||||
|
||||
void CURVE_OT_separate(wmOperatorType *ot);
|
||||
void CURVE_OT_split(wmOperatorType *ot);
|
||||
void CURVE_OT_duplicate(wmOperatorType *ot);
|
||||
void CURVE_OT_delete(wmOperatorType *ot);
|
||||
void CURVE_OT_dissolve_verts(wmOperatorType *ot);
|
||||
|
||||
void CURVE_OT_spline_type_set(wmOperatorType *ot);
|
||||
void CURVE_OT_radius_set(wmOperatorType *ot);
|
||||
void CURVE_OT_spline_weight_set(wmOperatorType *ot);
|
||||
void CURVE_OT_handle_type_set(wmOperatorType *ot);
|
||||
void CURVE_OT_normals_make_consistent(wmOperatorType *ot);
|
||||
void CURVE_OT_decimate(wmOperatorType *ot);
|
||||
void CURVE_OT_shade_smooth(wmOperatorType *ot);
|
||||
void CURVE_OT_shade_flat(wmOperatorType *ot);
|
||||
void CURVE_OT_tilt_clear(wmOperatorType *ot);
|
||||
|
||||
void CURVE_OT_smooth(wmOperatorType *ot);
|
||||
void CURVE_OT_smooth_weight(wmOperatorType *ot);
|
||||
void CURVE_OT_smooth_radius(wmOperatorType *ot);
|
||||
void CURVE_OT_smooth_tilt(wmOperatorType *ot);
|
||||
|
||||
void CURVE_OT_switch_direction(wmOperatorType *ot);
|
||||
void CURVE_OT_subdivide(wmOperatorType *ot);
|
||||
void CURVE_OT_make_segment(wmOperatorType *ot);
|
||||
void CURVE_OT_spin(wmOperatorType *ot);
|
||||
void CURVE_OT_vertex_add(wmOperatorType *ot);
|
||||
void CURVE_OT_extrude(wmOperatorType *ot);
|
||||
void CURVE_OT_cyclic_toggle(wmOperatorType *ot);
|
||||
|
||||
void CURVE_OT_match_texture_space(wmOperatorType *ot);
|
||||
|
||||
/* exported for editcurve_undo.cc */
|
||||
|
||||
CVKeyIndexMap *ED_curve_keyindex_hash_duplicate(CVKeyIndexMap *keyindex);
|
||||
void ED_curve_keyindex_update_nurb(EditNurb *editnurb, Nurb *nu, Nurb *newnu);
|
||||
|
||||
/* exported for `editcurve_pen.cc` */
|
||||
|
||||
int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, View3D *v3d, const float location_init[3]);
|
||||
bool curve_toggle_cyclic(View3D *v3d, ListBaseT<Nurb> *editnurb, int direction);
|
||||
void ed_dissolve_bez_segment(BezTriple *bezt_prev,
|
||||
BezTriple *bezt_next,
|
||||
const Nurb *nu,
|
||||
const Curve *cu,
|
||||
const uint span_len,
|
||||
const uint span_step[2]);
|
||||
|
||||
/* helper functions */
|
||||
void ed_editnurb_translate_flag(ListBaseT<Nurb> *editnurb,
|
||||
eBezTriple_Flag flag,
|
||||
const float vec[3],
|
||||
bool is_2d);
|
||||
/**
|
||||
* Only for #OB_SURF.
|
||||
*/
|
||||
bool ed_editnurb_extrude_flag(EditNurb *editnurb, eBezTriple_Flag flag);
|
||||
/**
|
||||
* \param axis: is in world-space.
|
||||
* \param cent: is in object-space.
|
||||
*/
|
||||
bool ed_editnurb_spin(
|
||||
float viewmat[4][4], View3D *v3d, Object *obedit, const float axis[3], const float cent[3]);
|
||||
|
||||
/* `editcurve_select.cc` */
|
||||
|
||||
void CURVE_OT_de_select_first(wmOperatorType *ot);
|
||||
void CURVE_OT_de_select_last(wmOperatorType *ot);
|
||||
void CURVE_OT_select_all(wmOperatorType *ot);
|
||||
void CURVE_OT_select_linked(wmOperatorType *ot);
|
||||
void CURVE_OT_select_linked_pick(wmOperatorType *ot);
|
||||
void CURVE_OT_select_row(wmOperatorType *ot);
|
||||
void CURVE_OT_select_next(wmOperatorType *ot);
|
||||
void CURVE_OT_select_previous(wmOperatorType *ot);
|
||||
void CURVE_OT_select_more(wmOperatorType *ot);
|
||||
void CURVE_OT_select_less(wmOperatorType *ot);
|
||||
void CURVE_OT_select_random(wmOperatorType *ot);
|
||||
void CURVE_OT_select_nth(wmOperatorType *ot);
|
||||
void CURVE_OT_select_similar(wmOperatorType *ot);
|
||||
void CURVE_OT_shortest_path_pick(wmOperatorType *ot);
|
||||
|
||||
/* `editcurve_add.cc` */
|
||||
|
||||
void CURVE_OT_primitive_bezier_curve_add(wmOperatorType *ot);
|
||||
void CURVE_OT_primitive_bezier_circle_add(wmOperatorType *ot);
|
||||
void CURVE_OT_primitive_nurbs_curve_add(wmOperatorType *ot);
|
||||
void CURVE_OT_primitive_nurbs_circle_add(wmOperatorType *ot);
|
||||
void CURVE_OT_primitive_nurbs_path_add(wmOperatorType *ot);
|
||||
|
||||
void SURFACE_OT_primitive_nurbs_surface_curve_add(wmOperatorType *ot);
|
||||
void SURFACE_OT_primitive_nurbs_surface_circle_add(wmOperatorType *ot);
|
||||
void SURFACE_OT_primitive_nurbs_surface_surface_add(wmOperatorType *ot);
|
||||
void SURFACE_OT_primitive_nurbs_surface_cylinder_add(wmOperatorType *ot);
|
||||
void SURFACE_OT_primitive_nurbs_surface_sphere_add(wmOperatorType *ot);
|
||||
void SURFACE_OT_primitive_nurbs_surface_torus_add(wmOperatorType *ot);
|
||||
|
||||
/* `editcurve_query.cc` */
|
||||
|
||||
bool ED_curve_pick_vert(ViewContext *vc,
|
||||
short sel,
|
||||
Nurb **r_nurb,
|
||||
BezTriple **r_bezt,
|
||||
BPoint **r_bp,
|
||||
short *r_handle,
|
||||
Base **r_base);
|
||||
/**
|
||||
* Pick the nearest `r_nurb` and `r_bezt` or `r_bp`.
|
||||
* \param select: selected vertices have a disadvantage.
|
||||
* \param dist_px: The selection distance in pixels.
|
||||
* \param r_handle: For bezier triples, set the handle index [0, 1, 2].
|
||||
*/
|
||||
bool ED_curve_pick_vert_ex(ViewContext *vc,
|
||||
bool select,
|
||||
int dist_px,
|
||||
Nurb **r_nurb,
|
||||
BezTriple **r_bezt,
|
||||
BPoint **r_bp,
|
||||
short *r_handle,
|
||||
Base **r_base);
|
||||
void ED_curve_nurb_vert_selected_find(
|
||||
Curve *cu, View3D *v3d, Nurb **r_nu, BezTriple **r_bezt, BPoint **r_bp);
|
||||
|
||||
/* `editcurve_paint.cc` */
|
||||
|
||||
void CURVE_OT_draw(wmOperatorType *ot);
|
||||
|
||||
/* `editcurve_pen.cc` */
|
||||
|
||||
void CURVE_OT_pen(wmOperatorType *ot);
|
||||
wmKeyMap *curve_pen_modal_keymap(wmKeyConfig *keyconf);
|
||||
|
||||
} // namespace blender
|
||||
161
blender-5.2.0/source/blender/editors/curve/curve_ops.cc
Normal file
161
blender-5.2.0/source/blender/editors/curve/curve_ops.cc
Normal file
@@ -0,0 +1,161 @@
|
||||
/* SPDX-FileCopyrightText: 2009 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edcurve
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "RNA_access.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "ED_curve.hh"
|
||||
#include "ED_screen.hh"
|
||||
|
||||
#include "curve_intern.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/************************* registration ****************************/
|
||||
|
||||
void ED_operatortypes_curve()
|
||||
{
|
||||
WM_operatortype_append(FONT_OT_text_insert);
|
||||
WM_operatortype_append(FONT_OT_line_break);
|
||||
|
||||
WM_operatortype_append(FONT_OT_case_toggle);
|
||||
WM_operatortype_append(FONT_OT_case_set);
|
||||
WM_operatortype_append(FONT_OT_style_toggle);
|
||||
WM_operatortype_append(FONT_OT_style_set);
|
||||
|
||||
WM_operatortype_append(FONT_OT_select_all);
|
||||
|
||||
WM_operatortype_append(FONT_OT_text_copy);
|
||||
WM_operatortype_append(FONT_OT_text_cut);
|
||||
WM_operatortype_append(FONT_OT_text_paste);
|
||||
WM_operatortype_append(FONT_OT_text_paste_from_file);
|
||||
WM_operatortype_append(FONT_OT_text_insert_unicode);
|
||||
|
||||
WM_operatortype_append(FONT_OT_selection_set);
|
||||
WM_operatortype_append(FONT_OT_select_word);
|
||||
|
||||
WM_operatortype_append(FONT_OT_move);
|
||||
WM_operatortype_append(FONT_OT_move_select);
|
||||
WM_operatortype_append(FONT_OT_delete);
|
||||
|
||||
WM_operatortype_append(FONT_OT_change_character);
|
||||
WM_operatortype_append(FONT_OT_change_spacing);
|
||||
|
||||
WM_operatortype_append(FONT_OT_open);
|
||||
WM_operatortype_append(FONT_OT_unlink);
|
||||
|
||||
WM_operatortype_append(FONT_OT_textbox_add);
|
||||
WM_operatortype_append(FONT_OT_textbox_remove);
|
||||
|
||||
WM_operatortype_append(CURVE_OT_hide);
|
||||
WM_operatortype_append(CURVE_OT_reveal);
|
||||
|
||||
WM_operatortype_append(CURVE_OT_separate);
|
||||
WM_operatortype_append(CURVE_OT_split);
|
||||
WM_operatortype_append(CURVE_OT_duplicate);
|
||||
WM_operatortype_append(CURVE_OT_delete);
|
||||
WM_operatortype_append(CURVE_OT_dissolve_verts);
|
||||
|
||||
WM_operatortype_append(CURVE_OT_spline_type_set);
|
||||
WM_operatortype_append(CURVE_OT_radius_set);
|
||||
WM_operatortype_append(CURVE_OT_spline_weight_set);
|
||||
WM_operatortype_append(CURVE_OT_handle_type_set);
|
||||
WM_operatortype_append(CURVE_OT_normals_make_consistent);
|
||||
WM_operatortype_append(CURVE_OT_decimate);
|
||||
WM_operatortype_append(CURVE_OT_shade_smooth);
|
||||
WM_operatortype_append(CURVE_OT_shade_flat);
|
||||
WM_operatortype_append(CURVE_OT_tilt_clear);
|
||||
|
||||
WM_operatortype_append(CURVE_OT_primitive_bezier_curve_add);
|
||||
WM_operatortype_append(CURVE_OT_primitive_bezier_circle_add);
|
||||
WM_operatortype_append(CURVE_OT_primitive_nurbs_curve_add);
|
||||
WM_operatortype_append(CURVE_OT_primitive_nurbs_circle_add);
|
||||
WM_operatortype_append(CURVE_OT_primitive_nurbs_path_add);
|
||||
|
||||
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_curve_add);
|
||||
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_circle_add);
|
||||
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_surface_add);
|
||||
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_cylinder_add);
|
||||
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_sphere_add);
|
||||
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_torus_add);
|
||||
|
||||
WM_operatortype_append(CURVE_OT_smooth);
|
||||
WM_operatortype_append(CURVE_OT_smooth_weight);
|
||||
WM_operatortype_append(CURVE_OT_smooth_radius);
|
||||
WM_operatortype_append(CURVE_OT_smooth_tilt);
|
||||
|
||||
WM_operatortype_append(CURVE_OT_de_select_first);
|
||||
WM_operatortype_append(CURVE_OT_de_select_last);
|
||||
WM_operatortype_append(CURVE_OT_select_all);
|
||||
WM_operatortype_append(CURVE_OT_select_linked);
|
||||
WM_operatortype_append(CURVE_OT_select_linked_pick);
|
||||
WM_operatortype_append(CURVE_OT_select_row);
|
||||
WM_operatortype_append(CURVE_OT_select_next);
|
||||
WM_operatortype_append(CURVE_OT_select_previous);
|
||||
WM_operatortype_append(CURVE_OT_select_more);
|
||||
WM_operatortype_append(CURVE_OT_select_less);
|
||||
WM_operatortype_append(CURVE_OT_select_random);
|
||||
WM_operatortype_append(CURVE_OT_select_nth);
|
||||
WM_operatortype_append(CURVE_OT_select_similar);
|
||||
WM_operatortype_append(CURVE_OT_shortest_path_pick);
|
||||
|
||||
WM_operatortype_append(CURVE_OT_switch_direction);
|
||||
WM_operatortype_append(CURVE_OT_subdivide);
|
||||
WM_operatortype_append(CURVE_OT_make_segment);
|
||||
WM_operatortype_append(CURVE_OT_spin);
|
||||
WM_operatortype_append(CURVE_OT_vertex_add);
|
||||
WM_operatortype_append(CURVE_OT_draw);
|
||||
WM_operatortype_append(CURVE_OT_pen);
|
||||
WM_operatortype_append(CURVE_OT_extrude);
|
||||
WM_operatortype_append(CURVE_OT_cyclic_toggle);
|
||||
|
||||
WM_operatortype_append(CURVE_OT_match_texture_space);
|
||||
}
|
||||
|
||||
void ED_operatormacros_curve()
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
wmOperatorTypeMacro *otmacro;
|
||||
|
||||
ot = WM_operatortype_append_macro("CURVE_OT_duplicate_move",
|
||||
"Add Duplicate",
|
||||
"Duplicate curve and move",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
WM_operatortype_macro_define(ot, "CURVE_OT_duplicate");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
RNA_boolean_set(otmacro->ptr, "mirror", false);
|
||||
|
||||
ot = WM_operatortype_append_macro("CURVE_OT_extrude_move",
|
||||
"Extrude Curve and Move",
|
||||
"Extrude curve and move result",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
WM_operatortype_macro_define(ot, "CURVE_OT_extrude");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
RNA_boolean_set(otmacro->ptr, "mirror", false);
|
||||
}
|
||||
|
||||
void ED_keymap_curve(wmKeyConfig *keyconf)
|
||||
{
|
||||
/* only set in editmode font, by space_view3d listener */
|
||||
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Font", SPACE_EMPTY, RGN_TYPE_WINDOW);
|
||||
keymap->poll = ED_operator_editfont;
|
||||
|
||||
/* only set in editmode curve, by space_view3d listener */
|
||||
keymap = WM_keymap_ensure(keyconf, "Curve", SPACE_EMPTY, RGN_TYPE_WINDOW);
|
||||
keymap->poll = ED_operator_editsurfcurve;
|
||||
|
||||
curve_pen_modal_keymap(keyconf);
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
7259
blender-5.2.0/source/blender/editors/curve/editcurve.cc
Normal file
7259
blender-5.2.0/source/blender/editors/curve/editcurve.cc
Normal file
File diff suppressed because it is too large
Load Diff
832
blender-5.2.0/source/blender/editors/curve/editcurve_add.cc
Normal file
832
blender-5.2.0/source/blender/editors/curve/editcurve_add.cc
Normal file
@@ -0,0 +1,832 @@
|
||||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edcurve
|
||||
*/
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_layer.hh"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "ED_curve.hh"
|
||||
#include "ED_object.hh"
|
||||
#include "ED_screen.hh"
|
||||
#include "ED_view3d.hh"
|
||||
|
||||
#include "curve_intern.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
static const float nurbcircle[8][2] = {
|
||||
{0.0, -1.0},
|
||||
{-1.0, -1.0},
|
||||
{-1.0, 0.0},
|
||||
{-1.0, 1.0},
|
||||
{0.0, 1.0},
|
||||
{1.0, 1.0},
|
||||
{1.0, 0.0},
|
||||
{1.0, -1.0},
|
||||
};
|
||||
|
||||
/************ add primitive, used by object/ module ****************/
|
||||
|
||||
static const char *get_curve_defname(int type)
|
||||
{
|
||||
int stype = type & CU_PRIMITIVE;
|
||||
|
||||
if ((type & CU_TYPE) == CU_BEZIER) {
|
||||
switch (stype) {
|
||||
case CU_PRIM_CURVE:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "BézierCurve");
|
||||
case CU_PRIM_CIRCLE:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "BézierCircle");
|
||||
case CU_PRIM_PATH:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "CurvePath");
|
||||
default:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "Curve");
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (stype) {
|
||||
case CU_PRIM_CURVE:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "NurbsCurve");
|
||||
case CU_PRIM_CIRCLE:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "NurbsCircle");
|
||||
case CU_PRIM_PATH:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "NurbsPath");
|
||||
default:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "Curve");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char *get_surf_defname(int type)
|
||||
{
|
||||
int stype = type & CU_PRIMITIVE;
|
||||
|
||||
switch (stype) {
|
||||
case CU_PRIM_CURVE:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfCurve");
|
||||
case CU_PRIM_CIRCLE:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfCircle");
|
||||
case CU_PRIM_PATCH:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfPatch");
|
||||
case CU_PRIM_TUBE:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfCylinder");
|
||||
case CU_PRIM_SPHERE:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfSphere");
|
||||
case CU_PRIM_DONUT:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfTorus");
|
||||
default:
|
||||
return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "Surface");
|
||||
}
|
||||
}
|
||||
|
||||
Nurb *ED_curve_add_nurbs_primitive(
|
||||
bContext *C, Object *obedit, float mat[4][4], int type, int newob)
|
||||
{
|
||||
static int xzproj = 0; /* this function calls itself... */
|
||||
ListBaseT<Nurb> *editnurb = object_editcurve_get(obedit);
|
||||
RegionView3D *rv3d = ED_view3d_context_rv3d(C);
|
||||
Nurb *nu = nullptr;
|
||||
BezTriple *bezt;
|
||||
BPoint *bp;
|
||||
Curve *cu = id_cast<Curve *>(obedit->data);
|
||||
float vec[3], zvec[3] = {0.0f, 0.0f, 1.0f};
|
||||
float umat[4][4], viewmat[4][4];
|
||||
float fac;
|
||||
int a, b;
|
||||
const float grid = 1.0f;
|
||||
const eNurbType cutype = eNurbType(type & CU_TYPE); /* poly, bezier, nurbs, etc */
|
||||
const int stype = (type & CU_PRIMITIVE);
|
||||
|
||||
unit_m4(umat);
|
||||
unit_m4(viewmat);
|
||||
|
||||
if (rv3d) {
|
||||
copy_m4_m4(viewmat, rv3d->viewmat);
|
||||
copy_v3_v3(zvec, rv3d->viewinv[2]);
|
||||
}
|
||||
|
||||
BKE_nurbList_flag_set(editnurb, BEZT_FLAG_SELECT, false);
|
||||
|
||||
/* these types call this function to return a Nurb */
|
||||
if (!ELEM(stype, CU_PRIM_TUBE, CU_PRIM_DONUT)) {
|
||||
nu = MEM_new<Nurb>("addNurbprim");
|
||||
nu->type = cutype;
|
||||
nu->resolu = cu->resolu;
|
||||
nu->resolv = cu->resolv;
|
||||
}
|
||||
|
||||
switch (stype) {
|
||||
case CU_PRIM_CURVE: /* curve */
|
||||
nu->resolu = cu->resolu;
|
||||
if (cutype == CU_BEZIER) {
|
||||
nu->pntsu = 2;
|
||||
nu->bezt = MEM_new_array_zeroed<BezTriple>(nu->pntsu, "addNurbprim1");
|
||||
bezt = nu->bezt;
|
||||
bezt->h1 = bezt->h2 = HD_ALIGN;
|
||||
bezt->f1 = bezt->f2 = bezt->f3 = BEZT_FLAG_SELECT;
|
||||
bezt->radius = 1.0;
|
||||
|
||||
bezt->vec[1][0] += -grid;
|
||||
bezt->vec[0][0] += -1.5f * grid;
|
||||
bezt->vec[0][1] += -0.5f * grid;
|
||||
bezt->vec[2][0] += -0.5f * grid;
|
||||
bezt->vec[2][1] += 0.5f * grid;
|
||||
for (a = 0; a < 3; a++) {
|
||||
mul_m4_v3(mat, bezt->vec[a]);
|
||||
}
|
||||
|
||||
bezt++;
|
||||
bezt->h1 = bezt->h2 = HD_ALIGN;
|
||||
bezt->f1 = bezt->f2 = bezt->f3 = BEZT_FLAG_SELECT;
|
||||
bezt->radius = bezt->weight = 1.0;
|
||||
|
||||
bezt->vec[0][0] = 0;
|
||||
bezt->vec[0][1] = 0;
|
||||
bezt->vec[1][0] = grid;
|
||||
bezt->vec[1][1] = 0;
|
||||
bezt->vec[2][0] = grid * 2;
|
||||
bezt->vec[2][1] = 0;
|
||||
for (a = 0; a < 3; a++) {
|
||||
mul_m4_v3(mat, bezt->vec[a]);
|
||||
}
|
||||
|
||||
BKE_nurb_handles_calc(nu);
|
||||
}
|
||||
else {
|
||||
|
||||
nu->pntsu = 4;
|
||||
nu->pntsv = 1;
|
||||
nu->orderu = 4;
|
||||
nu->bp = MEM_new_array_zeroed<BPoint>(nu->pntsu, "addNurbprim3");
|
||||
|
||||
bp = nu->bp;
|
||||
for (a = 0; a < 4; a++, bp++) {
|
||||
bp->vec[3] = 1.0;
|
||||
bp->f1 = SELECT;
|
||||
bp->radius = bp->weight = 1.0;
|
||||
}
|
||||
|
||||
bp = nu->bp;
|
||||
bp->vec[0] += -1.5f * grid;
|
||||
bp++;
|
||||
bp->vec[0] += -grid;
|
||||
bp->vec[1] += grid;
|
||||
bp++;
|
||||
bp->vec[0] += grid;
|
||||
bp->vec[1] += grid;
|
||||
bp++;
|
||||
bp->vec[0] += 1.5f * grid;
|
||||
|
||||
bp = nu->bp;
|
||||
for (a = 0; a < 4; a++, bp++) {
|
||||
mul_m4_v3(mat, bp->vec);
|
||||
}
|
||||
|
||||
if (cutype == CU_NURBS) {
|
||||
nu->knotsu = nullptr; /* nurbs_knot_calc_u allocates */
|
||||
BKE_nurb_knot_calc_u(nu);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CU_PRIM_PATH: /* 5 point path */
|
||||
nu->pntsu = 5;
|
||||
nu->pntsv = 1;
|
||||
nu->orderu = 5;
|
||||
nu->flagu = CU_NURB_ENDPOINT; /* endpoint */
|
||||
nu->resolu = cu->resolu;
|
||||
nu->bp = MEM_new_array_zeroed<BPoint>(nu->pntsu, "addNurbprim3");
|
||||
|
||||
bp = nu->bp;
|
||||
for (a = 0; a < 5; a++, bp++) {
|
||||
bp->vec[3] = 1.0;
|
||||
bp->f1 = SELECT;
|
||||
bp->radius = bp->weight = 1.0;
|
||||
}
|
||||
|
||||
bp = nu->bp;
|
||||
bp->vec[0] += -2.0f * grid;
|
||||
bp++;
|
||||
bp->vec[0] += -grid;
|
||||
bp++;
|
||||
bp++;
|
||||
bp->vec[0] += grid;
|
||||
bp++;
|
||||
bp->vec[0] += 2.0f * grid;
|
||||
|
||||
bp = nu->bp;
|
||||
for (a = 0; a < 5; a++, bp++) {
|
||||
mul_m4_v3(mat, bp->vec);
|
||||
}
|
||||
|
||||
if (cutype == CU_NURBS) {
|
||||
nu->knotsu = nullptr; /* nurbs_knot_calc_u allocates */
|
||||
BKE_nurb_knot_calc_u(nu);
|
||||
}
|
||||
|
||||
break;
|
||||
case CU_PRIM_CIRCLE: /* circle */
|
||||
nu->resolu = cu->resolu;
|
||||
|
||||
if (cutype == CU_BEZIER) {
|
||||
nu->pntsu = 4;
|
||||
nu->bezt = MEM_new_array_zeroed<BezTriple>(nu->pntsu, "addNurbprim1");
|
||||
nu->flagu = CU_NURB_CYCLIC;
|
||||
bezt = nu->bezt;
|
||||
|
||||
bezt->h1 = bezt->h2 = HD_AUTO;
|
||||
bezt->f1 = bezt->f2 = bezt->f3 = BEZT_FLAG_SELECT;
|
||||
bezt->vec[1][0] += -grid;
|
||||
for (a = 0; a < 3; a++) {
|
||||
mul_m4_v3(mat, bezt->vec[a]);
|
||||
}
|
||||
bezt->radius = bezt->weight = 1.0;
|
||||
|
||||
bezt++;
|
||||
bezt->h1 = bezt->h2 = HD_AUTO;
|
||||
bezt->f1 = bezt->f2 = bezt->f3 = BEZT_FLAG_SELECT;
|
||||
bezt->vec[1][1] += grid;
|
||||
for (a = 0; a < 3; a++) {
|
||||
mul_m4_v3(mat, bezt->vec[a]);
|
||||
}
|
||||
bezt->radius = bezt->weight = 1.0;
|
||||
|
||||
bezt++;
|
||||
bezt->h1 = bezt->h2 = HD_AUTO;
|
||||
bezt->f1 = bezt->f2 = bezt->f3 = BEZT_FLAG_SELECT;
|
||||
bezt->vec[1][0] += grid;
|
||||
for (a = 0; a < 3; a++) {
|
||||
mul_m4_v3(mat, bezt->vec[a]);
|
||||
}
|
||||
bezt->radius = bezt->weight = 1.0;
|
||||
|
||||
bezt++;
|
||||
bezt->h1 = bezt->h2 = HD_AUTO;
|
||||
bezt->f1 = bezt->f2 = bezt->f3 = BEZT_FLAG_SELECT;
|
||||
bezt->vec[1][1] += -grid;
|
||||
for (a = 0; a < 3; a++) {
|
||||
mul_m4_v3(mat, bezt->vec[a]);
|
||||
}
|
||||
bezt->radius = bezt->weight = 1.0;
|
||||
|
||||
BKE_nurb_handles_calc(nu);
|
||||
}
|
||||
else if (cutype == CU_NURBS) { /* nurb */
|
||||
nu->pntsu = 8;
|
||||
nu->pntsv = 1;
|
||||
nu->orderu = 3;
|
||||
nu->bp = MEM_new_array_zeroed<BPoint>(nu->pntsu, "addNurbprim6");
|
||||
nu->flagu = CU_NURB_CYCLIC | CU_NURB_BEZIER | CU_NURB_ENDPOINT;
|
||||
bp = nu->bp;
|
||||
|
||||
for (a = 0; a < 8; a++) {
|
||||
bp->f1 = SELECT;
|
||||
if (xzproj == 0) {
|
||||
bp->vec[0] += nurbcircle[a][0] * grid;
|
||||
bp->vec[1] += nurbcircle[a][1] * grid;
|
||||
}
|
||||
else {
|
||||
bp->vec[0] += 0.25f * nurbcircle[a][0] * grid - 0.75f * grid;
|
||||
bp->vec[2] += 0.25f * nurbcircle[a][1] * grid;
|
||||
}
|
||||
if (a & 1) {
|
||||
bp->vec[3] = 0.5 * M_SQRT2;
|
||||
}
|
||||
else {
|
||||
bp->vec[3] = 1.0;
|
||||
}
|
||||
mul_m4_v3(mat, bp->vec);
|
||||
bp->radius = bp->weight = 1.0;
|
||||
|
||||
bp++;
|
||||
}
|
||||
|
||||
BKE_nurb_knot_calc_u(nu);
|
||||
}
|
||||
break;
|
||||
case CU_PRIM_PATCH: /* 4x4 patch */
|
||||
if (cutype == CU_NURBS) { /* nurb */
|
||||
|
||||
nu->pntsu = 4;
|
||||
nu->pntsv = 4;
|
||||
nu->orderu = 4;
|
||||
nu->orderv = 4;
|
||||
nu->flag = CU_SMOOTH;
|
||||
nu->bp = MEM_new_array_zeroed<BPoint>((4 * 4), "addNurbprim6");
|
||||
nu->flagu = {};
|
||||
nu->flagv = {};
|
||||
bp = nu->bp;
|
||||
|
||||
for (a = 0; a < 4; a++) {
|
||||
for (b = 0; b < 4; b++) {
|
||||
bp->f1 = SELECT;
|
||||
fac = float(a) - 1.5f;
|
||||
bp->vec[0] += fac * grid;
|
||||
fac = float(b) - 1.5f;
|
||||
bp->vec[1] += fac * grid;
|
||||
if (ELEM(a, 1, 2) && ELEM(b, 1, 2)) {
|
||||
bp->vec[2] += grid;
|
||||
}
|
||||
mul_m4_v3(mat, bp->vec);
|
||||
bp->vec[3] = 1.0;
|
||||
bp++;
|
||||
}
|
||||
}
|
||||
|
||||
BKE_nurb_knot_calc_u(nu);
|
||||
BKE_nurb_knot_calc_v(nu);
|
||||
}
|
||||
break;
|
||||
case CU_PRIM_TUBE: /* Cylinder */
|
||||
if (cutype == CU_NURBS) {
|
||||
nu = ED_curve_add_nurbs_primitive(C, obedit, mat, CU_NURBS | CU_PRIM_CIRCLE, 0);
|
||||
nu->resolu = cu->resolu;
|
||||
nu->flag = CU_SMOOTH;
|
||||
BLI_addtail(editnurb, nu); /* temporal for extrude and translate */
|
||||
vec[0] = vec[1] = 0.0;
|
||||
vec[2] = -grid;
|
||||
|
||||
mul_mat3_m4_v3(mat, vec);
|
||||
|
||||
ed_editnurb_translate_flag(editnurb, BEZT_FLAG_SELECT, vec, CU_IS_2D(cu));
|
||||
ed_editnurb_extrude_flag(cu->editnurb, BEZT_FLAG_SELECT);
|
||||
mul_v3_fl(vec, -2.0f);
|
||||
ed_editnurb_translate_flag(editnurb, BEZT_FLAG_SELECT, vec, CU_IS_2D(cu));
|
||||
|
||||
BLI_remlink(editnurb, nu);
|
||||
|
||||
a = nu->pntsu * nu->pntsv;
|
||||
bp = nu->bp;
|
||||
while (a-- > 0) {
|
||||
bp->f1 |= SELECT;
|
||||
bp++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CU_PRIM_SPHERE: /* sphere */
|
||||
if (cutype == CU_NURBS) {
|
||||
const float tmp_cent[3] = {0.0f, 0.0f, 0.0f};
|
||||
const float tmp_vec[3] = {0.0f, 0.0f, 1.0f};
|
||||
|
||||
nu->pntsu = 5;
|
||||
nu->pntsv = 1;
|
||||
nu->orderu = 3;
|
||||
nu->resolu = cu->resolu;
|
||||
nu->resolv = cu->resolv;
|
||||
nu->flag = CU_SMOOTH;
|
||||
nu->bp = MEM_new_array_zeroed<BPoint>(nu->pntsu, "addNurbprim6");
|
||||
nu->flagu = {};
|
||||
bp = nu->bp;
|
||||
|
||||
for (a = 0; a < 5; a++) {
|
||||
bp->f1 = SELECT;
|
||||
bp->vec[0] += nurbcircle[a][0] * grid;
|
||||
bp->vec[2] += nurbcircle[a][1] * grid;
|
||||
if (a & 1) {
|
||||
bp->vec[3] = 0.5 * M_SQRT2;
|
||||
}
|
||||
else {
|
||||
bp->vec[3] = 1.0;
|
||||
}
|
||||
mul_m4_v3(mat, bp->vec);
|
||||
bp++;
|
||||
}
|
||||
nu->flagu = CU_NURB_BEZIER | CU_NURB_ENDPOINT;
|
||||
BKE_nurb_knot_calc_u(nu);
|
||||
|
||||
BLI_addtail(editnurb, nu); /* temporal for spin */
|
||||
|
||||
if (newob && (U.flag & USER_ADD_VIEWALIGNED) == 0) {
|
||||
ed_editnurb_spin(umat, nullptr, obedit, tmp_vec, tmp_cent);
|
||||
}
|
||||
else if (U.flag & USER_ADD_VIEWALIGNED) {
|
||||
ed_editnurb_spin(viewmat, nullptr, obedit, zvec, mat[3]);
|
||||
}
|
||||
else {
|
||||
ed_editnurb_spin(umat, nullptr, obedit, tmp_vec, mat[3]);
|
||||
}
|
||||
|
||||
BKE_nurb_knot_calc_v(nu);
|
||||
|
||||
a = nu->pntsu * nu->pntsv;
|
||||
bp = nu->bp;
|
||||
while (a-- > 0) {
|
||||
bp->f1 |= SELECT;
|
||||
bp++;
|
||||
}
|
||||
BLI_remlink(editnurb, nu);
|
||||
}
|
||||
break;
|
||||
case CU_PRIM_DONUT: /* torus */
|
||||
if (cutype == CU_NURBS) {
|
||||
const float tmp_cent[3] = {0.0f, 0.0f, 0.0f};
|
||||
const float tmp_vec[3] = {0.0f, 0.0f, 1.0f};
|
||||
|
||||
xzproj = 1;
|
||||
nu = ED_curve_add_nurbs_primitive(C, obedit, mat, CU_NURBS | CU_PRIM_CIRCLE, 0);
|
||||
xzproj = 0;
|
||||
nu->resolu = cu->resolu;
|
||||
nu->resolv = cu->resolv;
|
||||
nu->flag = CU_SMOOTH;
|
||||
BLI_addtail(editnurb, nu); /* temporal for spin */
|
||||
|
||||
/* same as above */
|
||||
if (newob && (U.flag & USER_ADD_VIEWALIGNED) == 0) {
|
||||
ed_editnurb_spin(umat, nullptr, obedit, tmp_vec, tmp_cent);
|
||||
}
|
||||
else if (U.flag & USER_ADD_VIEWALIGNED) {
|
||||
ed_editnurb_spin(viewmat, nullptr, obedit, zvec, mat[3]);
|
||||
}
|
||||
else {
|
||||
ed_editnurb_spin(umat, nullptr, obedit, tmp_vec, mat[3]);
|
||||
}
|
||||
|
||||
BLI_remlink(editnurb, nu);
|
||||
|
||||
a = nu->pntsu * nu->pntsv;
|
||||
bp = nu->bp;
|
||||
while (a-- > 0) {
|
||||
bp->f1 |= SELECT;
|
||||
bp++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* should never happen */
|
||||
BLI_assert_msg(0, "invalid nurbs type");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BLI_assert(nu != nullptr);
|
||||
|
||||
if (nu) { /* should always be set */
|
||||
nu->flag |= CU_SMOOTH;
|
||||
cu->actnu = editnurb->count();
|
||||
cu->actvert = CU_ACT_NONE;
|
||||
|
||||
if (CU_IS_2D(cu)) {
|
||||
BKE_nurb_project_2d(nu);
|
||||
}
|
||||
}
|
||||
|
||||
return nu;
|
||||
}
|
||||
|
||||
static wmOperatorStatus curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
BKE_view_layer_synced_ensure(*bmain, scene, view_layer);
|
||||
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
|
||||
ListBaseT<Nurb> *editnurb;
|
||||
Nurb *nu;
|
||||
bool newob = false;
|
||||
bool enter_editmode;
|
||||
ushort local_view_bits;
|
||||
float loc[3], rot[3];
|
||||
float mat[4][4];
|
||||
|
||||
WM_operator_view3d_unit_defaults(C, op);
|
||||
|
||||
ed::object::add_generic_get_opts(
|
||||
C, op, 'Z', loc, rot, nullptr, &enter_editmode, &local_view_bits, nullptr);
|
||||
|
||||
if (!isSurf) { /* adding curve */
|
||||
if (obedit == nullptr || obedit->type != OB_CURVES_LEGACY) {
|
||||
const char *name = get_curve_defname(type);
|
||||
Curve *cu;
|
||||
|
||||
obedit = ed::object::add_type(C, OB_CURVES_LEGACY, name, loc, rot, true, local_view_bits);
|
||||
newob = true;
|
||||
|
||||
cu = id_cast<Curve *>(obedit->data);
|
||||
|
||||
if (type & CU_PRIM_PATH) {
|
||||
cu->flag |= CU_PATH | CU_3D;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
|
||||
}
|
||||
}
|
||||
else { /* adding surface */
|
||||
if (obedit == nullptr || obedit->type != OB_SURF) {
|
||||
const char *name = get_surf_defname(type);
|
||||
obedit = ed::object::add_type(C, OB_SURF, name, loc, rot, true, local_view_bits);
|
||||
newob = true;
|
||||
}
|
||||
else {
|
||||
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
|
||||
}
|
||||
}
|
||||
|
||||
float radius = RNA_float_get(op->ptr, "radius");
|
||||
float scale[3];
|
||||
copy_v3_fl(scale, radius);
|
||||
ed::object::new_primitive_matrix(C, obedit, loc, rot, scale, mat);
|
||||
|
||||
nu = ED_curve_add_nurbs_primitive(C, obedit, mat, type, newob);
|
||||
editnurb = object_editcurve_get(obedit);
|
||||
BLI_addtail(editnurb, nu);
|
||||
|
||||
/* userdef */
|
||||
if (newob && !enter_editmode) {
|
||||
ed::object::editmode_exit_ex(bmain, scene, obedit, ed::object::EM_FREEDATA);
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static wmOperatorStatus curve_prim_add(bContext *C, wmOperator *op, int type)
|
||||
{
|
||||
return curvesurf_prim_add(C, op, type, 0);
|
||||
}
|
||||
|
||||
static wmOperatorStatus surf_prim_add(bContext *C, wmOperator *op, int type)
|
||||
{
|
||||
return curvesurf_prim_add(C, op, type, 1);
|
||||
}
|
||||
|
||||
/* ******************** Curves ******************* */
|
||||
|
||||
static wmOperatorStatus add_primitive_bezier_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return curve_prim_add(C, op, CU_BEZIER | CU_PRIM_CURVE);
|
||||
}
|
||||
|
||||
void CURVE_OT_primitive_bezier_curve_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Bézier";
|
||||
ot->description = "Construct a Bézier Curve";
|
||||
ot->idname = "CURVE_OT_primitive_bezier_curve_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_bezier_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
static wmOperatorStatus add_primitive_bezier_circle_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return curve_prim_add(C, op, CU_BEZIER | CU_PRIM_CIRCLE);
|
||||
}
|
||||
|
||||
void CURVE_OT_primitive_bezier_circle_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Bézier Circle";
|
||||
ot->description = "Construct a Bézier Circle";
|
||||
ot->idname = "CURVE_OT_primitive_bezier_circle_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_bezier_circle_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
static wmOperatorStatus add_primitive_nurbs_curve_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return curve_prim_add(C, op, CU_NURBS | CU_PRIM_CURVE);
|
||||
}
|
||||
|
||||
void CURVE_OT_primitive_nurbs_curve_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Nurbs Curve";
|
||||
ot->description = "Construct a Nurbs Curve";
|
||||
ot->idname = "CURVE_OT_primitive_nurbs_curve_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_nurbs_curve_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
static wmOperatorStatus add_primitive_nurbs_circle_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return curve_prim_add(C, op, CU_NURBS | CU_PRIM_CIRCLE);
|
||||
}
|
||||
|
||||
void CURVE_OT_primitive_nurbs_circle_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Nurbs Circle";
|
||||
ot->description = "Construct a Nurbs Circle";
|
||||
ot->idname = "CURVE_OT_primitive_nurbs_circle_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_nurbs_circle_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
static wmOperatorStatus add_primitive_curve_path_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return curve_prim_add(C, op, CU_NURBS | CU_PRIM_PATH);
|
||||
}
|
||||
|
||||
void CURVE_OT_primitive_nurbs_path_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Path";
|
||||
ot->description = "Construct a Path";
|
||||
ot->idname = "CURVE_OT_primitive_nurbs_path_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_curve_path_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
/* **************** NURBS surfaces ********************** */
|
||||
static wmOperatorStatus add_primitive_nurbs_surface_curve_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return surf_prim_add(C, op, CU_PRIM_CURVE | CU_NURBS);
|
||||
}
|
||||
|
||||
void SURFACE_OT_primitive_nurbs_surface_curve_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Surface Curve";
|
||||
ot->description = "Construct a NURBS surface curve";
|
||||
ot->idname = "SURFACE_OT_primitive_nurbs_surface_curve_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_nurbs_surface_curve_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
static wmOperatorStatus add_primitive_nurbs_surface_circle_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return surf_prim_add(C, op, CU_PRIM_CIRCLE | CU_NURBS);
|
||||
}
|
||||
|
||||
void SURFACE_OT_primitive_nurbs_surface_circle_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Surface Circle";
|
||||
ot->description = "Construct a NURBS surface circle";
|
||||
ot->idname = "SURFACE_OT_primitive_nurbs_surface_circle_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_nurbs_surface_circle_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
static wmOperatorStatus add_primitive_nurbs_surface_surface_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return surf_prim_add(C, op, CU_PRIM_PATCH | CU_NURBS);
|
||||
}
|
||||
|
||||
void SURFACE_OT_primitive_nurbs_surface_surface_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Surface Patch";
|
||||
ot->description = "Construct a NURBS surface patch";
|
||||
ot->idname = "SURFACE_OT_primitive_nurbs_surface_surface_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_nurbs_surface_surface_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
static wmOperatorStatus add_primitive_nurbs_surface_cylinder_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return surf_prim_add(C, op, CU_PRIM_TUBE | CU_NURBS);
|
||||
}
|
||||
|
||||
void SURFACE_OT_primitive_nurbs_surface_cylinder_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Surface Cylinder";
|
||||
ot->description = "Construct a NURBS surface cylinder";
|
||||
ot->idname = "SURFACE_OT_primitive_nurbs_surface_cylinder_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_nurbs_surface_cylinder_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
static wmOperatorStatus add_primitive_nurbs_surface_sphere_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return surf_prim_add(C, op, CU_PRIM_SPHERE | CU_NURBS);
|
||||
}
|
||||
|
||||
void SURFACE_OT_primitive_nurbs_surface_sphere_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Surface Sphere";
|
||||
ot->description = "Construct a NURBS surface sphere";
|
||||
ot->idname = "SURFACE_OT_primitive_nurbs_surface_sphere_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_nurbs_surface_sphere_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
static wmOperatorStatus add_primitive_nurbs_surface_torus_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return surf_prim_add(C, op, CU_PRIM_DONUT | CU_NURBS);
|
||||
}
|
||||
|
||||
void SURFACE_OT_primitive_nurbs_surface_torus_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Surface Torus";
|
||||
ot->description = "Construct a NURBS surface torus";
|
||||
ot->idname = "SURFACE_OT_primitive_nurbs_surface_torus_add";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = add_primitive_nurbs_surface_torus_exec;
|
||||
ot->poll = ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ed::object::add_unit_props_radius(ot);
|
||||
ed::object::add_generic_props(ot, true);
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
1266
blender-5.2.0/source/blender/editors/curve/editcurve_paint.cc
Normal file
1266
blender-5.2.0/source/blender/editors/curve/editcurve_paint.cc
Normal file
File diff suppressed because it is too large
Load Diff
1894
blender-5.2.0/source/blender/editors/curve/editcurve_pen.cc
Normal file
1894
blender-5.2.0/source/blender/editors/curve/editcurve_pen.cc
Normal file
File diff suppressed because it is too large
Load Diff
240
blender-5.2.0/source/blender/editors/curve/editcurve_query.cc
Normal file
240
blender-5.2.0/source/blender/editors/curve/editcurve_query.cc
Normal file
@@ -0,0 +1,240 @@
|
||||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edcurve
|
||||
*/
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_layer.hh"
|
||||
|
||||
#include "ED_curve.hh"
|
||||
#include "ED_view3d.hh"
|
||||
|
||||
#include "curve_intern.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Cursor Picking API
|
||||
* \{ */
|
||||
|
||||
struct PickUserData {
|
||||
BPoint *bp;
|
||||
BezTriple *bezt;
|
||||
Nurb *nurb;
|
||||
float dist;
|
||||
int hpoint;
|
||||
uint8_t select;
|
||||
float mval_fl[2];
|
||||
bool is_changed;
|
||||
};
|
||||
|
||||
static void curve_pick_vert__do_closest(void *user_data,
|
||||
Nurb *nu,
|
||||
BPoint *bp,
|
||||
BezTriple *bezt,
|
||||
int beztindex,
|
||||
bool handles_visible,
|
||||
const float screen_co[2])
|
||||
{
|
||||
PickUserData *data = static_cast<PickUserData *>(user_data);
|
||||
|
||||
uint8_t flag;
|
||||
float dist_test;
|
||||
|
||||
if (bp) {
|
||||
flag = bp->f1;
|
||||
}
|
||||
else {
|
||||
BLI_assert(handles_visible || beztindex == 1);
|
||||
|
||||
if (beztindex == 0) {
|
||||
flag = bezt->f1;
|
||||
}
|
||||
else if (beztindex == 1) {
|
||||
flag = bezt->f2;
|
||||
}
|
||||
else {
|
||||
flag = bezt->f3;
|
||||
}
|
||||
}
|
||||
|
||||
dist_test = len_manhattan_v2v2(data->mval_fl, screen_co);
|
||||
if ((flag & SELECT) == data->select) {
|
||||
dist_test += 5.0f;
|
||||
}
|
||||
if (bezt && beztindex == 1) {
|
||||
dist_test += 3.0f; /* middle points get a small disadvantage */
|
||||
}
|
||||
|
||||
if (dist_test < data->dist) {
|
||||
data->dist = dist_test;
|
||||
|
||||
data->bp = bp;
|
||||
data->bezt = bezt;
|
||||
data->nurb = nu;
|
||||
data->hpoint = bezt ? beztindex : 0;
|
||||
data->is_changed = true;
|
||||
}
|
||||
|
||||
UNUSED_VARS_NDEBUG(handles_visible);
|
||||
}
|
||||
|
||||
bool ED_curve_pick_vert_ex(ViewContext *vc,
|
||||
const bool select,
|
||||
const int dist_px,
|
||||
Nurb **r_nurb,
|
||||
BezTriple **r_bezt,
|
||||
BPoint **r_bp,
|
||||
short *r_handle,
|
||||
Base **r_base)
|
||||
{
|
||||
PickUserData data{};
|
||||
|
||||
data.dist = dist_px;
|
||||
data.hpoint = 0;
|
||||
data.select = select ? SELECT : 0;
|
||||
data.mval_fl[0] = vc->mval[0];
|
||||
data.mval_fl[1] = vc->mval[1];
|
||||
|
||||
Vector<Base *> bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
|
||||
*vc->bmain, vc->scene, vc->view_layer, vc->v3d);
|
||||
for (Base *base : bases) {
|
||||
data.is_changed = false;
|
||||
|
||||
ED_view3d_viewcontext_init_object(vc, base->object);
|
||||
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
|
||||
nurbs_foreachScreenVert(vc, curve_pick_vert__do_closest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
|
||||
if (r_base && data.is_changed) {
|
||||
*r_base = base;
|
||||
}
|
||||
}
|
||||
|
||||
*r_nurb = data.nurb;
|
||||
*r_bezt = data.bezt;
|
||||
*r_bp = data.bp;
|
||||
|
||||
if (r_handle) {
|
||||
*r_handle = data.hpoint;
|
||||
}
|
||||
|
||||
return (data.bezt || data.bp);
|
||||
}
|
||||
|
||||
bool ED_curve_pick_vert(ViewContext *vc,
|
||||
short sel,
|
||||
Nurb **r_nurb,
|
||||
BezTriple **r_bezt,
|
||||
BPoint **r_bp,
|
||||
short *r_handle,
|
||||
Base **r_base)
|
||||
{
|
||||
return ED_curve_pick_vert_ex(
|
||||
vc, sel, ED_view3d_select_dist_px(), r_nurb, r_bezt, r_bp, r_handle, r_base);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Selection Queries
|
||||
* \{ */
|
||||
|
||||
void ED_curve_nurb_vert_selected_find(
|
||||
Curve *cu, View3D *v3d, Nurb **r_nu, BezTriple **r_bezt, BPoint **r_bp)
|
||||
{
|
||||
/* In nu and (bezt or bp) selected are written if there's 1 sel. */
|
||||
/* If more points selected in 1 spline: return only nu, bezt and bp are 0. */
|
||||
ListBaseT<Nurb> *editnurb = &cu->editnurb->nurbs;
|
||||
BezTriple *bezt1;
|
||||
BPoint *bp1;
|
||||
int a;
|
||||
|
||||
*r_nu = nullptr;
|
||||
*r_bezt = nullptr;
|
||||
*r_bp = nullptr;
|
||||
|
||||
for (Nurb &nu1 : *editnurb) {
|
||||
if (nu1.type == CU_BEZIER) {
|
||||
bezt1 = nu1.bezt;
|
||||
a = nu1.pntsu;
|
||||
while (a--) {
|
||||
if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1)) {
|
||||
if (!ELEM(*r_nu, nullptr, &nu1)) {
|
||||
*r_nu = nullptr;
|
||||
*r_bp = nullptr;
|
||||
*r_bezt = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*r_bezt || *r_bp) {
|
||||
*r_bp = nullptr;
|
||||
*r_bezt = nullptr;
|
||||
}
|
||||
else {
|
||||
*r_bezt = bezt1;
|
||||
*r_nu = &nu1;
|
||||
}
|
||||
}
|
||||
bezt1++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bp1 = nu1.bp;
|
||||
a = nu1.pntsu * nu1.pntsv;
|
||||
while (a--) {
|
||||
if (bp1->f1 & SELECT) {
|
||||
if (!ELEM(*r_nu, nullptr, &nu1)) {
|
||||
*r_bp = nullptr;
|
||||
*r_bezt = nullptr;
|
||||
*r_nu = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*r_bezt || *r_bp) {
|
||||
*r_bp = nullptr;
|
||||
*r_bezt = nullptr;
|
||||
}
|
||||
else {
|
||||
*r_bp = bp1;
|
||||
*r_nu = &nu1;
|
||||
}
|
||||
}
|
||||
bp1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ED_curve_active_center(Curve *cu, float center[3])
|
||||
{
|
||||
Nurb *nu = nullptr;
|
||||
void *vert = nullptr;
|
||||
|
||||
if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nu->type == CU_BEZIER) {
|
||||
BezTriple *bezt = static_cast<BezTriple *>(vert);
|
||||
copy_v3_v3(center, bezt->vec[1]);
|
||||
}
|
||||
else {
|
||||
BPoint *bp = static_cast<BPoint *>(vert);
|
||||
copy_v3_v3(center, bp->vec);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender
|
||||
2090
blender-5.2.0/source/blender/editors/curve/editcurve_select.cc
Normal file
2090
blender-5.2.0/source/blender/editors/curve/editcurve_select.cc
Normal file
File diff suppressed because it is too large
Load Diff
324
blender-5.2.0/source/blender/editors/curve/editcurve_undo.cc
Normal file
324
blender-5.2.0/source/blender/editors/curve/editcurve_undo.cc
Normal file
@@ -0,0 +1,324 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edcurve
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLI_array_utils.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "BKE_anim_data.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_fcurve.hh"
|
||||
#include "BKE_layer.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_undo_system.hh"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
|
||||
#include "ED_curve.hh"
|
||||
#include "ED_undo.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "curve_intern.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/** We only need this locally. */
|
||||
static CLG_LogRef LOG = {"undo.curve"};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Undo Conversion
|
||||
* \{ */
|
||||
|
||||
namespace {
|
||||
|
||||
struct UndoCurve {
|
||||
ListBaseT<Nurb> nubase;
|
||||
int actvert;
|
||||
CVKeyIndexMap *undoIndex;
|
||||
|
||||
/* Historical note: Once upon a time, this code also made a backup of F-Curves, in an attempt to
|
||||
* enable undo of animation changes. This was very limited, as it only backed up the animation
|
||||
* of the curve ID; all the other IDs whose animation was shown in the dope sheet, timeline, etc.
|
||||
* was ignored. It also ignored the NLA, and deleted Action groups even when the animation was
|
||||
* not touched by the user.
|
||||
*
|
||||
* With the introduction of slotted Actions, a decision had to be made to either port this
|
||||
* behavior or remove it. The latter was chosen. For more information, see #135585. */
|
||||
ListBaseT<FCurve> drivers;
|
||||
|
||||
int actnu;
|
||||
eCurveFlag flag;
|
||||
|
||||
/* Stored in the object, needed since users may change the active key while in edit-mode. */
|
||||
struct {
|
||||
short shapenr;
|
||||
} obedit;
|
||||
|
||||
size_t undo_size;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static void undocurve_to_editcurve(Main *bmain, UndoCurve *ucu, Curve *cu, short *r_shapenr)
|
||||
{
|
||||
ListBaseT<Nurb> *undobase = &ucu->nubase;
|
||||
ListBaseT<Nurb> *editbase = BKE_curve_editNurbs_get(cu);
|
||||
EditNurb *editnurb = cu->editnurb;
|
||||
AnimData *ad = BKE_animdata_from_id(&cu->id);
|
||||
|
||||
BKE_nurbList_free(editbase);
|
||||
|
||||
if (ucu->undoIndex) {
|
||||
BKE_curve_editNurb_keyIndex_free(&editnurb->keyindex);
|
||||
editnurb->keyindex = ED_curve_keyindex_hash_duplicate(ucu->undoIndex);
|
||||
}
|
||||
|
||||
if (ad) {
|
||||
BKE_fcurves_free(&ad->drivers);
|
||||
BKE_fcurves_copy(&ad->drivers, &ucu->drivers);
|
||||
}
|
||||
|
||||
/* Copy. */
|
||||
for (Nurb &nu : *undobase) {
|
||||
Nurb *newnu = BKE_nurb_duplicate(&nu);
|
||||
|
||||
if (editnurb->keyindex) {
|
||||
ED_curve_keyindex_update_nurb(editnurb, &nu, newnu);
|
||||
}
|
||||
|
||||
BLI_addtail(editbase, newnu);
|
||||
}
|
||||
|
||||
cu->actvert = ucu->actvert;
|
||||
cu->actnu = ucu->actnu;
|
||||
cu->flag = ucu->flag;
|
||||
*r_shapenr = ucu->obedit.shapenr;
|
||||
ED_curve_updateAnimPaths(bmain, cu);
|
||||
}
|
||||
|
||||
static void undocurve_from_editcurve(UndoCurve *ucu, Curve *cu, const short shapenr)
|
||||
{
|
||||
BLI_assert(BLI_array_is_zeroed(ucu, 1));
|
||||
ListBaseT<Nurb> *nubase = BKE_curve_editNurbs_get(cu);
|
||||
EditNurb *editnurb = cu->editnurb, tmpEditnurb;
|
||||
AnimData *ad = BKE_animdata_from_id(&cu->id);
|
||||
|
||||
/* TODO: include size of drivers & undoIndex */
|
||||
// ucu->undo_size = 0;
|
||||
|
||||
if (editnurb->keyindex) {
|
||||
ucu->undoIndex = ED_curve_keyindex_hash_duplicate(editnurb->keyindex);
|
||||
tmpEditnurb.keyindex = ucu->undoIndex;
|
||||
}
|
||||
|
||||
if (ad) {
|
||||
BKE_fcurves_copy(&ucu->drivers, &ad->drivers);
|
||||
}
|
||||
|
||||
/* Copy. */
|
||||
for (Nurb &nu : *nubase) {
|
||||
Nurb *newnu = BKE_nurb_duplicate(&nu);
|
||||
|
||||
if (ucu->undoIndex) {
|
||||
ED_curve_keyindex_update_nurb(&tmpEditnurb, &nu, newnu);
|
||||
}
|
||||
|
||||
BLI_addtail(&ucu->nubase, newnu);
|
||||
|
||||
ucu->undo_size += ((nu.bezt ? (sizeof(BezTriple) * nu.pntsu) : 0) +
|
||||
(nu.bp ? (sizeof(BPoint) * (nu.pntsu * nu.pntsv)) : 0) +
|
||||
(nu.knotsu ? (sizeof(float) * KNOTSU(&nu)) : 0) +
|
||||
(nu.knotsv ? (sizeof(float) * KNOTSV(&nu)) : 0) + sizeof(Nurb));
|
||||
}
|
||||
|
||||
ucu->actvert = cu->actvert;
|
||||
ucu->actnu = cu->actnu;
|
||||
ucu->flag = cu->flag;
|
||||
|
||||
ucu->obedit.shapenr = shapenr;
|
||||
}
|
||||
|
||||
static void undocurve_free_data(UndoCurve *uc)
|
||||
{
|
||||
BKE_nurbList_free(&uc->nubase);
|
||||
|
||||
BKE_curve_editNurb_keyIndex_free(&uc->undoIndex);
|
||||
|
||||
BKE_fcurves_free(&uc->drivers);
|
||||
}
|
||||
|
||||
static Object *editcurve_object_from_context(bContext *C)
|
||||
{
|
||||
const Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
BKE_view_layer_synced_ensure(*bmain, scene, view_layer);
|
||||
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
|
||||
if (obedit && ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
|
||||
Curve *cu = id_cast<Curve *>(obedit->data);
|
||||
if (BKE_curve_editNurbs_get(cu) != nullptr) {
|
||||
return obedit;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Implements ED Undo System
|
||||
*
|
||||
* \note This is similar for all edit-mode types.
|
||||
* \{ */
|
||||
|
||||
struct CurveUndoStep_Elem {
|
||||
UndoRefID_Object obedit_ref;
|
||||
UndoCurve data;
|
||||
};
|
||||
|
||||
struct CurveUndoStep {
|
||||
UndoStep step;
|
||||
/** See #ED_undo_object_editmode_validate_scene_from_windows code comment for details. */
|
||||
UndoRefID_Scene scene_ref;
|
||||
CurveUndoStep_Elem *elems;
|
||||
uint elems_len;
|
||||
};
|
||||
|
||||
static bool curve_undosys_poll(bContext *C)
|
||||
{
|
||||
Object *obedit = editcurve_object_from_context(C);
|
||||
return (obedit != nullptr);
|
||||
}
|
||||
|
||||
static bool curve_undosys_step_encode(bContext *C, Main *bmain, UndoStep *us_p)
|
||||
{
|
||||
CurveUndoStep *us = reinterpret_cast<CurveUndoStep *>(us_p);
|
||||
|
||||
/* Important not to use the 3D view when getting objects because all objects
|
||||
* outside of this list will be moved out of edit-mode when reading back undo steps. */
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
Vector<Object *> objects = ED_undo_editmode_objects_from_view_layer(*bmain, scene, view_layer);
|
||||
|
||||
us->scene_ref.ptr = scene;
|
||||
us->elems = MEM_new_array_zeroed<CurveUndoStep_Elem>(objects.size(), __func__);
|
||||
us->elems_len = objects.size();
|
||||
|
||||
for (uint i = 0; i < objects.size(); i++) {
|
||||
Object *ob = objects[i];
|
||||
Curve *cu = id_cast<Curve *>(ob->data);
|
||||
CurveUndoStep_Elem *elem = &us->elems[i];
|
||||
|
||||
elem->obedit_ref.ptr = ob;
|
||||
undocurve_from_editcurve(&elem->data, id_cast<Curve *>(ob->data), ob->shapenr);
|
||||
cu->editnurb->needs_flush_to_id = 1;
|
||||
us->step.data_size += elem->data.undo_size;
|
||||
}
|
||||
|
||||
bmain->is_memfile_undo_flush_needed = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void curve_undosys_step_decode(
|
||||
bContext *C, Main *bmain, UndoStep *us_p, const eUndoStepDir /*dir*/, bool /*is_final*/)
|
||||
{
|
||||
CurveUndoStep *us = reinterpret_cast<CurveUndoStep *>(us_p);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
||||
ED_undo_object_editmode_validate_scene_from_windows(
|
||||
CTX_wm_manager(C), us->scene_ref.ptr, &scene, &view_layer);
|
||||
ED_undo_object_editmode_restore_helper(
|
||||
scene, view_layer, &us->elems[0].obedit_ref.ptr, us->elems_len, sizeof(*us->elems));
|
||||
|
||||
BLI_assert(BKE_object_is_in_editmode(us->elems[0].obedit_ref.ptr));
|
||||
|
||||
for (uint i = 0; i < us->elems_len; i++) {
|
||||
CurveUndoStep_Elem *elem = &us->elems[i];
|
||||
Object *obedit = elem->obedit_ref.ptr;
|
||||
Curve *cu = id_cast<Curve *>(obedit->data);
|
||||
if (cu->editnurb == nullptr) {
|
||||
/* Should never fail, may not crash but can give odd behavior. */
|
||||
CLOG_ERROR(&LOG,
|
||||
"name='%s', failed to enter edit-mode for object '%s', undo state invalid",
|
||||
us_p->name,
|
||||
obedit->id.name);
|
||||
continue;
|
||||
}
|
||||
undocurve_to_editcurve(bmain, &elem->data, id_cast<Curve *>(obedit->data), &obedit->shapenr);
|
||||
cu->editnurb->needs_flush_to_id = 1;
|
||||
DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY);
|
||||
}
|
||||
|
||||
/* The first element is always active */
|
||||
ED_undo_object_set_active_or_warn(
|
||||
*bmain, scene, view_layer, us->elems[0].obedit_ref.ptr, us_p->name, &LOG);
|
||||
|
||||
/* Check after setting active (unless undoing into another scene). */
|
||||
BLI_assert(curve_undosys_poll(C) || (scene != CTX_data_scene(C)));
|
||||
|
||||
bmain->is_memfile_undo_flush_needed = true;
|
||||
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, nullptr);
|
||||
}
|
||||
|
||||
static void curve_undosys_step_free(UndoStep *us_p)
|
||||
{
|
||||
CurveUndoStep *us = reinterpret_cast<CurveUndoStep *>(us_p);
|
||||
|
||||
for (uint i = 0; i < us->elems_len; i++) {
|
||||
CurveUndoStep_Elem *elem = &us->elems[i];
|
||||
undocurve_free_data(&elem->data);
|
||||
}
|
||||
MEM_delete(us->elems);
|
||||
}
|
||||
|
||||
static void curve_undosys_foreach_ID_ref(UndoStep *us_p,
|
||||
UndoTypeForEachIDRefFn foreach_ID_ref_fn,
|
||||
void *user_data)
|
||||
{
|
||||
CurveUndoStep *us = reinterpret_cast<CurveUndoStep *>(us_p);
|
||||
|
||||
foreach_ID_ref_fn(user_data, (reinterpret_cast<UndoRefID *>(&us->scene_ref)));
|
||||
for (uint i = 0; i < us->elems_len; i++) {
|
||||
CurveUndoStep_Elem *elem = &us->elems[i];
|
||||
foreach_ID_ref_fn(user_data, (reinterpret_cast<UndoRefID *>(&elem->obedit_ref)));
|
||||
}
|
||||
}
|
||||
|
||||
void ED_curve_undosys_type(UndoType *ut)
|
||||
{
|
||||
ut->name = "Edit Curve";
|
||||
ut->poll = curve_undosys_poll;
|
||||
ut->step_encode = curve_undosys_step_encode;
|
||||
ut->step_decode = curve_undosys_step_decode;
|
||||
ut->step_free = curve_undosys_step_free;
|
||||
|
||||
ut->step_foreach_ID_ref = curve_undosys_foreach_ID_ref;
|
||||
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(CurveUndoStep);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender
|
||||
2668
blender-5.2.0/source/blender/editors/curve/editfont.cc
Normal file
2668
blender-5.2.0/source/blender/editors/curve/editfont.cc
Normal file
File diff suppressed because it is too large
Load Diff
428
blender-5.2.0/source/blender/editors/curve/editfont_undo.cc
Normal file
428
blender-5.2.0/source/blender/editors/curve/editfont_undo.cc
Normal file
@@ -0,0 +1,428 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edcurve
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "BLI_array_utils.h" /* For #BLI_array_is_zeroed. */
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_layer.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_undo_system.hh"
|
||||
#include "BKE_vfont.hh"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
|
||||
#include "ED_curve.hh"
|
||||
#include "ED_undo.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#define USE_ARRAY_STORE
|
||||
|
||||
#ifdef USE_ARRAY_STORE
|
||||
// # define DEBUG_PRINT
|
||||
# include "BLI_array_store.h"
|
||||
# include "BLI_array_store_utils.h"
|
||||
# include "BLI_listbase.h"
|
||||
# define ARRAY_CHUNK_SIZE 32
|
||||
#endif
|
||||
|
||||
namespace blender {
|
||||
|
||||
/** Only needed this locally. */
|
||||
static CLG_LogRef LOG = {"undo.font"};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Undo Conversion
|
||||
* \{ */
|
||||
|
||||
struct UndoFont {
|
||||
char32_t *textbuf;
|
||||
CharInfo *textbufinfo;
|
||||
|
||||
int len, pos, selstart, selend;
|
||||
|
||||
#ifdef USE_ARRAY_STORE
|
||||
struct {
|
||||
BArrayState *textbuf;
|
||||
BArrayState *textbufinfo;
|
||||
} store;
|
||||
#endif
|
||||
|
||||
size_t undo_size;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef USE_ARRAY_STORE
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Array Store
|
||||
* \{ */
|
||||
|
||||
static struct {
|
||||
BArrayStore_AtSize bs_stride;
|
||||
int users;
|
||||
|
||||
/* We could have the undo API pass in the previous state, for now store a local list */
|
||||
ListBaseT<LinkData> local_links;
|
||||
|
||||
} uf_arraystore = {{nullptr}};
|
||||
|
||||
/**
|
||||
* \param create: When false, only free the arrays.
|
||||
* This is done since when reading from an undo state, they must be temporarily expanded.
|
||||
* then discarded afterwards, having this argument avoids having 2x code paths.
|
||||
*/
|
||||
static void uf_arraystore_compact_ex(UndoFont *uf, const UndoFont *uf_ref, bool create)
|
||||
{
|
||||
# define STATE_COMPACT(uf, id, len) \
|
||||
if ((uf)->id) { \
|
||||
BLI_assert(create == ((uf)->store.id == nullptr)); \
|
||||
if (create) { \
|
||||
const BArrayState *state_reference = uf_ref ? uf_ref->store.id : nullptr; \
|
||||
const size_t stride = sizeof(*(uf)->id); \
|
||||
BArrayStore *bs = BLI_array_store_at_size_ensure( \
|
||||
&uf_arraystore.bs_stride, stride, ARRAY_CHUNK_SIZE); \
|
||||
(uf)->store.id = BLI_array_store_state_add( \
|
||||
bs, (uf)->id, size_t(len) * stride, state_reference); \
|
||||
} \
|
||||
/* keep uf->len for validation */ \
|
||||
MEM_delete((uf)->id); \
|
||||
(uf)->id = nullptr; \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
STATE_COMPACT(uf, textbuf, uf->len + 1);
|
||||
STATE_COMPACT(uf, textbufinfo, uf->len + 1);
|
||||
|
||||
# undef STATE_COMPACT
|
||||
|
||||
if (create) {
|
||||
uf_arraystore.users += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from allocated arrays to de-duplicated states and clear arrays.
|
||||
*/
|
||||
static void uf_arraystore_compact(UndoFont *um, const UndoFont *uf_ref)
|
||||
{
|
||||
uf_arraystore_compact_ex(um, uf_ref, true);
|
||||
}
|
||||
|
||||
static void uf_arraystore_compact_with_info(UndoFont *um, const UndoFont *uf_ref)
|
||||
{
|
||||
# ifdef DEBUG_PRINT
|
||||
size_t size_expanded_prev, size_compacted_prev;
|
||||
BLI_array_store_at_size_calc_memory_usage(
|
||||
&uf_arraystore.bs_stride, &size_expanded_prev, &size_compacted_prev);
|
||||
# endif
|
||||
|
||||
uf_arraystore_compact(um, uf_ref);
|
||||
|
||||
# ifdef DEBUG_PRINT
|
||||
{
|
||||
size_t size_expanded, size_compacted;
|
||||
BLI_array_store_at_size_calc_memory_usage(
|
||||
&uf_arraystore.bs_stride, &size_expanded, &size_compacted);
|
||||
|
||||
const double percent_total = size_expanded ?
|
||||
((double(size_compacted) / double(size_expanded)) * 100.0) :
|
||||
-1.0;
|
||||
|
||||
size_t size_expanded_step = size_expanded - size_expanded_prev;
|
||||
size_t size_compacted_step = size_compacted - size_compacted_prev;
|
||||
const double percent_step = size_expanded_step ?
|
||||
((double(size_compacted_step) / double(size_expanded_step)) *
|
||||
100.0) :
|
||||
-1.0;
|
||||
|
||||
printf("overall memory use: %.8f%% of expanded size\n", percent_total);
|
||||
printf("step memory use: %.8f%% of expanded size\n", percent_step);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove data we only expanded for temporary use.
|
||||
*/
|
||||
static void uf_arraystore_expand_clear(UndoFont *um)
|
||||
{
|
||||
uf_arraystore_compact_ex(um, nullptr, false);
|
||||
}
|
||||
|
||||
static void uf_arraystore_expand(UndoFont *uf)
|
||||
{
|
||||
# define STATE_EXPAND(uf, id, len) \
|
||||
if ((uf)->store.id) { \
|
||||
const size_t stride = sizeof(*(uf)->id); \
|
||||
const BArrayState *state = (uf)->store.id; \
|
||||
size_t state_len; \
|
||||
*(void **)&(uf)->id = BLI_array_store_state_data_get_alloc(state, &state_len); \
|
||||
BLI_assert((len) == (state_len / stride)); \
|
||||
UNUSED_VARS_NDEBUG(stride); \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
STATE_EXPAND(uf, textbuf, uf->len + 1);
|
||||
STATE_EXPAND(uf, textbufinfo, uf->len + 1);
|
||||
|
||||
# undef STATE_EXPAND
|
||||
}
|
||||
|
||||
static void uf_arraystore_free(UndoFont *uf)
|
||||
{
|
||||
# define STATE_FREE(uf, id) \
|
||||
if ((uf)->store.id) { \
|
||||
const size_t stride = sizeof(*(uf)->id); \
|
||||
BArrayStore *bs = BLI_array_store_at_size_get(&uf_arraystore.bs_stride, stride); \
|
||||
BArrayState *state = (uf)->store.id; \
|
||||
BLI_array_store_state_remove(bs, state); \
|
||||
(uf)->store.id = nullptr; \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
STATE_FREE(uf, textbuf);
|
||||
STATE_FREE(uf, textbufinfo);
|
||||
|
||||
# undef STATE_FREE
|
||||
|
||||
uf_arraystore.users -= 1;
|
||||
|
||||
BLI_assert(uf_arraystore.users >= 0);
|
||||
|
||||
if (uf_arraystore.users == 0) {
|
||||
# ifdef DEBUG_PRINT
|
||||
printf("editfont undo store: freeing all data!\n");
|
||||
# endif
|
||||
|
||||
BLI_array_store_at_size_clear(&uf_arraystore.bs_stride);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* USE_ARRAY_STORE */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Undo/Redo Helper Functions
|
||||
* \{ */
|
||||
|
||||
static void undofont_to_editfont(UndoFont *uf, Curve *cu)
|
||||
{
|
||||
EditFont *ef = cu->editfont;
|
||||
|
||||
size_t final_size;
|
||||
|
||||
#ifdef USE_ARRAY_STORE
|
||||
uf_arraystore_expand(uf);
|
||||
#endif
|
||||
|
||||
final_size = sizeof(*ef->textbuf) * (uf->len + 1);
|
||||
memcpy(ef->textbuf, uf->textbuf, final_size);
|
||||
|
||||
final_size = sizeof(CharInfo) * (uf->len + 1);
|
||||
memcpy(ef->textbufinfo, uf->textbufinfo, final_size);
|
||||
|
||||
ef->pos = uf->pos;
|
||||
ef->selstart = uf->selstart;
|
||||
ef->selend = uf->selend;
|
||||
ef->len = uf->len;
|
||||
|
||||
#ifdef USE_ARRAY_STORE
|
||||
uf_arraystore_expand_clear(uf);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *undofont_from_editfont(UndoFont *uf, Curve *cu)
|
||||
{
|
||||
BLI_assert(BLI_array_is_zeroed(uf, 1));
|
||||
|
||||
const EditFont *ef = cu->editfont;
|
||||
|
||||
size_t mem_used_prev = MEM_get_memory_in_use();
|
||||
|
||||
size_t alloc_len = ef->len + 1;
|
||||
|
||||
BLI_assert(sizeof(*uf->textbuf) == sizeof(*ef->textbuf));
|
||||
uf->textbuf = MEM_new_array_uninitialized<char32_t>(alloc_len, __func__);
|
||||
memcpy(uf->textbuf, ef->textbuf, sizeof(char32_t) * alloc_len);
|
||||
|
||||
uf->textbufinfo = MEM_new_array<CharInfo>(alloc_len, __func__);
|
||||
memcpy(uf->textbufinfo, ef->textbufinfo, sizeof(CharInfo) * alloc_len);
|
||||
|
||||
uf->pos = ef->pos;
|
||||
uf->selstart = ef->selstart;
|
||||
uf->selend = ef->selend;
|
||||
uf->len = ef->len;
|
||||
|
||||
#ifdef USE_ARRAY_STORE
|
||||
{
|
||||
const UndoFont *uf_ref = static_cast<const UndoFont *>(
|
||||
uf_arraystore.local_links.last ?
|
||||
(static_cast<LinkData *>(uf_arraystore.local_links.last))->data :
|
||||
nullptr);
|
||||
|
||||
/* Add ourselves. */
|
||||
BLI_addtail(&uf_arraystore.local_links, BLI_genericNodeN(uf));
|
||||
|
||||
uf_arraystore_compact_with_info(uf, uf_ref);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t mem_used_curr = MEM_get_memory_in_use();
|
||||
|
||||
uf->undo_size = mem_used_prev < mem_used_curr ? mem_used_curr - mem_used_prev : sizeof(UndoFont);
|
||||
|
||||
return uf;
|
||||
}
|
||||
|
||||
static void undofont_free_data(UndoFont *uf)
|
||||
{
|
||||
#ifdef USE_ARRAY_STORE
|
||||
{
|
||||
LinkData *link = static_cast<LinkData *>(
|
||||
BLI_findptr(&uf_arraystore.local_links, uf, offsetof(LinkData, data)));
|
||||
BLI_remlink(&uf_arraystore.local_links, link);
|
||||
MEM_delete(link);
|
||||
}
|
||||
uf_arraystore_free(uf);
|
||||
#endif
|
||||
|
||||
if (uf->textbuf) {
|
||||
MEM_delete(uf->textbuf);
|
||||
}
|
||||
if (uf->textbufinfo) {
|
||||
MEM_delete(uf->textbufinfo);
|
||||
}
|
||||
}
|
||||
|
||||
static Object *editfont_object_from_context(bContext *C)
|
||||
{
|
||||
const Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
BKE_view_layer_synced_ensure(*bmain, scene, view_layer);
|
||||
Object *obedit = BKE_view_layer_edit_object_get(view_layer);
|
||||
if (obedit && obedit->type == OB_FONT) {
|
||||
const Curve *cu = id_cast<Curve *>(obedit->data);
|
||||
const EditFont *ef = cu->editfont;
|
||||
if (ef != nullptr) {
|
||||
return obedit;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Implements ED Undo System
|
||||
* \{ */
|
||||
|
||||
struct FontUndoStep {
|
||||
UndoStep step;
|
||||
/** See #ED_undo_object_editmode_validate_scene_from_windows code comment for details. */
|
||||
UndoRefID_Scene scene_ref;
|
||||
/* NOTE: will split out into list for multi-object-editmode. */
|
||||
UndoRefID_Object obedit_ref;
|
||||
UndoFont data;
|
||||
};
|
||||
|
||||
static bool font_undosys_poll(bContext *C)
|
||||
{
|
||||
return editfont_object_from_context(C) != nullptr;
|
||||
}
|
||||
|
||||
static bool font_undosys_step_encode(bContext *C, Main *bmain, UndoStep *us_p)
|
||||
{
|
||||
FontUndoStep *us = reinterpret_cast<FontUndoStep *>(us_p);
|
||||
us->scene_ref.ptr = CTX_data_scene(C);
|
||||
us->obedit_ref.ptr = editfont_object_from_context(C);
|
||||
Curve *cu = id_cast<Curve *>(us->obedit_ref.ptr->data);
|
||||
undofont_from_editfont(&us->data, cu);
|
||||
us->step.data_size = us->data.undo_size;
|
||||
cu->editfont->needs_flush_to_id = 1;
|
||||
bmain->is_memfile_undo_flush_needed = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void font_undosys_step_decode(
|
||||
bContext *C, Main *bmain, UndoStep *us_p, const eUndoStepDir /*dir*/, bool /*is_final*/)
|
||||
{
|
||||
|
||||
FontUndoStep *us = reinterpret_cast<FontUndoStep *>(us_p);
|
||||
Object *obedit = us->obedit_ref.ptr;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
||||
/* Pass in an array of 1 (typically used for multi-object edit-mode). */
|
||||
ED_undo_object_editmode_validate_scene_from_windows(
|
||||
CTX_wm_manager(C), us->scene_ref.ptr, &scene, &view_layer);
|
||||
ED_undo_object_editmode_restore_helper(scene, view_layer, &obedit, 1, sizeof(Object *));
|
||||
|
||||
Curve *cu = id_cast<Curve *>(obedit->data);
|
||||
undofont_to_editfont(&us->data, cu);
|
||||
DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY);
|
||||
|
||||
ED_undo_object_set_active_or_warn(*bmain, scene, view_layer, obedit, us_p->name, &LOG);
|
||||
|
||||
/* Check after setting active (unless undoing into another scene). */
|
||||
BLI_assert(font_undosys_poll(C) || (scene != CTX_data_scene(C)));
|
||||
|
||||
cu->editfont->needs_flush_to_id = 1;
|
||||
bmain->is_memfile_undo_flush_needed = true;
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, nullptr);
|
||||
}
|
||||
|
||||
static void font_undosys_step_free(UndoStep *us_p)
|
||||
{
|
||||
FontUndoStep *us = reinterpret_cast<FontUndoStep *>(us_p);
|
||||
undofont_free_data(&us->data);
|
||||
}
|
||||
|
||||
static void font_undosys_foreach_ID_ref(UndoStep *us_p,
|
||||
UndoTypeForEachIDRefFn foreach_ID_ref_fn,
|
||||
void *user_data)
|
||||
{
|
||||
FontUndoStep *us = reinterpret_cast<FontUndoStep *>(us_p);
|
||||
foreach_ID_ref_fn(user_data, (reinterpret_cast<UndoRefID *>(&us->scene_ref)));
|
||||
foreach_ID_ref_fn(user_data, (reinterpret_cast<UndoRefID *>(&us->obedit_ref)));
|
||||
}
|
||||
|
||||
void ED_font_undosys_type(UndoType *ut)
|
||||
{
|
||||
ut->name = "Edit Font";
|
||||
ut->poll = font_undosys_poll;
|
||||
ut->step_encode = font_undosys_step_encode;
|
||||
ut->step_decode = font_undosys_step_decode;
|
||||
ut->step_free = font_undosys_step_free;
|
||||
|
||||
ut->step_foreach_ID_ref = font_undosys_foreach_ID_ref;
|
||||
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(FontUndoStep);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender
|
||||
Reference in New Issue
Block a user