Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/editors/curve
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/editors/curve')
-rw-r--r--source/blender/editors/curve/CMakeLists.txt56
-rw-r--r--source/blender/editors/curve/curve_intern.h57
-rw-r--r--source/blender/editors/curve/curve_ops.c230
-rw-r--r--source/blender/editors/curve/editcurve.c12123
-rw-r--r--source/blender/editors/curve/editcurve_add.c1260
-rw-r--r--source/blender/editors/curve/editcurve_paint.c1981
-rw-r--r--source/blender/editors/curve/editcurve_select.c3271
-rw-r--r--source/blender/editors/curve/editcurve_undo.c380
-rw-r--r--source/blender/editors/curve/editfont.c3180
-rw-r--r--source/blender/editors/curve/editfont_undo.c394
10 files changed, 11656 insertions, 11276 deletions
diff --git a/source/blender/editors/curve/CMakeLists.txt b/source/blender/editors/curve/CMakeLists.txt
index 4ccf8d59e1f..3df6f3c97d4 100644
--- a/source/blender/editors/curve/CMakeLists.txt
+++ b/source/blender/editors/curve/CMakeLists.txt
@@ -16,46 +16,46 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- ../include
- ../../blenkernel
- ../../blenlib
- ../../blentranslation
- ../../depsgraph
- ../../gpu
- ../../makesdna
- ../../makesrna
- ../../windowmanager
- ../../../../intern/clog
- ../../../../intern/guardedalloc
- ../../../../intern/glew-mx
- ../../../../extern/curve_fit_nd
+ ../include
+ ../../blenkernel
+ ../../blenlib
+ ../../blentranslation
+ ../../depsgraph
+ ../../gpu
+ ../../makesdna
+ ../../makesrna
+ ../../windowmanager
+ ../../../../intern/clog
+ ../../../../intern/guardedalloc
+ ../../../../intern/glew-mx
+ ../../../../extern/curve_fit_nd
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
- curve_ops.c
- editcurve.c
- editcurve_add.c
- editcurve_paint.c
- editcurve_select.c
- editcurve_undo.c
- editfont.c
- editfont_undo.c
-
- curve_intern.h
+ curve_ops.c
+ editcurve.c
+ editcurve_add.c
+ editcurve_paint.c
+ editcurve_select.c
+ editcurve_undo.c
+ editfont.c
+ editfont_undo.c
+
+ curve_intern.h
)
set(LIB
- bf_blenkernel
- bf_blenlib
- extern_curve_fit_nd
+ bf_blenkernel
+ bf_blenlib
+ extern_curve_fit_nd
)
if(WITH_INTERNATIONAL)
- add_definitions(-DWITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
endif()
add_definitions(${GL_DEFINITIONS})
diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h
index c741b5393dc..201ba2560dc 100644
--- a/source/blender/editors/curve/curve_intern.h
+++ b/source/blender/editors/curve/curve_intern.h
@@ -21,7 +21,6 @@
* \ingroup edcurve
*/
-
#ifndef __CURVE_INTERN_H__
#define __CURVE_INTERN_H__
@@ -34,24 +33,42 @@ struct ViewContext;
struct wmOperatorType;
/* editfont.c */
-enum { DEL_NEXT_CHAR, DEL_PREV_CHAR, DEL_NEXT_WORD, DEL_PREV_WORD, DEL_SELECTION, DEL_NEXT_SEL, DEL_PREV_SEL };
+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, PREV_CHAR, NEXT_CHAR, PREV_WORD, NEXT_WORD,
- PREV_LINE, NEXT_LINE, PREV_PAGE, NEXT_PAGE };
+enum {
+ LINE_BEGIN,
+ LINE_END,
+ PREV_CHAR,
+ NEXT_CHAR,
+ PREV_WORD,
+ NEXT_WORD,
+ PREV_LINE,
+ NEXT_LINE,
+ PREV_PAGE,
+ NEXT_PAGE
+};
typedef enum eVisible_Types {
- HIDDEN = true,
- VISIBLE = false,
+ HIDDEN = true,
+ VISIBLE = false,
} eVisible_Types;
typedef enum eEndPoint_Types {
- FIRST = true,
- LAST = false,
+ FIRST = true,
+ LAST = false,
} eEndPoint_Types;
typedef enum eCurveElem_Types {
- CURVE_VERTEX = 0,
- CURVE_SEGMENT,
+ CURVE_VERTEX = 0,
+ CURVE_SEGMENT,
} eCurveElem_Types;
/* internal select utils */
@@ -86,7 +103,6 @@ void FONT_OT_unlink(struct wmOperatorType *ot);
void FONT_OT_textbox_add(struct wmOperatorType *ot);
void FONT_OT_textbox_remove(struct wmOperatorType *ot);
-
/* editcurve.c */
void CURVE_OT_hide(struct wmOperatorType *ot);
void CURVE_OT_reveal(struct wmOperatorType *ot);
@@ -124,17 +140,24 @@ void CURVE_OT_match_texture_space(struct wmOperatorType *ot);
/* exported for editcurve_undo.c */
struct GHash *ED_curve_keyindex_hash_duplicate(struct GHash *keyindex);
-void ED_curve_keyindex_update_nurb(struct EditNurb *editnurb, struct Nurb *nu, struct Nurb *newnu);
+void ED_curve_keyindex_update_nurb(struct EditNurb *editnurb, struct Nurb *nu, struct Nurb *newnu);
-bool ED_curve_pick_vert(
- struct ViewContext *vc, short sel,
- struct Nurb **r_nurb, struct BezTriple **r_bezt, struct BPoint **r_bp, short *r_handle,
- struct Base **r_base);
+bool ED_curve_pick_vert(struct ViewContext *vc,
+ short sel,
+ struct Nurb **r_nurb,
+ struct BezTriple **r_bezt,
+ struct BPoint **r_bp,
+ short *r_handle,
+ struct Base **r_base);
/* helper functions */
void ed_editnurb_translate_flag(struct ListBase *editnurb, short flag, const float vec[3]);
bool ed_editnurb_extrude_flag(struct EditNurb *editnurb, const short flag);
-bool ed_editnurb_spin(float viewmat[4][4], struct View3D *v3d, struct Object *obedit, const float axis[3], const float cent[3]);
+bool ed_editnurb_spin(float viewmat[4][4],
+ struct View3D *v3d,
+ struct Object *obedit,
+ const float axis[3],
+ const float cent[3]);
/* editcurve_select.c */
void CURVE_OT_de_select_first(struct wmOperatorType *ot);
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index de6fe686356..782b093fab4 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -21,11 +21,9 @@
* \ingroup edcurve
*/
-
#include <stdlib.h>
#include <math.h>
-
#include "DNA_curve_types.h"
#include "DNA_scene_types.h"
@@ -46,125 +44,129 @@
void ED_operatortypes_curve(void)
{
- 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_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_extrude);
- WM_operatortype_append(CURVE_OT_cyclic_toggle);
-
- WM_operatortype_append(CURVE_OT_match_texture_space);
+ 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_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_extrude);
+ WM_operatortype_append(CURVE_OT_cyclic_toggle);
+
+ WM_operatortype_append(CURVE_OT_match_texture_space);
}
void ED_operatormacros_curve(void)
{
- 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_enum_set(otmacro->ptr, "proportional", 0);
- 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_enum_set(otmacro->ptr, "proportional", 0);
- RNA_boolean_set(otmacro->ptr, "mirror", false);
+ 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_enum_set(otmacro->ptr, "proportional", 0);
+ 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_enum_set(otmacro->ptr, "proportional", 0);
+ 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", 0, 0);
- keymap->poll = ED_operator_editfont;
+ /* only set in editmode font, by space_view3d listener */
+ wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Font", 0, 0);
+ keymap->poll = ED_operator_editfont;
- /* only set in editmode curve, by space_view3d listener */
- keymap = WM_keymap_ensure(keyconf, "Curve", 0, 0);
- keymap->poll = ED_operator_editsurfcurve;
+ /* only set in editmode curve, by space_view3d listener */
+ keymap = WM_keymap_ensure(keyconf, "Curve", 0, 0);
+ keymap->poll = ED_operator_editsurfcurve;
}
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 4aaf0dc2a2f..c37ce4cc89d 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -77,17 +77,18 @@
#include "RNA_enum_types.h"
void selectend_nurb(Object *obedit, enum eEndPoint_Types selfirst, bool doswap, bool selstatus);
-static void adduplicateflagNurb(Object *obedit, View3D *v3d, ListBase *newnurb, const short flag, const bool split);
+static void adduplicateflagNurb(
+ Object *obedit, View3D *v3d, ListBase *newnurb, const short flag, const bool split);
static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split);
static bool curve_delete_vertices(Object *obedit, View3D *v3d);
ListBase *object_editcurve_get(Object *ob)
{
- if (ob && ELEM(ob->type, OB_CURVE, OB_SURF)) {
- Curve *cu = ob->data;
- return &cu->editnurb->nurbs;
- }
- return NULL;
+ if (ob && ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ Curve *cu = ob->data;
+ return &cu->editnurb->nurbs;
+ }
+ return NULL;
}
/* ******************* PRINTS ********************* */
@@ -95,2725 +96,2741 @@ ListBase *object_editcurve_get(Object *ob)
#if 0
void printknots(Object *obedit)
{
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- int a, num;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (ED_curve_nurb_select_check(nu) && nu->type == CU_NURBS) {
- if (nu->knotsu) {
- num = KNOTSU(nu);
- for (a = 0; a < num; a++) printf("knotu %d: %f\n", a, nu->knotsu[a]);
- }
- if (nu->knotsv) {
- num = KNOTSV(nu);
- for (a = 0; a < num; a++) printf("knotv %d: %f\n", a, nu->knotsv[a]);
- }
- }
- }
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ int a, num;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (ED_curve_nurb_select_check(nu) && nu->type == CU_NURBS) {
+ if (nu->knotsu) {
+ num = KNOTSU(nu);
+ for (a = 0; a < num; a++) printf("knotu %d: %f\n", a, nu->knotsu[a]);
+ }
+ if (nu->knotsv) {
+ num = KNOTSV(nu);
+ for (a = 0; a < num; a++) printf("knotv %d: %f\n", a, nu->knotsv[a]);
+ }
+ }
+ }
}
#endif
/* ********************* Shape keys *************** */
-static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_index, int vertex_index)
+static CVKeyIndex *init_cvKeyIndex(
+ void *cv, int key_index, int nu_index, int pt_index, int vertex_index)
{
- CVKeyIndex *cvIndex = MEM_callocN(sizeof(CVKeyIndex), __func__);
+ CVKeyIndex *cvIndex = MEM_callocN(sizeof(CVKeyIndex), __func__);
- cvIndex->orig_cv = cv;
- cvIndex->key_index = key_index;
- cvIndex->nu_index = nu_index;
- cvIndex->pt_index = pt_index;
- cvIndex->vertex_index = vertex_index;
- cvIndex->switched = false;
+ cvIndex->orig_cv = cv;
+ cvIndex->key_index = key_index;
+ cvIndex->nu_index = nu_index;
+ cvIndex->pt_index = pt_index;
+ cvIndex->vertex_index = vertex_index;
+ cvIndex->switched = false;
- return cvIndex;
+ return cvIndex;
}
static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
{
- Nurb *nu = editnurb->nurbs.first;
- Nurb *orignu = origBase->first;
- GHash *gh;
- BezTriple *bezt, *origbezt;
- BPoint *bp, *origbp;
- CVKeyIndex *keyIndex;
- int a, key_index = 0, nu_index = 0, pt_index = 0, vertex_index = 0;
-
- if (editnurb->keyindex) {
- return;
- }
-
- gh = BLI_ghash_ptr_new("editNurb keyIndex");
-
- while (orignu) {
- if (orignu->bezt) {
- a = orignu->pntsu;
- bezt = nu->bezt;
- origbezt = orignu->bezt;
- pt_index = 0;
- while (a--) {
- /* We cannot keep *any* reference to curve obdata,
- * it might be replaced and freed while editcurve remain in use
- * (in viewport render case e.g.). Note that we could use a pool to avoid
- * lots of malloc's here, but... not really a problem for now. */
- BezTriple *origbezt_cpy = MEM_mallocN(sizeof(*origbezt), __func__);
- *origbezt_cpy = *origbezt;
- keyIndex = init_cvKeyIndex(origbezt_cpy, key_index, nu_index, pt_index, vertex_index);
- BLI_ghash_insert(gh, bezt, keyIndex);
- key_index += KEYELEM_FLOAT_LEN_BEZTRIPLE;
- vertex_index += 3;
- bezt++;
- origbezt++;
- pt_index++;
- }
- }
- else {
- a = orignu->pntsu * orignu->pntsv;
- bp = nu->bp;
- origbp = orignu->bp;
- pt_index = 0;
- while (a--) {
- /* We cannot keep *any* reference to curve obdata,
- * it might be replaced and freed while editcurve remain in use
- * (in viewport render case e.g.). Note that we could use a pool to avoid
- * lots of malloc's here, but... not really a problem for now. */
- BPoint *origbp_cpy = MEM_mallocN(sizeof(*origbp_cpy), __func__);
- *origbp_cpy = *origbp;
- keyIndex = init_cvKeyIndex(origbp_cpy, key_index, nu_index, pt_index, vertex_index);
- BLI_ghash_insert(gh, bp, keyIndex);
- key_index += KEYELEM_FLOAT_LEN_BPOINT;
- bp++;
- origbp++;
- pt_index++;
- vertex_index++;
- }
- }
-
- nu = nu->next;
- orignu = orignu->next;
- nu_index++;
- }
-
- editnurb->keyindex = gh;
+ Nurb *nu = editnurb->nurbs.first;
+ Nurb *orignu = origBase->first;
+ GHash *gh;
+ BezTriple *bezt, *origbezt;
+ BPoint *bp, *origbp;
+ CVKeyIndex *keyIndex;
+ int a, key_index = 0, nu_index = 0, pt_index = 0, vertex_index = 0;
+
+ if (editnurb->keyindex) {
+ return;
+ }
+
+ gh = BLI_ghash_ptr_new("editNurb keyIndex");
+
+ while (orignu) {
+ if (orignu->bezt) {
+ a = orignu->pntsu;
+ bezt = nu->bezt;
+ origbezt = orignu->bezt;
+ pt_index = 0;
+ while (a--) {
+ /* We cannot keep *any* reference to curve obdata,
+ * it might be replaced and freed while editcurve remain in use
+ * (in viewport render case e.g.). Note that we could use a pool to avoid
+ * lots of malloc's here, but... not really a problem for now. */
+ BezTriple *origbezt_cpy = MEM_mallocN(sizeof(*origbezt), __func__);
+ *origbezt_cpy = *origbezt;
+ keyIndex = init_cvKeyIndex(origbezt_cpy, key_index, nu_index, pt_index, vertex_index);
+ BLI_ghash_insert(gh, bezt, keyIndex);
+ key_index += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ vertex_index += 3;
+ bezt++;
+ origbezt++;
+ pt_index++;
+ }
+ }
+ else {
+ a = orignu->pntsu * orignu->pntsv;
+ bp = nu->bp;
+ origbp = orignu->bp;
+ pt_index = 0;
+ while (a--) {
+ /* We cannot keep *any* reference to curve obdata,
+ * it might be replaced and freed while editcurve remain in use
+ * (in viewport render case e.g.). Note that we could use a pool to avoid
+ * lots of malloc's here, but... not really a problem for now. */
+ BPoint *origbp_cpy = MEM_mallocN(sizeof(*origbp_cpy), __func__);
+ *origbp_cpy = *origbp;
+ keyIndex = init_cvKeyIndex(origbp_cpy, key_index, nu_index, pt_index, vertex_index);
+ BLI_ghash_insert(gh, bp, keyIndex);
+ key_index += KEYELEM_FLOAT_LEN_BPOINT;
+ bp++;
+ origbp++;
+ pt_index++;
+ vertex_index++;
+ }
+ }
+
+ nu = nu->next;
+ orignu = orignu->next;
+ nu_index++;
+ }
+
+ editnurb->keyindex = gh;
}
static CVKeyIndex *getCVKeyIndex(EditNurb *editnurb, const void *cv)
{
- return BLI_ghash_lookup(editnurb->keyindex, cv);
+ return BLI_ghash_lookup(editnurb->keyindex, cv);
}
static CVKeyIndex *popCVKeyIndex(EditNurb *editnurb, const void *cv)
{
- return BLI_ghash_popkey(editnurb->keyindex, cv, NULL);
+ return BLI_ghash_popkey(editnurb->keyindex, cv, NULL);
}
static BezTriple *getKeyIndexOrig_bezt(EditNurb *editnurb, const BezTriple *bezt)
{
- CVKeyIndex *index = getCVKeyIndex(editnurb, bezt);
+ CVKeyIndex *index = getCVKeyIndex(editnurb, bezt);
- if (!index) {
- return NULL;
- }
+ if (!index) {
+ return NULL;
+ }
- return (BezTriple *)index->orig_cv;
+ return (BezTriple *)index->orig_cv;
}
static BPoint *getKeyIndexOrig_bp(EditNurb *editnurb, BPoint *bp)
{
- CVKeyIndex *index = getCVKeyIndex(editnurb, bp);
+ CVKeyIndex *index = getCVKeyIndex(editnurb, bp);
- if (!index) {
- return NULL;
- }
+ if (!index) {
+ return NULL;
+ }
- return (BPoint *)index->orig_cv;
+ return (BPoint *)index->orig_cv;
}
static int getKeyIndexOrig_keyIndex(EditNurb *editnurb, void *cv)
{
- CVKeyIndex *index = getCVKeyIndex(editnurb, cv);
+ CVKeyIndex *index = getCVKeyIndex(editnurb, cv);
- if (!index) {
- return -1;
- }
+ if (!index) {
+ return -1;
+ }
- return index->key_index;
+ return index->key_index;
}
static void keyIndex_delBezt(EditNurb *editnurb, BezTriple *bezt)
{
- if (!editnurb->keyindex) {
- return;
- }
+ if (!editnurb->keyindex) {
+ return;
+ }
- BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bezt);
+ BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bezt);
}
static void keyIndex_delBP(EditNurb *editnurb, BPoint *bp)
{
- if (!editnurb->keyindex) {
- return;
- }
+ if (!editnurb->keyindex) {
+ return;
+ }
- BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bp);
+ BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bp);
}
static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu)
{
- int a;
+ int a;
- if (!editnurb->keyindex) {
- return;
- }
+ if (!editnurb->keyindex) {
+ return;
+ }
- if (nu->bezt) {
- const BezTriple *bezt = nu->bezt;
- a = nu->pntsu;
+ if (nu->bezt) {
+ const BezTriple *bezt = nu->bezt;
+ a = nu->pntsu;
- while (a--) {
- BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bezt);
- bezt++;
- }
- }
- else {
- const BPoint *bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bezt);
+ bezt++;
+ }
+ }
+ else {
+ const BPoint *bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
- while (a--) {
- BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bp);
- bp++;
- }
- }
+ while (a--) {
+ BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bp);
+ bp++;
+ }
+ }
}
static void keyIndex_delNurbList(EditNurb *editnurb, ListBase *nubase)
{
- Nurb *nu = nubase->first;
+ Nurb *nu = nubase->first;
- while (nu) {
- keyIndex_delNurb(editnurb, nu);
+ while (nu) {
+ keyIndex_delNurb(editnurb, nu);
- nu = nu->next;
- }
+ nu = nu->next;
+ }
}
-static void keyIndex_updateCV(EditNurb *editnurb, char *cv,
- char *newcv, int count, int size)
+static void keyIndex_updateCV(EditNurb *editnurb, char *cv, char *newcv, int count, int size)
{
- int i;
- CVKeyIndex *index;
+ int i;
+ CVKeyIndex *index;
- if (editnurb->keyindex == NULL) {
- /* No shape keys - updating not needed */
- return;
- }
+ if (editnurb->keyindex == NULL) {
+ /* No shape keys - updating not needed */
+ return;
+ }
- for (i = 0; i < count; i++) {
- index = popCVKeyIndex(editnurb, cv);
+ for (i = 0; i < count; i++) {
+ index = popCVKeyIndex(editnurb, cv);
- if (index) {
- BLI_ghash_insert(editnurb->keyindex, newcv, index);
- }
+ if (index) {
+ BLI_ghash_insert(editnurb->keyindex, newcv, index);
+ }
- newcv += size;
- cv += size;
- }
+ newcv += size;
+ cv += size;
+ }
}
-static void keyIndex_updateBezt(EditNurb *editnurb, BezTriple *bezt,
- BezTriple *newbezt, int count)
+static void keyIndex_updateBezt(EditNurb *editnurb, BezTriple *bezt, BezTriple *newbezt, int count)
{
- keyIndex_updateCV(editnurb, (char *)bezt, (char *)newbezt, count, sizeof(BezTriple));
+ keyIndex_updateCV(editnurb, (char *)bezt, (char *)newbezt, count, sizeof(BezTriple));
}
-static void keyIndex_updateBP(EditNurb *editnurb, BPoint *bp,
- BPoint *newbp, int count)
+static void keyIndex_updateBP(EditNurb *editnurb, BPoint *bp, BPoint *newbp, int count)
{
- keyIndex_updateCV(editnurb, (char *)bp, (char *)newbp, count, sizeof(BPoint));
+ keyIndex_updateCV(editnurb, (char *)bp, (char *)newbp, count, sizeof(BPoint));
}
void ED_curve_keyindex_update_nurb(EditNurb *editnurb, Nurb *nu, Nurb *newnu)
{
- if (nu->bezt) {
- keyIndex_updateBezt(editnurb, nu->bezt, newnu->bezt, newnu->pntsu);
- }
- else {
- keyIndex_updateBP(editnurb, nu->bp, newnu->bp, newnu->pntsu * newnu->pntsv);
- }
+ if (nu->bezt) {
+ keyIndex_updateBezt(editnurb, nu->bezt, newnu->bezt, newnu->pntsu);
+ }
+ else {
+ keyIndex_updateBP(editnurb, nu->bp, newnu->bp, newnu->pntsu * newnu->pntsv);
+ }
}
static void keyIndex_swap(EditNurb *editnurb, void *a, void *b)
{
- CVKeyIndex *index1 = popCVKeyIndex(editnurb, a);
- CVKeyIndex *index2 = popCVKeyIndex(editnurb, b);
+ CVKeyIndex *index1 = popCVKeyIndex(editnurb, a);
+ CVKeyIndex *index2 = popCVKeyIndex(editnurb, b);
- if (index2) {
- BLI_ghash_insert(editnurb->keyindex, a, index2);
- }
- if (index1) {
- BLI_ghash_insert(editnurb->keyindex, b, index1);
- }
+ if (index2) {
+ BLI_ghash_insert(editnurb->keyindex, a, index2);
+ }
+ if (index1) {
+ BLI_ghash_insert(editnurb->keyindex, b, index1);
+ }
}
static void keyIndex_switchDirection(EditNurb *editnurb, Nurb *nu)
{
- int a;
- CVKeyIndex *index1, *index2;
+ int a;
+ CVKeyIndex *index1, *index2;
- if (nu->bezt) {
- BezTriple *bezt1, *bezt2;
+ if (nu->bezt) {
+ BezTriple *bezt1, *bezt2;
- a = nu->pntsu;
+ a = nu->pntsu;
- bezt1 = nu->bezt;
- bezt2 = bezt1 + (a - 1);
+ bezt1 = nu->bezt;
+ bezt2 = bezt1 + (a - 1);
- if (a & 1) {
- a++;
- }
+ if (a & 1) {
+ a++;
+ }
- a /= 2;
+ a /= 2;
- while (a--) {
- index1 = getCVKeyIndex(editnurb, bezt1);
- index2 = getCVKeyIndex(editnurb, bezt2);
+ while (a--) {
+ index1 = getCVKeyIndex(editnurb, bezt1);
+ index2 = getCVKeyIndex(editnurb, bezt2);
- if (index1) {
- index1->switched = !index1->switched;
- }
+ if (index1) {
+ index1->switched = !index1->switched;
+ }
- if (bezt1 != bezt2) {
- keyIndex_swap(editnurb, bezt1, bezt2);
+ if (bezt1 != bezt2) {
+ keyIndex_swap(editnurb, bezt1, bezt2);
- if (index2) {
- index2->switched = !index2->switched;
- }
- }
+ if (index2) {
+ index2->switched = !index2->switched;
+ }
+ }
- bezt1++;
- bezt2--;
- }
- }
- else {
- BPoint *bp1, *bp2;
+ bezt1++;
+ bezt2--;
+ }
+ }
+ else {
+ BPoint *bp1, *bp2;
- if (nu->pntsv == 1) {
- a = nu->pntsu;
- bp1 = nu->bp;
- bp2 = bp1 + (a - 1);
- a /= 2;
- while (bp1 != bp2 && a > 0) {
- index1 = getCVKeyIndex(editnurb, bp1);
- index2 = getCVKeyIndex(editnurb, bp2);
+ if (nu->pntsv == 1) {
+ a = nu->pntsu;
+ bp1 = nu->bp;
+ bp2 = bp1 + (a - 1);
+ a /= 2;
+ while (bp1 != bp2 && a > 0) {
+ index1 = getCVKeyIndex(editnurb, bp1);
+ index2 = getCVKeyIndex(editnurb, bp2);
- if (index1) {
- index1->switched = !index1->switched;
- }
+ if (index1) {
+ index1->switched = !index1->switched;
+ }
- if (bp1 != bp2) {
- if (index2) {
- index2->switched = !index2->switched;
- }
+ if (bp1 != bp2) {
+ if (index2) {
+ index2->switched = !index2->switched;
+ }
- keyIndex_swap(editnurb, bp1, bp2);
- }
+ keyIndex_swap(editnurb, bp1, bp2);
+ }
- a--;
- bp1++;
- bp2--;
- }
- }
- else {
- int b;
+ a--;
+ bp1++;
+ bp2--;
+ }
+ }
+ else {
+ int b;
- for (b = 0; b < nu->pntsv; b++) {
+ for (b = 0; b < nu->pntsv; b++) {
- bp1 = &nu->bp[b * nu->pntsu];
- a = nu->pntsu;
- bp2 = bp1 + (a - 1);
- a /= 2;
+ bp1 = &nu->bp[b * nu->pntsu];
+ a = nu->pntsu;
+ bp2 = bp1 + (a - 1);
+ a /= 2;
- while (bp1 != bp2 && a > 0) {
- index1 = getCVKeyIndex(editnurb, bp1);
- index2 = getCVKeyIndex(editnurb, bp2);
+ while (bp1 != bp2 && a > 0) {
+ index1 = getCVKeyIndex(editnurb, bp1);
+ index2 = getCVKeyIndex(editnurb, bp2);
- if (index1) {
- index1->switched = !index1->switched;
- }
+ if (index1) {
+ index1->switched = !index1->switched;
+ }
- if (bp1 != bp2) {
- if (index2) {
- index2->switched = !index2->switched;
- }
+ if (bp1 != bp2) {
+ if (index2) {
+ index2->switched = !index2->switched;
+ }
- keyIndex_swap(editnurb, bp1, bp2);
- }
+ keyIndex_swap(editnurb, bp1, bp2);
+ }
- a--;
- bp1++;
- bp2--;
- }
- }
-
- }
- }
+ a--;
+ bp1++;
+ bp2--;
+ }
+ }
+ }
+ }
}
static void switch_keys_direction(Curve *cu, Nurb *actnu)
{
- KeyBlock *currkey;
- EditNurb *editnurb = cu->editnurb;
- ListBase *nubase = &editnurb->nurbs;
- Nurb *nu;
- float *fp;
- int a;
-
- currkey = cu->key->block.first;
- while (currkey) {
- fp = currkey->data;
-
- nu = nubase->first;
- while (nu) {
- if (nu->bezt) {
- BezTriple *bezt = nu->bezt;
- a = nu->pntsu;
- if (nu == actnu) {
- while (a--) {
- if (getKeyIndexOrig_bezt(editnurb, bezt)) {
- swap_v3_v3(fp, fp + 6);
- *(fp + 9) = -*(fp + 9);
- fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
- }
- bezt++;
- }
- }
- else {
- fp += a * KEYELEM_FLOAT_LEN_BEZTRIPLE;
- }
- }
- else {
- BPoint *bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- if (nu == actnu) {
- while (a--) {
- if (getKeyIndexOrig_bp(editnurb, bp)) {
- *(fp + 3) = -*(fp + 3);
- fp += KEYELEM_FLOAT_LEN_BPOINT;
- }
- bp++;
- }
- }
- else {
- fp += a * KEYELEM_FLOAT_LEN_BPOINT;
- }
- }
-
- nu = nu->next;
- }
-
- currkey = currkey->next;
- }
+ KeyBlock *currkey;
+ EditNurb *editnurb = cu->editnurb;
+ ListBase *nubase = &editnurb->nurbs;
+ Nurb *nu;
+ float *fp;
+ int a;
+
+ currkey = cu->key->block.first;
+ while (currkey) {
+ fp = currkey->data;
+
+ nu = nubase->first;
+ while (nu) {
+ if (nu->bezt) {
+ BezTriple *bezt = nu->bezt;
+ a = nu->pntsu;
+ if (nu == actnu) {
+ while (a--) {
+ if (getKeyIndexOrig_bezt(editnurb, bezt)) {
+ swap_v3_v3(fp, fp + 6);
+ *(fp + 9) = -*(fp + 9);
+ fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ }
+ bezt++;
+ }
+ }
+ else {
+ fp += a * KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ }
+ }
+ else {
+ BPoint *bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ if (nu == actnu) {
+ while (a--) {
+ if (getKeyIndexOrig_bp(editnurb, bp)) {
+ *(fp + 3) = -*(fp + 3);
+ fp += KEYELEM_FLOAT_LEN_BPOINT;
+ }
+ bp++;
+ }
+ }
+ else {
+ fp += a * KEYELEM_FLOAT_LEN_BPOINT;
+ }
+ }
+
+ nu = nu->next;
+ }
+
+ currkey = currkey->next;
+ }
}
static void keyData_switchDirectionNurb(Curve *cu, Nurb *nu)
{
- EditNurb *editnurb = cu->editnurb;
+ EditNurb *editnurb = cu->editnurb;
- if (!editnurb->keyindex) {
- /* no shape keys - nothing to do */
- return;
- }
+ if (!editnurb->keyindex) {
+ /* no shape keys - nothing to do */
+ return;
+ }
- keyIndex_switchDirection(editnurb, nu);
- if (cu->key) {
- switch_keys_direction(cu, nu);
- }
+ keyIndex_switchDirection(editnurb, nu);
+ if (cu->key) {
+ switch_keys_direction(cu, nu);
+ }
}
GHash *ED_curve_keyindex_hash_duplicate(GHash *keyindex)
{
- GHash *gh;
- GHashIterator gh_iter;
+ GHash *gh;
+ GHashIterator gh_iter;
- gh = BLI_ghash_ptr_new_ex("dupli_keyIndex gh", BLI_ghash_len(keyindex));
+ gh = BLI_ghash_ptr_new_ex("dupli_keyIndex gh", BLI_ghash_len(keyindex));
- GHASH_ITER (gh_iter, keyindex) {
- void *cv = BLI_ghashIterator_getKey(&gh_iter);
- CVKeyIndex *index = BLI_ghashIterator_getValue(&gh_iter);
- CVKeyIndex *newIndex = MEM_mallocN(sizeof(CVKeyIndex), "dupli_keyIndexHash index");
+ GHASH_ITER (gh_iter, keyindex) {
+ void *cv = BLI_ghashIterator_getKey(&gh_iter);
+ CVKeyIndex *index = BLI_ghashIterator_getValue(&gh_iter);
+ CVKeyIndex *newIndex = MEM_mallocN(sizeof(CVKeyIndex), "dupli_keyIndexHash index");
- memcpy(newIndex, index, sizeof(CVKeyIndex));
- newIndex->orig_cv = MEM_dupallocN(index->orig_cv);
+ memcpy(newIndex, index, sizeof(CVKeyIndex));
+ newIndex->orig_cv = MEM_dupallocN(index->orig_cv);
- BLI_ghash_insert(gh, cv, newIndex);
- }
+ BLI_ghash_insert(gh, cv, newIndex);
+ }
- return gh;
+ return gh;
}
static void key_to_bezt(float *key, BezTriple *basebezt, BezTriple *bezt)
{
- memcpy(bezt, basebezt, sizeof(BezTriple));
- memcpy(bezt->vec, key, sizeof(float) * 9);
- bezt->tilt = key[9];
- bezt->radius = key[10];
+ memcpy(bezt, basebezt, sizeof(BezTriple));
+ memcpy(bezt->vec, key, sizeof(float) * 9);
+ bezt->tilt = key[9];
+ bezt->radius = key[10];
}
static void bezt_to_key(BezTriple *bezt, float *key)
{
- memcpy(key, bezt->vec, sizeof(float) * 9);
- key[9] = bezt->tilt;
- key[10] = bezt->radius;
+ memcpy(key, bezt->vec, sizeof(float) * 9);
+ key[9] = bezt->tilt;
+ key[10] = bezt->radius;
}
static void calc_keyHandles(ListBase *nurb, float *key)
{
- Nurb *nu;
- int a;
- float *fp = key;
- BezTriple *bezt;
-
- nu = nurb->first;
- while (nu) {
- if (nu->bezt) {
- BezTriple *prevp, *nextp;
- BezTriple cur, prev, next;
- float *startfp, *prevfp, *nextfp;
-
- bezt = nu->bezt;
- a = nu->pntsu;
- startfp = fp;
-
- if (nu->flagu & CU_NURB_CYCLIC) {
- prevp = bezt + (a - 1);
- prevfp = fp + (KEYELEM_FLOAT_LEN_BEZTRIPLE * (a - 1));
- }
- else {
- prevp = NULL;
- prevfp = NULL;
- }
-
- nextp = bezt + 1;
- nextfp = fp + KEYELEM_FLOAT_LEN_BEZTRIPLE;
-
- while (a--) {
- key_to_bezt(fp, bezt, &cur);
-
- if (nextp) {
- key_to_bezt(nextfp, nextp, &next);
- }
- if (prevp) {
- key_to_bezt(prevfp, prevp, &prev);
- }
-
- BKE_nurb_handle_calc(&cur, prevp ? &prev : NULL, nextp ? &next : NULL, 0, 0);
- bezt_to_key(&cur, fp);
-
- prevp = bezt;
- prevfp = fp;
- if (a == 1) {
- if (nu->flagu & CU_NURB_CYCLIC) {
- nextp = nu->bezt;
- nextfp = startfp;
- }
- else {
- nextp = NULL;
- nextfp = NULL;
- }
- }
- else {
- nextp++;
- nextfp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
- }
-
- bezt++;
- fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
- }
- }
- else {
- a = nu->pntsu * nu->pntsv;
- fp += a * KEYELEM_FLOAT_LEN_BPOINT;
- }
-
- nu = nu->next;
- }
+ Nurb *nu;
+ int a;
+ float *fp = key;
+ BezTriple *bezt;
+
+ nu = nurb->first;
+ while (nu) {
+ if (nu->bezt) {
+ BezTriple *prevp, *nextp;
+ BezTriple cur, prev, next;
+ float *startfp, *prevfp, *nextfp;
+
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ startfp = fp;
+
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ prevp = bezt + (a - 1);
+ prevfp = fp + (KEYELEM_FLOAT_LEN_BEZTRIPLE * (a - 1));
+ }
+ else {
+ prevp = NULL;
+ prevfp = NULL;
+ }
+
+ nextp = bezt + 1;
+ nextfp = fp + KEYELEM_FLOAT_LEN_BEZTRIPLE;
+
+ while (a--) {
+ key_to_bezt(fp, bezt, &cur);
+
+ if (nextp) {
+ key_to_bezt(nextfp, nextp, &next);
+ }
+ if (prevp) {
+ key_to_bezt(prevfp, prevp, &prev);
+ }
+
+ BKE_nurb_handle_calc(&cur, prevp ? &prev : NULL, nextp ? &next : NULL, 0, 0);
+ bezt_to_key(&cur, fp);
+
+ prevp = bezt;
+ prevfp = fp;
+ if (a == 1) {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ nextp = nu->bezt;
+ nextfp = startfp;
+ }
+ else {
+ nextp = NULL;
+ nextfp = NULL;
+ }
+ }
+ else {
+ nextp++;
+ nextfp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ }
+
+ bezt++;
+ fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ }
+ }
+ else {
+ a = nu->pntsu * nu->pntsv;
+ fp += a * KEYELEM_FLOAT_LEN_BPOINT;
+ }
+
+ nu = nu->next;
+ }
}
static void calc_shapeKeys(Object *obedit, ListBase *newnurbs)
{
- Curve *cu = (Curve *)obedit->data;
-
- /* are there keys? */
- if (cu->key) {
- int a, i;
- EditNurb *editnurb = cu->editnurb;
- KeyBlock *currkey;
- KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1);
- BezTriple *bezt, *oldbezt;
- BPoint *bp, *oldbp;
- Nurb *nu, *newnu;
- int totvert = BKE_keyblock_curve_element_count(&editnurb->nurbs);
-
- float (*ofs)[3] = NULL;
- float *oldkey, *newkey, *ofp;
-
- /* editing the base key should update others */
- if (cu->key->type == KEY_RELATIVE) {
- if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */
- int totvec = 0;
-
- /* Calculate needed memory to store offset */
- nu = editnurb->nurbs.first;
- while (nu) {
- if (nu->bezt) {
- /* Three vects to store handles and one for tilt. */
- totvec += nu->pntsu * 4;
- }
- else {
- totvec += 2 * nu->pntsu * nu->pntsv;
- }
-
- nu = nu->next;
- }
-
- ofs = MEM_callocN(sizeof(float) * 3 * totvec, "currkey->data");
- nu = editnurb->nurbs.first;
- i = 0;
- while (nu) {
- if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
-
- if (oldbezt) {
- int j;
- for (j = 0; j < 3; ++j) {
- sub_v3_v3v3(ofs[i], bezt->vec[j], oldbezt->vec[j]);
- i++;
- }
- ofs[i][0] = bezt->tilt - oldbezt->tilt;
- ofs[i][1] = bezt->radius - oldbezt->radius;
- i++;
- }
- else {
- i += 4;
- }
- bezt++;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- oldbp = getKeyIndexOrig_bp(editnurb, bp);
- if (oldbp) {
- sub_v3_v3v3(ofs[i], bp->vec, oldbp->vec);
- ofs[i + 1][0] = bp->tilt - oldbp->tilt;
- ofs[i + 1][1] = bp->radius - oldbp->radius;
- }
- i += 2;
- bp++;
- }
- }
-
- nu = nu->next;
- }
- }
- }
-
- currkey = cu->key->block.first;
- while (currkey) {
- const bool apply_offset = (ofs && (currkey != actkey) && (editnurb->shapenr - 1 == currkey->relative));
-
- float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data");
- ofp = oldkey = currkey->data;
-
- nu = editnurb->nurbs.first;
- /* We need to restore to original curve into newnurb, *not* editcurve's nurbs.
- * Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render), we would
- * invalidate editcurve. */
- newnu = newnurbs->first;
- i = 0;
- while (nu) {
- if (currkey == actkey) {
- const bool restore = actkey != cu->key->refkey;
-
- if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
- BezTriple *newbezt = newnu->bezt;
- while (a--) {
- int j;
- oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
-
- for (j = 0; j < 3; j++, i++) {
- copy_v3_v3(&fp[j * 3], bezt->vec[j]);
-
- if (restore && oldbezt) {
- copy_v3_v3(newbezt->vec[j], oldbezt->vec[j]);
- }
- }
- fp[9] = bezt->tilt;
- fp[10] = bezt->radius;
-
- if (restore && oldbezt) {
- newbezt->tilt = oldbezt->tilt;
- newbezt->radius = oldbezt->radius;
- }
-
- fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
- i++;
- bezt++;
- newbezt++;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- BPoint *newbp = newnu->bp;
- while (a--) {
- oldbp = getKeyIndexOrig_bp(editnurb, bp);
-
- copy_v3_v3(fp, bp->vec);
-
- fp[3] = bp->tilt;
- fp[4] = bp->radius;
-
- if (restore && oldbp) {
- copy_v3_v3(newbp->vec, oldbp->vec);
- newbp->tilt = oldbp->tilt;
- newbp->radius = oldbp->radius;
- }
-
- fp += KEYELEM_FLOAT_LEN_BPOINT;
- bp++;
- newbp++;
- i += 2;
- }
- }
- }
- else {
- int index;
- const float *curofp;
-
- if (oldkey) {
- if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
-
- while (a--) {
- index = getKeyIndexOrig_keyIndex(editnurb, bezt);
- if (index >= 0) {
- int j;
- curofp = ofp + index;
-
- for (j = 0; j < 3; j++, i++) {
- copy_v3_v3(&fp[j * 3], &curofp[j * 3]);
-
- if (apply_offset) {
- add_v3_v3(&fp[j * 3], ofs[i]);
- }
- }
- fp[9] = curofp[9];
- fp[10] = curofp[10];
-
- if (apply_offset) {
- /* Apply tilt offsets. */
- add_v3_v3(fp + 9, ofs[i]);
- i++;
- }
-
- fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
- }
- else {
- int j;
- for (j = 0; j < 3; j++, i++) {
- copy_v3_v3(&fp[j * 3], bezt->vec[j]);
- }
- fp[9] = bezt->tilt;
- fp[10] = bezt->radius;
-
- fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
- }
- bezt++;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- index = getKeyIndexOrig_keyIndex(editnurb, bp);
-
- if (index >= 0) {
- curofp = ofp + index;
- copy_v3_v3(fp, curofp);
- fp[3] = curofp[3];
- fp[4] = curofp[4];
-
- if (apply_offset) {
- add_v3_v3(fp, ofs[i]);
- add_v3_v3(&fp[3], ofs[i + 1]);
- }
- }
- else {
- copy_v3_v3(fp, bp->vec);
- fp[3] = bp->tilt;
- fp[4] = bp->radius;
- }
-
- fp += KEYELEM_FLOAT_LEN_BPOINT;
- bp++;
- i += 2;
- }
- }
- }
- }
-
- nu = nu->next;
- newnu = newnu->next;
- }
-
- if (apply_offset) {
- /* handles could become malicious after offsets applying */
- calc_keyHandles(&editnurb->nurbs, newkey);
- }
-
- currkey->totelem = totvert;
- if (currkey->data) {
- MEM_freeN(currkey->data);
- }
- currkey->data = newkey;
-
- currkey = currkey->next;
- }
-
- if (ofs) {
- MEM_freeN(ofs);
- }
- }
+ Curve *cu = (Curve *)obedit->data;
+
+ /* are there keys? */
+ if (cu->key) {
+ int a, i;
+ EditNurb *editnurb = cu->editnurb;
+ KeyBlock *currkey;
+ KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1);
+ BezTriple *bezt, *oldbezt;
+ BPoint *bp, *oldbp;
+ Nurb *nu, *newnu;
+ int totvert = BKE_keyblock_curve_element_count(&editnurb->nurbs);
+
+ float(*ofs)[3] = NULL;
+ float *oldkey, *newkey, *ofp;
+
+ /* editing the base key should update others */
+ if (cu->key->type == KEY_RELATIVE) {
+ if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */
+ int totvec = 0;
+
+ /* Calculate needed memory to store offset */
+ nu = editnurb->nurbs.first;
+ while (nu) {
+ if (nu->bezt) {
+ /* Three vects to store handles and one for tilt. */
+ totvec += nu->pntsu * 4;
+ }
+ else {
+ totvec += 2 * nu->pntsu * nu->pntsv;
+ }
+
+ nu = nu->next;
+ }
+
+ ofs = MEM_callocN(sizeof(float) * 3 * totvec, "currkey->data");
+ nu = editnurb->nurbs.first;
+ i = 0;
+ while (nu) {
+ if (nu->bezt) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ while (a--) {
+ oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
+
+ if (oldbezt) {
+ int j;
+ for (j = 0; j < 3; ++j) {
+ sub_v3_v3v3(ofs[i], bezt->vec[j], oldbezt->vec[j]);
+ i++;
+ }
+ ofs[i][0] = bezt->tilt - oldbezt->tilt;
+ ofs[i][1] = bezt->radius - oldbezt->radius;
+ i++;
+ }
+ else {
+ i += 4;
+ }
+ bezt++;
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ oldbp = getKeyIndexOrig_bp(editnurb, bp);
+ if (oldbp) {
+ sub_v3_v3v3(ofs[i], bp->vec, oldbp->vec);
+ ofs[i + 1][0] = bp->tilt - oldbp->tilt;
+ ofs[i + 1][1] = bp->radius - oldbp->radius;
+ }
+ i += 2;
+ bp++;
+ }
+ }
+
+ nu = nu->next;
+ }
+ }
+ }
+
+ currkey = cu->key->block.first;
+ while (currkey) {
+ const bool apply_offset = (ofs && (currkey != actkey) &&
+ (editnurb->shapenr - 1 == currkey->relative));
+
+ float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data");
+ ofp = oldkey = currkey->data;
+
+ nu = editnurb->nurbs.first;
+ /* We need to restore to original curve into newnurb, *not* editcurve's nurbs.
+ * Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render), we would
+ * invalidate editcurve. */
+ newnu = newnurbs->first;
+ i = 0;
+ while (nu) {
+ if (currkey == actkey) {
+ const bool restore = actkey != cu->key->refkey;
+
+ if (nu->bezt) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ BezTriple *newbezt = newnu->bezt;
+ while (a--) {
+ int j;
+ oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
+
+ for (j = 0; j < 3; j++, i++) {
+ copy_v3_v3(&fp[j * 3], bezt->vec[j]);
+
+ if (restore && oldbezt) {
+ copy_v3_v3(newbezt->vec[j], oldbezt->vec[j]);
+ }
+ }
+ fp[9] = bezt->tilt;
+ fp[10] = bezt->radius;
+
+ if (restore && oldbezt) {
+ newbezt->tilt = oldbezt->tilt;
+ newbezt->radius = oldbezt->radius;
+ }
+
+ fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ i++;
+ bezt++;
+ newbezt++;
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ BPoint *newbp = newnu->bp;
+ while (a--) {
+ oldbp = getKeyIndexOrig_bp(editnurb, bp);
+
+ copy_v3_v3(fp, bp->vec);
+
+ fp[3] = bp->tilt;
+ fp[4] = bp->radius;
+
+ if (restore && oldbp) {
+ copy_v3_v3(newbp->vec, oldbp->vec);
+ newbp->tilt = oldbp->tilt;
+ newbp->radius = oldbp->radius;
+ }
+
+ fp += KEYELEM_FLOAT_LEN_BPOINT;
+ bp++;
+ newbp++;
+ i += 2;
+ }
+ }
+ }
+ else {
+ int index;
+ const float *curofp;
+
+ if (oldkey) {
+ if (nu->bezt) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+
+ while (a--) {
+ index = getKeyIndexOrig_keyIndex(editnurb, bezt);
+ if (index >= 0) {
+ int j;
+ curofp = ofp + index;
+
+ for (j = 0; j < 3; j++, i++) {
+ copy_v3_v3(&fp[j * 3], &curofp[j * 3]);
+
+ if (apply_offset) {
+ add_v3_v3(&fp[j * 3], ofs[i]);
+ }
+ }
+ fp[9] = curofp[9];
+ fp[10] = curofp[10];
+
+ if (apply_offset) {
+ /* Apply tilt offsets. */
+ add_v3_v3(fp + 9, ofs[i]);
+ i++;
+ }
+
+ fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ }
+ else {
+ int j;
+ for (j = 0; j < 3; j++, i++) {
+ copy_v3_v3(&fp[j * 3], bezt->vec[j]);
+ }
+ fp[9] = bezt->tilt;
+ fp[10] = bezt->radius;
+
+ fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ }
+ bezt++;
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ index = getKeyIndexOrig_keyIndex(editnurb, bp);
+
+ if (index >= 0) {
+ curofp = ofp + index;
+ copy_v3_v3(fp, curofp);
+ fp[3] = curofp[3];
+ fp[4] = curofp[4];
+
+ if (apply_offset) {
+ add_v3_v3(fp, ofs[i]);
+ add_v3_v3(&fp[3], ofs[i + 1]);
+ }
+ }
+ else {
+ copy_v3_v3(fp, bp->vec);
+ fp[3] = bp->tilt;
+ fp[4] = bp->radius;
+ }
+
+ fp += KEYELEM_FLOAT_LEN_BPOINT;
+ bp++;
+ i += 2;
+ }
+ }
+ }
+ }
+
+ nu = nu->next;
+ newnu = newnu->next;
+ }
+
+ if (apply_offset) {
+ /* handles could become malicious after offsets applying */
+ calc_keyHandles(&editnurb->nurbs, newkey);
+ }
+
+ currkey->totelem = totvert;
+ if (currkey->data) {
+ MEM_freeN(currkey->data);
+ }
+ currkey->data = newkey;
+
+ currkey = currkey->next;
+ }
+
+ if (ofs) {
+ MEM_freeN(ofs);
+ }
+ }
}
/* ********************* Amimation data *************** */
static bool curve_is_animated(Curve *cu)
{
- AnimData *ad = BKE_animdata_from_id(&cu->id);
+ AnimData *ad = BKE_animdata_from_id(&cu->id);
- return ad && (ad->action || ad->drivers.first);
+ return ad && (ad->action || ad->drivers.first);
}
-static void fcurve_path_rename(AnimData *adt, const char *orig_rna_path, char *rna_path,
- ListBase *orig_curves, ListBase *curves)
+static void fcurve_path_rename(AnimData *adt,
+ const char *orig_rna_path,
+ char *rna_path,
+ ListBase *orig_curves,
+ ListBase *curves)
{
- FCurve *fcu, *nfcu, *nextfcu;
- int len = strlen(orig_rna_path);
+ FCurve *fcu, *nfcu, *nextfcu;
+ int len = strlen(orig_rna_path);
- for (fcu = orig_curves->first; fcu; fcu = nextfcu) {
- nextfcu = fcu->next;
- if (STREQLEN(fcu->rna_path, orig_rna_path, len)) {
- char *spath, *suffix = fcu->rna_path + len;
- nfcu = copy_fcurve(fcu);
- spath = nfcu->rna_path;
- nfcu->rna_path = BLI_sprintfN("%s%s", rna_path, suffix);
- BLI_addtail(curves, nfcu);
+ for (fcu = orig_curves->first; fcu; fcu = nextfcu) {
+ nextfcu = fcu->next;
+ if (STREQLEN(fcu->rna_path, orig_rna_path, len)) {
+ char *spath, *suffix = fcu->rna_path + len;
+ nfcu = copy_fcurve(fcu);
+ spath = nfcu->rna_path;
+ nfcu->rna_path = BLI_sprintfN("%s%s", rna_path, suffix);
+ BLI_addtail(curves, nfcu);
- if (fcu->grp) {
- action_groups_remove_channel(adt->action, fcu);
- action_groups_add_channel(adt->action, fcu->grp, nfcu);
- }
- else if ((adt->action) && (&adt->action->curves == orig_curves)) {
- BLI_remlink(&adt->action->curves, fcu);
- }
- else {
- BLI_remlink(&adt->drivers, fcu);
- }
+ if (fcu->grp) {
+ action_groups_remove_channel(adt->action, fcu);
+ action_groups_add_channel(adt->action, fcu->grp, nfcu);
+ }
+ else if ((adt->action) && (&adt->action->curves == orig_curves)) {
+ BLI_remlink(&adt->action->curves, fcu);
+ }
+ else {
+ BLI_remlink(&adt->drivers, fcu);
+ }
- free_fcurve(fcu);
+ free_fcurve(fcu);
- MEM_freeN(spath);
- }
- }
+ MEM_freeN(spath);
+ }
+ }
}
static void fcurve_remove(AnimData *adt, ListBase *orig_curves, FCurve *fcu)
{
- if (orig_curves == &adt->drivers) {
- BLI_remlink(&adt->drivers, fcu);
- }
- else {
- action_groups_remove_channel(adt->action, fcu);
- }
+ if (orig_curves == &adt->drivers) {
+ BLI_remlink(&adt->drivers, fcu);
+ }
+ else {
+ action_groups_remove_channel(adt->action, fcu);
+ }
- free_fcurve(fcu);
+ free_fcurve(fcu);
}
static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
{
- int nu_index = 0, a, pt_index;
- EditNurb *editnurb = cu->editnurb;
- Nurb *nu;
- CVKeyIndex *keyIndex;
- char rna_path[64], orig_rna_path[64];
- AnimData *adt = BKE_animdata_from_id(&cu->id);
- ListBase curves = {NULL, NULL};
- FCurve *fcu, *next;
-
- for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) {
- if (nu->bezt) {
- BezTriple *bezt = nu->bezt;
- a = nu->pntsu;
- pt_index = 0;
-
- while (a--) {
- keyIndex = getCVKeyIndex(editnurb, bezt);
- if (keyIndex) {
- BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d].bezier_points[%d]", nu_index, pt_index);
- BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d].bezier_points[%d]", keyIndex->nu_index, keyIndex->pt_index);
-
- if (keyIndex->switched) {
- char handle_path[64], orig_handle_path[64];
- BLI_snprintf(orig_handle_path, sizeof(orig_rna_path), "%s.handle_left", orig_rna_path);
- BLI_snprintf(handle_path, sizeof(rna_path), "%s.handle_right", rna_path);
- fcurve_path_rename(adt, orig_handle_path, handle_path, orig_curves, &curves);
-
- BLI_snprintf(orig_handle_path, sizeof(orig_rna_path), "%s.handle_right", orig_rna_path);
- BLI_snprintf(handle_path, sizeof(rna_path), "%s.handle_left", rna_path);
- fcurve_path_rename(adt, orig_handle_path, handle_path, orig_curves, &curves);
- }
-
- fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
-
- keyIndex->nu_index = nu_index;
- keyIndex->pt_index = pt_index;
- }
-
- bezt++;
- pt_index++;
- }
- }
- else {
- BPoint *bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- pt_index = 0;
-
- while (a--) {
- keyIndex = getCVKeyIndex(editnurb, bp);
- if (keyIndex) {
- BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d].points[%d]", nu_index, pt_index);
- BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d].points[%d]", keyIndex->nu_index, keyIndex->pt_index);
- fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
-
- keyIndex->nu_index = nu_index;
- keyIndex->pt_index = pt_index;
- }
-
- bp++;
- pt_index++;
- }
- }
- }
-
- /* remove paths for removed control points
- * need this to make further step with copying non-cv related curves copying
- * not touching cv's f-curves */
- for (fcu = orig_curves->first; fcu; fcu = next) {
- next = fcu->next;
-
- if (STREQLEN(fcu->rna_path, "splines", 7)) {
- const char *ch = strchr(fcu->rna_path, '.');
-
- if (ch && (STREQLEN(ch, ".bezier_points", 14) || STREQLEN(ch, ".points", 7))) {
- fcurve_remove(adt, orig_curves, fcu);
- }
- }
- }
-
- for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) {
- keyIndex = NULL;
- if (nu->pntsu) {
- if (nu->bezt) {
- keyIndex = getCVKeyIndex(editnurb, &nu->bezt[0]);
- }
- else {
- keyIndex = getCVKeyIndex(editnurb, &nu->bp[0]);
- }
- }
-
- if (keyIndex) {
- BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d]", nu_index);
- BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d]", keyIndex->nu_index);
- fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
- }
- }
-
- /* the remainders in orig_curves can be copied back (like follow path) */
- /* (if it's not path to spline) */
- for (fcu = orig_curves->first; fcu; fcu = next) {
- next = fcu->next;
-
- if (STREQLEN(fcu->rna_path, "splines", 7)) {
- fcurve_remove(adt, orig_curves, fcu);
- }
- else {
- BLI_addtail(&curves, fcu);
- }
- }
-
- *orig_curves = curves;
+ int nu_index = 0, a, pt_index;
+ EditNurb *editnurb = cu->editnurb;
+ Nurb *nu;
+ CVKeyIndex *keyIndex;
+ char rna_path[64], orig_rna_path[64];
+ AnimData *adt = BKE_animdata_from_id(&cu->id);
+ ListBase curves = {NULL, NULL};
+ FCurve *fcu, *next;
+
+ for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) {
+ if (nu->bezt) {
+ BezTriple *bezt = nu->bezt;
+ a = nu->pntsu;
+ pt_index = 0;
+
+ while (a--) {
+ keyIndex = getCVKeyIndex(editnurb, bezt);
+ if (keyIndex) {
+ BLI_snprintf(
+ rna_path, sizeof(rna_path), "splines[%d].bezier_points[%d]", nu_index, pt_index);
+ BLI_snprintf(orig_rna_path,
+ sizeof(orig_rna_path),
+ "splines[%d].bezier_points[%d]",
+ keyIndex->nu_index,
+ keyIndex->pt_index);
+
+ if (keyIndex->switched) {
+ char handle_path[64], orig_handle_path[64];
+ BLI_snprintf(orig_handle_path, sizeof(orig_rna_path), "%s.handle_left", orig_rna_path);
+ BLI_snprintf(handle_path, sizeof(rna_path), "%s.handle_right", rna_path);
+ fcurve_path_rename(adt, orig_handle_path, handle_path, orig_curves, &curves);
+
+ BLI_snprintf(
+ orig_handle_path, sizeof(orig_rna_path), "%s.handle_right", orig_rna_path);
+ BLI_snprintf(handle_path, sizeof(rna_path), "%s.handle_left", rna_path);
+ fcurve_path_rename(adt, orig_handle_path, handle_path, orig_curves, &curves);
+ }
+
+ fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
+
+ keyIndex->nu_index = nu_index;
+ keyIndex->pt_index = pt_index;
+ }
+
+ bezt++;
+ pt_index++;
+ }
+ }
+ else {
+ BPoint *bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ pt_index = 0;
+
+ while (a--) {
+ keyIndex = getCVKeyIndex(editnurb, bp);
+ if (keyIndex) {
+ BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d].points[%d]", nu_index, pt_index);
+ BLI_snprintf(orig_rna_path,
+ sizeof(orig_rna_path),
+ "splines[%d].points[%d]",
+ keyIndex->nu_index,
+ keyIndex->pt_index);
+ fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
+
+ keyIndex->nu_index = nu_index;
+ keyIndex->pt_index = pt_index;
+ }
+
+ bp++;
+ pt_index++;
+ }
+ }
+ }
+
+ /* remove paths for removed control points
+ * need this to make further step with copying non-cv related curves copying
+ * not touching cv's f-curves */
+ for (fcu = orig_curves->first; fcu; fcu = next) {
+ next = fcu->next;
+
+ if (STREQLEN(fcu->rna_path, "splines", 7)) {
+ const char *ch = strchr(fcu->rna_path, '.');
+
+ if (ch && (STREQLEN(ch, ".bezier_points", 14) || STREQLEN(ch, ".points", 7))) {
+ fcurve_remove(adt, orig_curves, fcu);
+ }
+ }
+ }
+
+ for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) {
+ keyIndex = NULL;
+ if (nu->pntsu) {
+ if (nu->bezt) {
+ keyIndex = getCVKeyIndex(editnurb, &nu->bezt[0]);
+ }
+ else {
+ keyIndex = getCVKeyIndex(editnurb, &nu->bp[0]);
+ }
+ }
+
+ if (keyIndex) {
+ BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d]", nu_index);
+ BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d]", keyIndex->nu_index);
+ fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
+ }
+ }
+
+ /* the remainders in orig_curves can be copied back (like follow path) */
+ /* (if it's not path to spline) */
+ for (fcu = orig_curves->first; fcu; fcu = next) {
+ next = fcu->next;
+
+ if (STREQLEN(fcu->rna_path, "splines", 7)) {
+ fcurve_remove(adt, orig_curves, fcu);
+ }
+ else {
+ BLI_addtail(&curves, fcu);
+ }
+ }
+
+ *orig_curves = curves;
}
/* return 0 if animation data wasn't changed, 1 otherwise */
int ED_curve_updateAnimPaths(Main *bmain, Curve *cu)
{
- AnimData *adt = BKE_animdata_from_id(&cu->id);
- EditNurb *editnurb = cu->editnurb;
+ AnimData *adt = BKE_animdata_from_id(&cu->id);
+ EditNurb *editnurb = cu->editnurb;
- if (!editnurb->keyindex) {
- return 0;
- }
+ if (!editnurb->keyindex) {
+ return 0;
+ }
- if (!curve_is_animated(cu)) {
- return 0;
- }
+ if (!curve_is_animated(cu)) {
+ return 0;
+ }
- if (adt->action != NULL) {
- curve_rename_fcurves(cu, &adt->action->curves);
- DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
- }
+ if (adt->action != NULL) {
+ curve_rename_fcurves(cu, &adt->action->curves);
+ DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
+ }
- curve_rename_fcurves(cu, &adt->drivers);
- DEG_id_tag_update(&cu->id, ID_RECALC_COPY_ON_WRITE);
+ curve_rename_fcurves(cu, &adt->drivers);
+ DEG_id_tag_update(&cu->id, ID_RECALC_COPY_ON_WRITE);
- /* TODO(sergey): Only update if something actually changed. */
- DEG_relations_tag_update(bmain);
+ /* TODO(sergey): Only update if something actually changed. */
+ DEG_relations_tag_update(bmain);
- return 1;
+ return 1;
}
/* ********************* LOAD and MAKE *************** */
static int *initialize_index_map(Object *obedit, int *r_old_totvert)
{
- Curve *curve = (Curve *) obedit->data;
- EditNurb *editnurb = curve->editnurb;
- Nurb *nu;
- CVKeyIndex *keyIndex;
- int *old_to_new_map;
- int old_totvert, i;
- int vertex_index;
-
- for (nu = curve->nurb.first, old_totvert = 0; nu != NULL; nu = nu->next) {
- if (nu->bezt) {
- old_totvert += nu->pntsu * 3;
- }
- else {
- old_totvert += nu->pntsu * nu->pntsv;
- }
- }
-
- old_to_new_map = MEM_mallocN(old_totvert * sizeof(int), "curve old to new index map");
- for (i = 0; i < old_totvert; i++) {
- old_to_new_map[i] = -1;
- }
-
- for (nu = editnurb->nurbs.first, vertex_index = 0;
- nu != NULL;
- nu = nu->next)
- {
- if (nu->bezt) {
- BezTriple *bezt = nu->bezt;
- int a = nu->pntsu;
-
- while (a--) {
- keyIndex = getCVKeyIndex(editnurb, bezt);
- if (keyIndex && keyIndex->vertex_index + 2 < old_totvert) {
- if (keyIndex->switched) {
- old_to_new_map[keyIndex->vertex_index] = vertex_index + 2;
- old_to_new_map[keyIndex->vertex_index + 1] = vertex_index + 1;
- old_to_new_map[keyIndex->vertex_index + 2] = vertex_index;
- }
- else {
- old_to_new_map[keyIndex->vertex_index] = vertex_index;
- old_to_new_map[keyIndex->vertex_index + 1] = vertex_index + 1;
- old_to_new_map[keyIndex->vertex_index + 2] = vertex_index + 2;
- }
- }
- vertex_index += 3;
- bezt++;
- }
- }
- else {
- BPoint *bp = nu->bp;
- int a = nu->pntsu * nu->pntsv;
-
- while (a--) {
- keyIndex = getCVKeyIndex(editnurb, bp);
- if (keyIndex) {
- old_to_new_map[keyIndex->vertex_index] = vertex_index;
- }
- vertex_index++;
- bp++;
- }
- }
- }
-
- *r_old_totvert = old_totvert;
- return old_to_new_map;
+ Curve *curve = (Curve *)obedit->data;
+ EditNurb *editnurb = curve->editnurb;
+ Nurb *nu;
+ CVKeyIndex *keyIndex;
+ int *old_to_new_map;
+ int old_totvert, i;
+ int vertex_index;
+
+ for (nu = curve->nurb.first, old_totvert = 0; nu != NULL; nu = nu->next) {
+ if (nu->bezt) {
+ old_totvert += nu->pntsu * 3;
+ }
+ else {
+ old_totvert += nu->pntsu * nu->pntsv;
+ }
+ }
+
+ old_to_new_map = MEM_mallocN(old_totvert * sizeof(int), "curve old to new index map");
+ for (i = 0; i < old_totvert; i++) {
+ old_to_new_map[i] = -1;
+ }
+
+ for (nu = editnurb->nurbs.first, vertex_index = 0; nu != NULL; nu = nu->next) {
+ if (nu->bezt) {
+ BezTriple *bezt = nu->bezt;
+ int a = nu->pntsu;
+
+ while (a--) {
+ keyIndex = getCVKeyIndex(editnurb, bezt);
+ if (keyIndex && keyIndex->vertex_index + 2 < old_totvert) {
+ if (keyIndex->switched) {
+ old_to_new_map[keyIndex->vertex_index] = vertex_index + 2;
+ old_to_new_map[keyIndex->vertex_index + 1] = vertex_index + 1;
+ old_to_new_map[keyIndex->vertex_index + 2] = vertex_index;
+ }
+ else {
+ old_to_new_map[keyIndex->vertex_index] = vertex_index;
+ old_to_new_map[keyIndex->vertex_index + 1] = vertex_index + 1;
+ old_to_new_map[keyIndex->vertex_index + 2] = vertex_index + 2;
+ }
+ }
+ vertex_index += 3;
+ bezt++;
+ }
+ }
+ else {
+ BPoint *bp = nu->bp;
+ int a = nu->pntsu * nu->pntsv;
+
+ while (a--) {
+ keyIndex = getCVKeyIndex(editnurb, bp);
+ if (keyIndex) {
+ old_to_new_map[keyIndex->vertex_index] = vertex_index;
+ }
+ vertex_index++;
+ bp++;
+ }
+ }
+ }
+
+ *r_old_totvert = old_totvert;
+ return old_to_new_map;
}
static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
{
- Object *object;
- Curve *curve = (Curve *) obedit->data;
- EditNurb *editnurb = curve->editnurb;
- int *old_to_new_map = NULL;
- int old_totvert;
-
- if (editnurb->keyindex == NULL) {
- /* TODO(sergey): Happens when separating curves, this would lead to
- * the wrong indices in the hook modifier, address this together with
- * other indices issues.
- */
- return;
- }
-
- for (object = bmain->objects.first; object; object = object->id.next) {
- ModifierData *md;
- int index;
- if ((object->parent) &&
- (object->parent->data == curve) &&
- ELEM(object->partype, PARVERT1, PARVERT3))
- {
- if (old_to_new_map == NULL) {
- old_to_new_map = initialize_index_map(obedit, &old_totvert);
- }
-
- if (object->par1 < old_totvert) {
- index = old_to_new_map[object->par1];
- if (index != -1) {
- object->par1 = index;
- }
- }
- if (object->par2 < old_totvert) {
- index = old_to_new_map[object->par2];
- if (index != -1) {
- object->par2 = index;
- }
- }
- if (object->par3 < old_totvert) {
- index = old_to_new_map[object->par3];
- if (index != -1) {
- object->par3 = index;
- }
- }
- }
- if (object->data == curve) {
- for (md = object->modifiers.first; md; md = md->next) {
- if (md->type == eModifierType_Hook) {
- HookModifierData *hmd = (HookModifierData *) md;
- int i, j;
-
- if (old_to_new_map == NULL) {
- old_to_new_map = initialize_index_map(obedit, &old_totvert);
- }
-
- for (i = j = 0; i < hmd->totindex; i++) {
- if (hmd->indexar[i] < old_totvert) {
- index = old_to_new_map[hmd->indexar[i]];
- if (index != -1) {
- hmd->indexar[j++] = index;
- }
- }
- else {
- j++;
- }
- }
-
- hmd->totindex = j;
- }
- }
- }
- }
- if (old_to_new_map != NULL) {
- MEM_freeN(old_to_new_map);
- }
+ Object *object;
+ Curve *curve = (Curve *)obedit->data;
+ EditNurb *editnurb = curve->editnurb;
+ int *old_to_new_map = NULL;
+ int old_totvert;
+
+ if (editnurb->keyindex == NULL) {
+ /* TODO(sergey): Happens when separating curves, this would lead to
+ * the wrong indices in the hook modifier, address this together with
+ * other indices issues.
+ */
+ return;
+ }
+
+ for (object = bmain->objects.first; object; object = object->id.next) {
+ ModifierData *md;
+ int index;
+ if ((object->parent) && (object->parent->data == curve) &&
+ ELEM(object->partype, PARVERT1, PARVERT3)) {
+ if (old_to_new_map == NULL) {
+ old_to_new_map = initialize_index_map(obedit, &old_totvert);
+ }
+
+ if (object->par1 < old_totvert) {
+ index = old_to_new_map[object->par1];
+ if (index != -1) {
+ object->par1 = index;
+ }
+ }
+ if (object->par2 < old_totvert) {
+ index = old_to_new_map[object->par2];
+ if (index != -1) {
+ object->par2 = index;
+ }
+ }
+ if (object->par3 < old_totvert) {
+ index = old_to_new_map[object->par3];
+ if (index != -1) {
+ object->par3 = index;
+ }
+ }
+ }
+ if (object->data == curve) {
+ for (md = object->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Hook) {
+ HookModifierData *hmd = (HookModifierData *)md;
+ int i, j;
+
+ if (old_to_new_map == NULL) {
+ old_to_new_map = initialize_index_map(obedit, &old_totvert);
+ }
+
+ for (i = j = 0; i < hmd->totindex; i++) {
+ if (hmd->indexar[i] < old_totvert) {
+ index = old_to_new_map[hmd->indexar[i]];
+ if (index != -1) {
+ hmd->indexar[j++] = index;
+ }
+ }
+ else {
+ j++;
+ }
+ }
+
+ hmd->totindex = j;
+ }
+ }
+ }
+ }
+ if (old_to_new_map != NULL) {
+ MEM_freeN(old_to_new_map);
+ }
}
/* load editNurb in object */
void ED_curve_editnurb_load(Main *bmain, Object *obedit)
{
- ListBase *editnurb = object_editcurve_get(obedit);
+ ListBase *editnurb = object_editcurve_get(obedit);
- if (obedit == NULL) {
- return;
- }
+ if (obedit == NULL) {
+ return;
+ }
- if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
- Curve *cu = obedit->data;
- Nurb *nu, *newnu;
- ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb;
+ if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ Curve *cu = obedit->data;
+ Nurb *nu, *newnu;
+ ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb;
- remap_hooks_and_vertex_parents(bmain, obedit);
+ remap_hooks_and_vertex_parents(bmain, obedit);
- for (nu = editnurb->first; nu; nu = nu->next) {
- newnu = BKE_nurb_duplicate(nu);
- BLI_addtail(&newnurb, newnu);
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ newnu = BKE_nurb_duplicate(nu);
+ BLI_addtail(&newnurb, newnu);
- if (nu->type == CU_NURBS) {
- BKE_nurb_order_clamp_u(nu);
- }
- }
+ if (nu->type == CU_NURBS) {
+ BKE_nurb_order_clamp_u(nu);
+ }
+ }
- /* We have to pass also new copied nurbs, since we want to restore original curve (without edited shapekey)
- * on obdata, but *not* on editcurve itself (ED_curve_editnurb_load call does not always implies freeing
- * of editcurve, e.g. when called to generate render data...). */
- calc_shapeKeys(obedit, &newnurb);
+ /* We have to pass also new copied nurbs, since we want to restore original curve (without edited shapekey)
+ * on obdata, but *not* on editcurve itself (ED_curve_editnurb_load call does not always implies freeing
+ * of editcurve, e.g. when called to generate render data...). */
+ calc_shapeKeys(obedit, &newnurb);
- cu->nurb = newnurb;
+ cu->nurb = newnurb;
- ED_curve_updateAnimPaths(bmain, obedit->data);
+ ED_curve_updateAnimPaths(bmain, obedit->data);
- BKE_nurbList_free(&oldnurb);
- }
+ BKE_nurbList_free(&oldnurb);
+ }
}
/* make copy in cu->editnurb */
void ED_curve_editnurb_make(Object *obedit)
{
- Curve *cu = (Curve *)obedit->data;
- EditNurb *editnurb = cu->editnurb;
- Nurb *nu, *newnu;
- KeyBlock *actkey;
+ Curve *cu = (Curve *)obedit->data;
+ EditNurb *editnurb = cu->editnurb;
+ Nurb *nu, *newnu;
+ KeyBlock *actkey;
- if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
- actkey = BKE_keyblock_from_object(obedit);
+ if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ actkey = BKE_keyblock_from_object(obedit);
- if (actkey) {
- // XXX strcpy(G.editModeTitleExtra, "(Key) ");
- /* TODO(campbell): undo_system: investigate why this was needed. */
+ if (actkey) {
+ // XXX strcpy(G.editModeTitleExtra, "(Key) ");
+ /* TODO(campbell): undo_system: investigate why this was needed. */
#if 0
- undo_editmode_clear();
+ undo_editmode_clear();
#endif
- }
-
- if (editnurb) {
- BKE_nurbList_free(&editnurb->nurbs);
- BKE_curve_editNurb_keyIndex_free(&editnurb->keyindex);
- }
- else {
- editnurb = MEM_callocN(sizeof(EditNurb), "editnurb");
- cu->editnurb = editnurb;
- }
-
- nu = cu->nurb.first;
- while (nu) {
- newnu = BKE_nurb_duplicate(nu);
- BKE_nurb_test_2d(newnu); // after join, or any other creation of curve
- BLI_addtail(&editnurb->nurbs, newnu);
- nu = nu->next;
- }
-
- /* animation could be added in editmode even if there was no animdata in
- * object mode hence we always need CVs index be created */
- init_editNurb_keyIndex(editnurb, &cu->nurb);
-
- if (actkey) {
- editnurb->shapenr = obedit->shapenr;
- /* Apply shapekey to new nurbs of editnurb, not those of original curve
- * (and *after* we generated keyIndex), else we do not have valid 'original' data
- * to properly restore curve when leaving editmode. */
- BKE_keyblock_convert_to_curve(actkey, cu, &editnurb->nurbs);
- }
- }
+ }
+
+ if (editnurb) {
+ BKE_nurbList_free(&editnurb->nurbs);
+ BKE_curve_editNurb_keyIndex_free(&editnurb->keyindex);
+ }
+ else {
+ editnurb = MEM_callocN(sizeof(EditNurb), "editnurb");
+ cu->editnurb = editnurb;
+ }
+
+ nu = cu->nurb.first;
+ while (nu) {
+ newnu = BKE_nurb_duplicate(nu);
+ BKE_nurb_test_2d(newnu); // after join, or any other creation of curve
+ BLI_addtail(&editnurb->nurbs, newnu);
+ nu = nu->next;
+ }
+
+ /* animation could be added in editmode even if there was no animdata in
+ * object mode hence we always need CVs index be created */
+ init_editNurb_keyIndex(editnurb, &cu->nurb);
+
+ if (actkey) {
+ editnurb->shapenr = obedit->shapenr;
+ /* Apply shapekey to new nurbs of editnurb, not those of original curve
+ * (and *after* we generated keyIndex), else we do not have valid 'original' data
+ * to properly restore curve when leaving editmode. */
+ BKE_keyblock_convert_to_curve(actkey, cu, &editnurb->nurbs);
+ }
+ }
}
void ED_curve_editnurb_free(Object *obedit)
{
- Curve *cu = obedit->data;
+ Curve *cu = obedit->data;
- BKE_curve_editNurb_free(cu);
+ BKE_curve_editNurb_free(cu);
}
/******************** separate operator ***********************/
static int separate_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- struct {
- int changed;
- int unselected;
- int error_vertex_keys;
- int error_generic;
- } status = {0};
-
- WM_cursor_wait(1);
-
- uint bases_len = 0;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &bases_len);
- for (uint b_index = 0; b_index < bases_len; b_index++) {
- Base *oldbase = bases[b_index];
- Base *newbase;
- Object *oldob, *newob;
- Curve *oldcu, *newcu;
- EditNurb *newedit;
- ListBase newnurb = {NULL, NULL};
-
- oldob = oldbase->object;
- oldcu = oldob->data;
-
- if (oldcu->key) {
- status.error_vertex_keys++;
- continue;
- }
-
- if (!ED_curve_select_check(v3d, oldcu->editnurb)) {
- status.unselected++;
- continue;
- }
-
- /* 1. Duplicate geometry and check for valid selection for separate. */
- adduplicateflagNurb(oldob, v3d, &newnurb, SELECT, true);
-
- if (BLI_listbase_is_empty(&newnurb)) {
- status.error_generic++;
- continue;
- }
-
- /* 2. Duplicate the object and data. */
- newbase = ED_object_add_duplicate(
- bmain, scene, view_layer, oldbase, 0); /* 0 = fully linked. */
- DEG_relations_tag_update(bmain);
-
- newob = newbase->object;
- newcu = newob->data = BKE_curve_copy(bmain, oldcu);
- newcu->editnurb = NULL;
- id_us_min(&oldcu->id); /* Because new curve is a copy: reduce user count. */
-
- /* 3. Put new object in editmode, clear it and set separated nurbs. */
- ED_curve_editnurb_make(newob);
- newedit = newcu->editnurb;
- BKE_nurbList_free(&newedit->nurbs);
- BKE_curve_editNurb_keyIndex_free(&newedit->keyindex);
- BLI_movelisttolist(&newedit->nurbs, &newnurb);
-
- /* 4. Put old object out of editmode and delete separated geometry. */
- ED_curve_editnurb_load(bmain, newob);
- ED_curve_editnurb_free(newob);
- curve_delete_segments(oldob, v3d, true);
-
- DEG_id_tag_update(&oldob->id, ID_RECALC_GEOMETRY); /* This is the original one. */
- DEG_id_tag_update(&newob->id, ID_RECALC_GEOMETRY); /* This is the separated one. */
-
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, oldob->data);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, newob);
- status.changed++;
- }
- MEM_freeN(bases);
- WM_cursor_wait(0);
-
- if (status.unselected == bases_len) {
- BKE_report(op->reports, RPT_ERROR, "No point was selected");
- return OPERATOR_CANCELLED;
- }
-
- const int tot_errors = status.error_vertex_keys + status.error_generic;
- if (tot_errors > 0) {
-
- /* Some curves changed, but some curves failed: don't explain why it failed. */
- if (status.changed) {
- BKE_reportf(op->reports,
- RPT_INFO,
- tot_errors == 1 ? "%d curve could not be separated" :
- "%d curves could not be separated",
- tot_errors);
- return OPERATOR_FINISHED;
- }
-
- /* All curves failed: If there is more than one error give a generic error report. */
- if (((status.error_vertex_keys ? 1 : 0) + (status.error_generic ? 1 : 0)) > 1) {
- BKE_report(op->reports,
- RPT_ERROR,
- tot_errors == 1 ? "Could not separate selected curves" :
- "Could not separate selected curve");
- }
-
- /* All curves failed due to the same error. */
- if (status.error_vertex_keys) {
- BKE_report(op->reports, RPT_ERROR, "Cannot separate curves with vertex keys");
- }
- else {
- BLI_assert(status.error_generic);
- BKE_report(op->reports, RPT_ERROR, "Cannot separate current selection");
- }
- return OPERATOR_CANCELLED;
- }
-
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ struct {
+ int changed;
+ int unselected;
+ int error_vertex_keys;
+ int error_generic;
+ } status = {0};
+
+ WM_cursor_wait(1);
+
+ uint bases_len = 0;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &bases_len);
+ for (uint b_index = 0; b_index < bases_len; b_index++) {
+ Base *oldbase = bases[b_index];
+ Base *newbase;
+ Object *oldob, *newob;
+ Curve *oldcu, *newcu;
+ EditNurb *newedit;
+ ListBase newnurb = {NULL, NULL};
+
+ oldob = oldbase->object;
+ oldcu = oldob->data;
+
+ if (oldcu->key) {
+ status.error_vertex_keys++;
+ continue;
+ }
+
+ if (!ED_curve_select_check(v3d, oldcu->editnurb)) {
+ status.unselected++;
+ continue;
+ }
+
+ /* 1. Duplicate geometry and check for valid selection for separate. */
+ adduplicateflagNurb(oldob, v3d, &newnurb, SELECT, true);
+
+ if (BLI_listbase_is_empty(&newnurb)) {
+ status.error_generic++;
+ continue;
+ }
+
+ /* 2. Duplicate the object and data. */
+ newbase = ED_object_add_duplicate(
+ bmain, scene, view_layer, oldbase, 0); /* 0 = fully linked. */
+ DEG_relations_tag_update(bmain);
+
+ newob = newbase->object;
+ newcu = newob->data = BKE_curve_copy(bmain, oldcu);
+ newcu->editnurb = NULL;
+ id_us_min(&oldcu->id); /* Because new curve is a copy: reduce user count. */
+
+ /* 3. Put new object in editmode, clear it and set separated nurbs. */
+ ED_curve_editnurb_make(newob);
+ newedit = newcu->editnurb;
+ BKE_nurbList_free(&newedit->nurbs);
+ BKE_curve_editNurb_keyIndex_free(&newedit->keyindex);
+ BLI_movelisttolist(&newedit->nurbs, &newnurb);
+
+ /* 4. Put old object out of editmode and delete separated geometry. */
+ ED_curve_editnurb_load(bmain, newob);
+ ED_curve_editnurb_free(newob);
+ curve_delete_segments(oldob, v3d, true);
+
+ DEG_id_tag_update(&oldob->id, ID_RECALC_GEOMETRY); /* This is the original one. */
+ DEG_id_tag_update(&newob->id, ID_RECALC_GEOMETRY); /* This is the separated one. */
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, oldob->data);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, newob);
+ status.changed++;
+ }
+ MEM_freeN(bases);
+ WM_cursor_wait(0);
+
+ if (status.unselected == bases_len) {
+ BKE_report(op->reports, RPT_ERROR, "No point was selected");
+ return OPERATOR_CANCELLED;
+ }
+
+ const int tot_errors = status.error_vertex_keys + status.error_generic;
+ if (tot_errors > 0) {
+
+ /* Some curves changed, but some curves failed: don't explain why it failed. */
+ if (status.changed) {
+ BKE_reportf(op->reports,
+ RPT_INFO,
+ tot_errors == 1 ? "%d curve could not be separated" :
+ "%d curves could not be separated",
+ tot_errors);
+ return OPERATOR_FINISHED;
+ }
+
+ /* All curves failed: If there is more than one error give a generic error report. */
+ if (((status.error_vertex_keys ? 1 : 0) + (status.error_generic ? 1 : 0)) > 1) {
+ BKE_report(op->reports,
+ RPT_ERROR,
+ tot_errors == 1 ? "Could not separate selected curves" :
+ "Could not separate selected curve");
+ }
+
+ /* All curves failed due to the same error. */
+ if (status.error_vertex_keys) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot separate curves with vertex keys");
+ }
+ else {
+ BLI_assert(status.error_generic);
+ BKE_report(op->reports, RPT_ERROR, "Cannot separate current selection");
+ }
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
}
void CURVE_OT_separate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Separate";
- ot->idname = "CURVE_OT_separate";
- ot->description = "Separate selected points from connected unselected points into a new object";
+ /* identifiers */
+ ot->name = "Separate";
+ ot->idname = "CURVE_OT_separate";
+ ot->description = "Separate selected points from connected unselected points into a new object";
- /* api callbacks */
- ot->invoke = WM_operator_confirm;
- ot->exec = separate_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = separate_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/******************** split operator ***********************/
static int curve_split_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- int ok = -1;
+ Main *bmain = CTX_data_main(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ int ok = -1;
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
- ListBase newnurb = {NULL, NULL};
+ ListBase newnurb = {NULL, NULL};
- adduplicateflagNurb(obedit, v3d, &newnurb, SELECT, true);
+ adduplicateflagNurb(obedit, v3d, &newnurb, SELECT, true);
- if (BLI_listbase_is_empty(&newnurb)) {
- ok = MAX2(ok, 0);
- continue;
- }
+ if (BLI_listbase_is_empty(&newnurb)) {
+ ok = MAX2(ok, 0);
+ continue;
+ }
- ListBase *editnurb = object_editcurve_get(obedit);
- const int len_orig = BLI_listbase_count(editnurb);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ const int len_orig = BLI_listbase_count(editnurb);
- curve_delete_segments(obedit, v3d, true);
- cu->actnu -= len_orig - BLI_listbase_count(editnurb);
- BLI_movelisttolist(editnurb, &newnurb);
+ curve_delete_segments(obedit, v3d, true);
+ cu->actnu -= len_orig - BLI_listbase_count(editnurb);
+ BLI_movelisttolist(editnurb, &newnurb);
- if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
+ if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
- ok = 1;
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- MEM_freeN(objects);
+ ok = 1;
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ MEM_freeN(objects);
- if (ok == 0) {
- BKE_report(op->reports, RPT_ERROR, "Cannot split current selection");
- return OPERATOR_CANCELLED;
- }
- return OPERATOR_FINISHED;
+ if (ok == 0) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot split current selection");
+ return OPERATOR_CANCELLED;
+ }
+ return OPERATOR_FINISHED;
}
void CURVE_OT_split(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Split";
- ot->idname = "CURVE_OT_split";
- ot->description = "Split off selected points from connected unselected points";
+ /* identifiers */
+ ot->name = "Split";
+ ot->idname = "CURVE_OT_split";
+ ot->description = "Split off selected points from connected unselected points";
- /* api callbacks */
- ot->exec = curve_split_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = curve_split_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************* FLAGS ********************* */
-static bool isNurbselUV(
- const Nurb *nu, int flag,
- int *r_u, int *r_v)
-{
- /* return (u != -1): 1 row in u-direction selected. U has value between 0-pntsv
- * return (v != -1): 1 column in v-direction selected. V has value between 0-pntsu
- */
- BPoint *bp;
- int a, b, sel;
-
- *r_u = *r_v = -1;
-
- bp = nu->bp;
- for (b = 0; b < nu->pntsv; b++) {
- sel = 0;
- for (a = 0; a < nu->pntsu; a++, bp++) {
- if (bp->f1 & flag) {
- sel++;
- }
- }
- if (sel == nu->pntsu) {
- if (*r_u == -1) {
- *r_u = b;
- }
- else {
- return 0;
- }
- }
- else if (sel > 1) {
- return 0; /* because sel == 1 is still ok */
- }
- }
-
- for (a = 0; a < nu->pntsu; a++) {
- sel = 0;
- bp = &nu->bp[a];
- for (b = 0; b < nu->pntsv; b++, bp += nu->pntsu) {
- if (bp->f1 & flag) {
- sel++;
- }
- }
- if (sel == nu->pntsv) {
- if (*r_v == -1) {
- *r_v = a;
- }
- else {
- return 0;
- }
- }
- else if (sel > 1) {
- return 0;
- }
- }
-
- if (*r_u == -1 && *r_v > -1) {
- return 1;
- }
- if (*r_v == -1 && *r_u > -1) {
- return 1;
- }
- return 0;
+static bool isNurbselUV(const Nurb *nu, int flag, int *r_u, int *r_v)
+{
+ /* return (u != -1): 1 row in u-direction selected. U has value between 0-pntsv
+ * return (v != -1): 1 column in v-direction selected. V has value between 0-pntsu
+ */
+ BPoint *bp;
+ int a, b, sel;
+
+ *r_u = *r_v = -1;
+
+ bp = nu->bp;
+ for (b = 0; b < nu->pntsv; b++) {
+ sel = 0;
+ for (a = 0; a < nu->pntsu; a++, bp++) {
+ if (bp->f1 & flag) {
+ sel++;
+ }
+ }
+ if (sel == nu->pntsu) {
+ if (*r_u == -1) {
+ *r_u = b;
+ }
+ else {
+ return 0;
+ }
+ }
+ else if (sel > 1) {
+ return 0; /* because sel == 1 is still ok */
+ }
+ }
+
+ for (a = 0; a < nu->pntsu; a++) {
+ sel = 0;
+ bp = &nu->bp[a];
+ for (b = 0; b < nu->pntsv; b++, bp += nu->pntsu) {
+ if (bp->f1 & flag) {
+ sel++;
+ }
+ }
+ if (sel == nu->pntsv) {
+ if (*r_v == -1) {
+ *r_v = a;
+ }
+ else {
+ return 0;
+ }
+ }
+ else if (sel > 1) {
+ return 0;
+ }
+ }
+
+ if (*r_u == -1 && *r_v > -1) {
+ return 1;
+ }
+ if (*r_v == -1 && *r_u > -1) {
+ return 1;
+ }
+ return 0;
}
/* return true if U direction is selected and number of selected columns v */
static bool isNurbselU(Nurb *nu, int *v, int flag)
{
- BPoint *bp;
- int a, b, sel;
+ BPoint *bp;
+ int a, b, sel;
- *v = 0;
+ *v = 0;
- for (b = 0, bp = nu->bp; b < nu->pntsv; b++) {
- sel = 0;
- for (a = 0; a < nu->pntsu; a++, bp++) {
- if (bp->f1 & flag) {
- sel++;
- }
- }
- if (sel == nu->pntsu) {
- (*v)++;
- }
- else if (sel >= 1) {
- *v = 0;
- return 0;
- }
- }
+ for (b = 0, bp = nu->bp; b < nu->pntsv; b++) {
+ sel = 0;
+ for (a = 0; a < nu->pntsu; a++, bp++) {
+ if (bp->f1 & flag) {
+ sel++;
+ }
+ }
+ if (sel == nu->pntsu) {
+ (*v)++;
+ }
+ else if (sel >= 1) {
+ *v = 0;
+ return 0;
+ }
+ }
- return 1;
+ return 1;
}
/* return true if V direction is selected and number of selected rows u */
static bool isNurbselV(Nurb *nu, int *u, int flag)
{
- BPoint *bp;
- int a, b, sel;
+ BPoint *bp;
+ int a, b, sel;
- *u = 0;
+ *u = 0;
- for (a = 0; a < nu->pntsu; a++) {
- bp = &nu->bp[a];
- sel = 0;
- for (b = 0; b < nu->pntsv; b++, bp += nu->pntsu) {
- if (bp->f1 & flag) {
- sel++;
- }
- }
- if (sel == nu->pntsv) {
- (*u)++;
- }
- else if (sel >= 1) {
- *u = 0;
- return 0;
- }
- }
+ for (a = 0; a < nu->pntsu; a++) {
+ bp = &nu->bp[a];
+ sel = 0;
+ for (b = 0; b < nu->pntsv; b++, bp += nu->pntsu) {
+ if (bp->f1 & flag) {
+ sel++;
+ }
+ }
+ if (sel == nu->pntsv) {
+ (*u)++;
+ }
+ else if (sel >= 1) {
+ *u = 0;
+ return 0;
+ }
+ }
- return 1;
+ return 1;
}
static void rotateflagNurb(ListBase *editnurb, short flag, const float cent[3], float rotmat[3][3])
{
- /* all verts with (flag & 'flag') rotate */
- Nurb *nu;
- BPoint *bp;
- int a;
+ /* all verts with (flag & 'flag') rotate */
+ Nurb *nu;
+ BPoint *bp;
+ int a;
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->type == CU_NURBS) {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->type == CU_NURBS) {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
- while (a--) {
- if (bp->f1 & flag) {
- sub_v3_v3(bp->vec, cent);
- mul_m3_v3(rotmat, bp->vec);
- add_v3_v3(bp->vec, cent);
- }
- bp++;
- }
- }
- }
+ while (a--) {
+ if (bp->f1 & flag) {
+ sub_v3_v3(bp->vec, cent);
+ mul_m3_v3(rotmat, bp->vec);
+ add_v3_v3(bp->vec, cent);
+ }
+ bp++;
+ }
+ }
+ }
}
void ed_editnurb_translate_flag(ListBase *editnurb, short flag, const float vec[3])
{
- /* all verts with ('flag' & flag) translate */
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- a = nu->pntsu;
- bezt = nu->bezt;
- while (a--) {
- if (bezt->f1 & flag) { add_v3_v3(bezt->vec[0], vec); }
- if (bezt->f2 & flag) { add_v3_v3(bezt->vec[1], vec); }
- if (bezt->f3 & flag) { add_v3_v3(bezt->vec[2], vec); }
- bezt++;
- }
- }
- else {
- a = nu->pntsu * nu->pntsv;
- bp = nu->bp;
- while (a--) {
- if (bp->f1 & flag) {
- add_v3_v3(bp->vec, vec);
- }
- bp++;
- }
- }
-
- BKE_nurb_test_2d(nu);
- }
+ /* all verts with ('flag' & flag) translate */
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ a = nu->pntsu;
+ bezt = nu->bezt;
+ while (a--) {
+ if (bezt->f1 & flag) {
+ add_v3_v3(bezt->vec[0], vec);
+ }
+ if (bezt->f2 & flag) {
+ add_v3_v3(bezt->vec[1], vec);
+ }
+ if (bezt->f3 & flag) {
+ add_v3_v3(bezt->vec[2], vec);
+ }
+ bezt++;
+ }
+ }
+ else {
+ a = nu->pntsu * nu->pntsv;
+ bp = nu->bp;
+ while (a--) {
+ if (bp->f1 & flag) {
+ add_v3_v3(bp->vec, vec);
+ }
+ bp++;
+ }
+ }
+
+ BKE_nurb_test_2d(nu);
+ }
}
static void weightflagNurb(ListBase *editnurb, short flag, float w)
{
- Nurb *nu;
- BPoint *bp;
- int a;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->type == CU_NURBS) {
- a = nu->pntsu * nu->pntsv;
- bp = nu->bp;
- while (a--) {
- if (bp->f1 & flag) {
- /* a mode used to exist for replace/multiple but is was unused */
- bp->vec[3] *= w;
- }
- bp++;
- }
- }
- }
+ Nurb *nu;
+ BPoint *bp;
+ int a;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->type == CU_NURBS) {
+ a = nu->pntsu * nu->pntsv;
+ bp = nu->bp;
+ while (a--) {
+ if (bp->f1 & flag) {
+ /* a mode used to exist for replace/multiple but is was unused */
+ bp->vec[3] *= w;
+ }
+ bp++;
+ }
+ }
+ }
}
static void ed_surf_delete_selected(Object *obedit)
{
- Curve *cu = obedit->data;
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu, *next;
- BPoint *bp, *bpn, *newbp;
- int a, b, newu, newv;
-
- BLI_assert(obedit->type == OB_SURF);
-
- nu = editnurb->first;
- while (nu) {
- next = nu->next;
-
- /* is entire nurb selected */
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a) {
- a--;
- if (bp->f1 & SELECT) {
- /* pass */
- }
- else {
- break;
- }
- bp++;
- }
- if (a == 0) {
- BLI_remlink(editnurb, nu);
- keyIndex_delNurb(cu->editnurb, nu);
- BKE_nurb_free(nu); nu = NULL;
- }
- else {
- if (isNurbselU(nu, &newv, SELECT)) {
- /* U direction selected */
- newv = nu->pntsv - newv;
- if (newv != nu->pntsv) {
- /* delete */
- bp = nu->bp;
- bpn = newbp = (BPoint *)MEM_mallocN(newv * nu->pntsu * sizeof(BPoint), "deleteNurb");
- for (b = 0; b < nu->pntsv; b++) {
- if ((bp->f1 & SELECT) == 0) {
- memcpy(bpn, bp, nu->pntsu * sizeof(BPoint));
- keyIndex_updateBP(cu->editnurb, bp, bpn, nu->pntsu);
- bpn += nu->pntsu;
- }
- else {
- keyIndex_delBP(cu->editnurb, bp);
- }
- bp += nu->pntsu;
- }
- nu->pntsv = newv;
- MEM_freeN(nu->bp);
- nu->bp = newbp;
- BKE_nurb_order_clamp_v(nu);
-
- BKE_nurb_knot_calc_v(nu);
- }
- }
- else if (isNurbselV(nu, &newu, SELECT)) {
- /* V direction selected */
- newu = nu->pntsu - newu;
- if (newu != nu->pntsu) {
- /* delete */
- bp = nu->bp;
- bpn = newbp = (BPoint *)MEM_mallocN(newu * nu->pntsv * sizeof(BPoint), "deleteNurb");
- for (b = 0; b < nu->pntsv; b++) {
- for (a = 0; a < nu->pntsu; a++, bp++) {
- if ((bp->f1 & SELECT) == 0) {
- *bpn = *bp;
- keyIndex_updateBP(cu->editnurb, bp, bpn, 1);
- bpn++;
- }
- else {
- keyIndex_delBP(cu->editnurb, bp);
- }
- }
- }
- MEM_freeN(nu->bp);
- nu->bp = newbp;
- if (newu == 1 && nu->pntsv > 1) { /* make a U spline */
- nu->pntsu = nu->pntsv;
- nu->pntsv = 1;
- SWAP(short, nu->orderu, nu->orderv);
- BKE_nurb_order_clamp_u(nu);
- if (nu->knotsv) {
- MEM_freeN(nu->knotsv);
- }
- nu->knotsv = NULL;
- }
- else {
- nu->pntsu = newu;
- BKE_nurb_order_clamp_u(nu);
- }
- BKE_nurb_knot_calc_u(nu);
- }
- }
- }
- nu = next;
- }
+ Curve *cu = obedit->data;
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu, *next;
+ BPoint *bp, *bpn, *newbp;
+ int a, b, newu, newv;
+
+ BLI_assert(obedit->type == OB_SURF);
+
+ nu = editnurb->first;
+ while (nu) {
+ next = nu->next;
+
+ /* is entire nurb selected */
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a) {
+ a--;
+ if (bp->f1 & SELECT) {
+ /* pass */
+ }
+ else {
+ break;
+ }
+ bp++;
+ }
+ if (a == 0) {
+ BLI_remlink(editnurb, nu);
+ keyIndex_delNurb(cu->editnurb, nu);
+ BKE_nurb_free(nu);
+ nu = NULL;
+ }
+ else {
+ if (isNurbselU(nu, &newv, SELECT)) {
+ /* U direction selected */
+ newv = nu->pntsv - newv;
+ if (newv != nu->pntsv) {
+ /* delete */
+ bp = nu->bp;
+ bpn = newbp = (BPoint *)MEM_mallocN(newv * nu->pntsu * sizeof(BPoint), "deleteNurb");
+ for (b = 0; b < nu->pntsv; b++) {
+ if ((bp->f1 & SELECT) == 0) {
+ memcpy(bpn, bp, nu->pntsu * sizeof(BPoint));
+ keyIndex_updateBP(cu->editnurb, bp, bpn, nu->pntsu);
+ bpn += nu->pntsu;
+ }
+ else {
+ keyIndex_delBP(cu->editnurb, bp);
+ }
+ bp += nu->pntsu;
+ }
+ nu->pntsv = newv;
+ MEM_freeN(nu->bp);
+ nu->bp = newbp;
+ BKE_nurb_order_clamp_v(nu);
+
+ BKE_nurb_knot_calc_v(nu);
+ }
+ }
+ else if (isNurbselV(nu, &newu, SELECT)) {
+ /* V direction selected */
+ newu = nu->pntsu - newu;
+ if (newu != nu->pntsu) {
+ /* delete */
+ bp = nu->bp;
+ bpn = newbp = (BPoint *)MEM_mallocN(newu * nu->pntsv * sizeof(BPoint), "deleteNurb");
+ for (b = 0; b < nu->pntsv; b++) {
+ for (a = 0; a < nu->pntsu; a++, bp++) {
+ if ((bp->f1 & SELECT) == 0) {
+ *bpn = *bp;
+ keyIndex_updateBP(cu->editnurb, bp, bpn, 1);
+ bpn++;
+ }
+ else {
+ keyIndex_delBP(cu->editnurb, bp);
+ }
+ }
+ }
+ MEM_freeN(nu->bp);
+ nu->bp = newbp;
+ if (newu == 1 && nu->pntsv > 1) { /* make a U spline */
+ nu->pntsu = nu->pntsv;
+ nu->pntsv = 1;
+ SWAP(short, nu->orderu, nu->orderv);
+ BKE_nurb_order_clamp_u(nu);
+ if (nu->knotsv) {
+ MEM_freeN(nu->knotsv);
+ }
+ nu->knotsv = NULL;
+ }
+ else {
+ nu->pntsu = newu;
+ BKE_nurb_order_clamp_u(nu);
+ }
+ BKE_nurb_knot_calc_u(nu);
+ }
+ }
+ }
+ nu = next;
+ }
}
static void ed_curve_delete_selected(Object *obedit, View3D *v3d)
{
- Curve *cu = obedit->data;
- EditNurb *editnurb = cu->editnurb;
- ListBase *nubase = &editnurb->nurbs;
- Nurb *nu, *next;
- BezTriple *bezt, *bezt1;
- BPoint *bp, *bp1;
- int a, type, nuindex = 0;
-
- /* first loop, can we remove entire pieces? */
- nu = nubase->first;
- while (nu) {
- next = nu->next;
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- if (a) {
- while (a) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- /* pass */
- }
- else {
- break;
- }
- a--;
- bezt++;
- }
- if (a == 0) {
- if (cu->actnu == nuindex) {
- cu->actnu = CU_ACT_NONE;
- }
-
- BLI_remlink(nubase, nu);
- keyIndex_delNurb(editnurb, nu);
- BKE_nurb_free(nu); nu = NULL;
- }
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- if (a) {
- while (a) {
- if (bp->f1 & SELECT) {
- /* pass */
- }
- else {
- break;
- }
- a--;
- bp++;
- }
- if (a == 0) {
- if (cu->actnu == nuindex) {
- cu->actnu = CU_ACT_NONE;
- }
-
- BLI_remlink(nubase, nu);
- keyIndex_delNurb(editnurb, nu);
- BKE_nurb_free(nu); nu = NULL;
- }
- }
- }
-
- /* Never allow the order to exceed the number of points
- * - note, this is ok but changes unselected nurbs, disable for now */
+ Curve *cu = obedit->data;
+ EditNurb *editnurb = cu->editnurb;
+ ListBase *nubase = &editnurb->nurbs;
+ Nurb *nu, *next;
+ BezTriple *bezt, *bezt1;
+ BPoint *bp, *bp1;
+ int a, type, nuindex = 0;
+
+ /* first loop, can we remove entire pieces? */
+ nu = nubase->first;
+ while (nu) {
+ next = nu->next;
+ if (nu->type == CU_BEZIER) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ if (a) {
+ while (a) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ /* pass */
+ }
+ else {
+ break;
+ }
+ a--;
+ bezt++;
+ }
+ if (a == 0) {
+ if (cu->actnu == nuindex) {
+ cu->actnu = CU_ACT_NONE;
+ }
+
+ BLI_remlink(nubase, nu);
+ keyIndex_delNurb(editnurb, nu);
+ BKE_nurb_free(nu);
+ nu = NULL;
+ }
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ if (a) {
+ while (a) {
+ if (bp->f1 & SELECT) {
+ /* pass */
+ }
+ else {
+ break;
+ }
+ a--;
+ bp++;
+ }
+ if (a == 0) {
+ if (cu->actnu == nuindex) {
+ cu->actnu = CU_ACT_NONE;
+ }
+
+ BLI_remlink(nubase, nu);
+ keyIndex_delNurb(editnurb, nu);
+ BKE_nurb_free(nu);
+ nu = NULL;
+ }
+ }
+ }
+
+ /* Never allow the order to exceed the number of points
+ * - note, this is ok but changes unselected nurbs, disable for now */
#if 0
- if ((nu != NULL) && (nu->type == CU_NURBS)) {
- clamp_nurb_order_u(nu);
- }
+ if ((nu != NULL) && (nu->type == CU_NURBS)) {
+ clamp_nurb_order_u(nu);
+ }
#endif
- nu = next;
- nuindex++;
- }
- /* 2nd loop, delete small pieces: just for curves */
- nu = nubase->first;
- while (nu) {
- next = nu->next;
- type = 0;
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- for (a = 0; a < nu->pntsu; a++) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- memmove(bezt, bezt + 1, (nu->pntsu - a - 1) * sizeof(BezTriple));
- keyIndex_delBezt(editnurb, bezt);
- keyIndex_updateBezt(editnurb, bezt + 1, bezt, nu->pntsu - a - 1);
- nu->pntsu--;
- a--;
- type = 1;
- }
- else {
- bezt++;
- }
- }
- if (type) {
- bezt1 = (BezTriple *)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb");
- memcpy(bezt1, nu->bezt, (nu->pntsu) * sizeof(BezTriple));
- keyIndex_updateBezt(editnurb, nu->bezt, bezt1, nu->pntsu);
- MEM_freeN(nu->bezt);
- nu->bezt = bezt1;
- BKE_nurb_handles_calc(nu);
- }
- }
- else if (nu->pntsv == 1) {
- bp = nu->bp;
-
- for (a = 0; a < nu->pntsu; a++) {
- if (bp->f1 & SELECT) {
- memmove(bp, bp + 1, (nu->pntsu - a - 1) * sizeof(BPoint));
- keyIndex_delBP(editnurb, bp);
- keyIndex_updateBP(editnurb, bp + 1, bp, nu->pntsu - a - 1);
- nu->pntsu--;
- a--;
- type = 1;
- }
- else {
- bp++;
- }
- }
- if (type) {
- bp1 = (BPoint *)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2");
- memcpy(bp1, nu->bp, (nu->pntsu) * sizeof(BPoint));
- keyIndex_updateBP(editnurb, nu->bp, bp1, nu->pntsu);
- MEM_freeN(nu->bp);
- nu->bp = bp1;
-
- /* Never allow the order to exceed the number of points
- * - note, this is ok but changes unselected nurbs, disable for now */
+ nu = next;
+ nuindex++;
+ }
+ /* 2nd loop, delete small pieces: just for curves */
+ nu = nubase->first;
+ while (nu) {
+ next = nu->next;
+ type = 0;
+ if (nu->type == CU_BEZIER) {
+ bezt = nu->bezt;
+ for (a = 0; a < nu->pntsu; a++) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ memmove(bezt, bezt + 1, (nu->pntsu - a - 1) * sizeof(BezTriple));
+ keyIndex_delBezt(editnurb, bezt);
+ keyIndex_updateBezt(editnurb, bezt + 1, bezt, nu->pntsu - a - 1);
+ nu->pntsu--;
+ a--;
+ type = 1;
+ }
+ else {
+ bezt++;
+ }
+ }
+ if (type) {
+ bezt1 = (BezTriple *)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb");
+ memcpy(bezt1, nu->bezt, (nu->pntsu) * sizeof(BezTriple));
+ keyIndex_updateBezt(editnurb, nu->bezt, bezt1, nu->pntsu);
+ MEM_freeN(nu->bezt);
+ nu->bezt = bezt1;
+ BKE_nurb_handles_calc(nu);
+ }
+ }
+ else if (nu->pntsv == 1) {
+ bp = nu->bp;
+
+ for (a = 0; a < nu->pntsu; a++) {
+ if (bp->f1 & SELECT) {
+ memmove(bp, bp + 1, (nu->pntsu - a - 1) * sizeof(BPoint));
+ keyIndex_delBP(editnurb, bp);
+ keyIndex_updateBP(editnurb, bp + 1, bp, nu->pntsu - a - 1);
+ nu->pntsu--;
+ a--;
+ type = 1;
+ }
+ else {
+ bp++;
+ }
+ }
+ if (type) {
+ bp1 = (BPoint *)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2");
+ memcpy(bp1, nu->bp, (nu->pntsu) * sizeof(BPoint));
+ keyIndex_updateBP(editnurb, nu->bp, bp1, nu->pntsu);
+ MEM_freeN(nu->bp);
+ nu->bp = bp1;
+
+ /* Never allow the order to exceed the number of points
+ * - note, this is ok but changes unselected nurbs, disable for now */
#if 0
- if (nu->type == CU_NURBS) {
- clamp_nurb_order_u(nu);
- }
+ if (nu->type == CU_NURBS) {
+ clamp_nurb_order_u(nu);
+ }
#endif
- }
- BKE_nurb_order_clamp_u(nu);
- BKE_nurb_knot_calc_u(nu);
- }
- nu = next;
- }
+ }
+ BKE_nurb_order_clamp_u(nu);
+ BKE_nurb_knot_calc_u(nu);
+ }
+ nu = next;
+ }
}
/* only for OB_SURF */
bool ed_editnurb_extrude_flag(EditNurb *editnurb, const short flag)
{
- Nurb *nu;
- BPoint *bp, *bpn, *newbp;
- int a, u, v, len;
- bool ok = false;
-
- nu = editnurb->nurbs.first;
- while (nu) {
-
- if (nu->pntsv == 1) {
- bp = nu->bp;
- a = nu->pntsu;
- while (a) {
- if (bp->f1 & flag) {
- /* pass */
- }
- else {
- break;
- }
- bp++;
- a--;
- }
- if (a == 0) {
- ok = true;
- newbp = (BPoint *)MEM_mallocN(2 * nu->pntsu * sizeof(BPoint), "extrudeNurb1");
- ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu);
- bp = newbp + nu->pntsu;
- ED_curve_bpcpy(editnurb, bp, nu->bp, nu->pntsu);
- MEM_freeN(nu->bp);
- nu->bp = newbp;
- a = nu->pntsu;
- while (a--) {
- select_bpoint(bp, SELECT, flag, HIDDEN);
- select_bpoint(newbp, DESELECT, flag, HIDDEN);
- bp++;
- newbp++;
- }
-
- nu->pntsv = 2;
- nu->orderv = 2;
- BKE_nurb_knot_calc_v(nu);
- }
- }
- else {
- /* which row or column is selected */
-
- if (isNurbselUV(nu, flag, &u, &v)) {
-
- /* deselect all */
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- select_bpoint(bp, DESELECT, flag, HIDDEN);
- bp++;
- }
-
- if (u == 0 || u == nu->pntsv - 1) { /* row in u-direction selected */
- ok = true;
- newbp = (BPoint *)MEM_mallocN(nu->pntsu * (nu->pntsv + 1) *
- sizeof(BPoint), "extrudeNurb1");
- if (u == 0) {
- len = nu->pntsv * nu->pntsu;
- ED_curve_bpcpy(editnurb, newbp + nu->pntsu, nu->bp, len);
- ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu);
- bp = newbp;
- }
- else {
- len = nu->pntsv * nu->pntsu;
- ED_curve_bpcpy(editnurb, newbp, nu->bp, len);
- ED_curve_bpcpy(editnurb, newbp + len, &nu->bp[len - nu->pntsu], nu->pntsu);
- bp = newbp + len;
- }
-
- a = nu->pntsu;
- while (a--) {
- select_bpoint(bp, SELECT, flag, HIDDEN);
- bp++;
- }
-
- MEM_freeN(nu->bp);
- nu->bp = newbp;
- nu->pntsv++;
- BKE_nurb_knot_calc_v(nu);
- }
- else if (v == 0 || v == nu->pntsu - 1) { /* column in v-direction selected */
- ok = true;
- bpn = newbp = (BPoint *)MEM_mallocN((nu->pntsu + 1) * nu->pntsv * sizeof(BPoint), "extrudeNurb1");
- bp = nu->bp;
-
- for (a = 0; a < nu->pntsv; a++) {
- if (v == 0) {
- *bpn = *bp;
- bpn->f1 |= flag;
- bpn++;
- }
- ED_curve_bpcpy(editnurb, bpn, bp, nu->pntsu);
- bp += nu->pntsu;
- bpn += nu->pntsu;
- if (v == nu->pntsu - 1) {
- *bpn = *(bp - 1);
- bpn->f1 |= flag;
- bpn++;
- }
- }
-
- MEM_freeN(nu->bp);
- nu->bp = newbp;
- nu->pntsu++;
- BKE_nurb_knot_calc_u(nu);
- }
- }
- }
- nu = nu->next;
- }
-
- return ok;
+ Nurb *nu;
+ BPoint *bp, *bpn, *newbp;
+ int a, u, v, len;
+ bool ok = false;
+
+ nu = editnurb->nurbs.first;
+ while (nu) {
+
+ if (nu->pntsv == 1) {
+ bp = nu->bp;
+ a = nu->pntsu;
+ while (a) {
+ if (bp->f1 & flag) {
+ /* pass */
+ }
+ else {
+ break;
+ }
+ bp++;
+ a--;
+ }
+ if (a == 0) {
+ ok = true;
+ newbp = (BPoint *)MEM_mallocN(2 * nu->pntsu * sizeof(BPoint), "extrudeNurb1");
+ ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu);
+ bp = newbp + nu->pntsu;
+ ED_curve_bpcpy(editnurb, bp, nu->bp, nu->pntsu);
+ MEM_freeN(nu->bp);
+ nu->bp = newbp;
+ a = nu->pntsu;
+ while (a--) {
+ select_bpoint(bp, SELECT, flag, HIDDEN);
+ select_bpoint(newbp, DESELECT, flag, HIDDEN);
+ bp++;
+ newbp++;
+ }
+
+ nu->pntsv = 2;
+ nu->orderv = 2;
+ BKE_nurb_knot_calc_v(nu);
+ }
+ }
+ else {
+ /* which row or column is selected */
+
+ if (isNurbselUV(nu, flag, &u, &v)) {
+
+ /* deselect all */
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ select_bpoint(bp, DESELECT, flag, HIDDEN);
+ bp++;
+ }
+
+ if (u == 0 || u == nu->pntsv - 1) { /* row in u-direction selected */
+ ok = true;
+ newbp = (BPoint *)MEM_mallocN(nu->pntsu * (nu->pntsv + 1) * sizeof(BPoint),
+ "extrudeNurb1");
+ if (u == 0) {
+ len = nu->pntsv * nu->pntsu;
+ ED_curve_bpcpy(editnurb, newbp + nu->pntsu, nu->bp, len);
+ ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu);
+ bp = newbp;
+ }
+ else {
+ len = nu->pntsv * nu->pntsu;
+ ED_curve_bpcpy(editnurb, newbp, nu->bp, len);
+ ED_curve_bpcpy(editnurb, newbp + len, &nu->bp[len - nu->pntsu], nu->pntsu);
+ bp = newbp + len;
+ }
+
+ a = nu->pntsu;
+ while (a--) {
+ select_bpoint(bp, SELECT, flag, HIDDEN);
+ bp++;
+ }
+
+ MEM_freeN(nu->bp);
+ nu->bp = newbp;
+ nu->pntsv++;
+ BKE_nurb_knot_calc_v(nu);
+ }
+ else if (v == 0 || v == nu->pntsu - 1) { /* column in v-direction selected */
+ ok = true;
+ bpn = newbp = (BPoint *)MEM_mallocN((nu->pntsu + 1) * nu->pntsv * sizeof(BPoint),
+ "extrudeNurb1");
+ bp = nu->bp;
+
+ for (a = 0; a < nu->pntsv; a++) {
+ if (v == 0) {
+ *bpn = *bp;
+ bpn->f1 |= flag;
+ bpn++;
+ }
+ ED_curve_bpcpy(editnurb, bpn, bp, nu->pntsu);
+ bp += nu->pntsu;
+ bpn += nu->pntsu;
+ if (v == nu->pntsu - 1) {
+ *bpn = *(bp - 1);
+ bpn->f1 |= flag;
+ bpn++;
+ }
+ }
+
+ MEM_freeN(nu->bp);
+ nu->bp = newbp;
+ nu->pntsu++;
+ BKE_nurb_knot_calc_u(nu);
+ }
+ }
+ }
+ nu = nu->next;
+ }
+
+ return ok;
}
static bool calc_duplicate_actvert(
- const ListBase *editnurb, const ListBase *newnurb, Curve *cu,
- int start, int end, int vert)
-{
- if ((start <= cu->actvert) && (end > cu->actvert)) {
- cu->actvert = vert;
- cu->actnu = BLI_listbase_count(editnurb) + BLI_listbase_count(newnurb);
- return true;
- }
- return false;
-}
-
-static void adduplicateflagNurb(Object *obedit, View3D *v3d, ListBase *newnurb,
- const short flag, const bool split)
-{
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu, *newnu;
- BezTriple *bezt, *bezt1;
- BPoint *bp, *bp1, *bp2, *bp3;
- Curve *cu = (Curve *)obedit->data;
- int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv, i;
- char *usel;
-
- for (i = 0, nu = editnurb->first; nu; i++, nu = nu->next) {
- cyclicu = cyclicv = 0;
- if (nu->type == CU_BEZIER) {
- for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
- enda = -1;
- starta = a;
- while ((bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag)) {
- if (!split) {
- select_beztriple(bezt, DESELECT, flag, HIDDEN);
- }
- enda = a;
- if (a >= nu->pntsu - 1) {
- break;
- }
- a++;
- bezt++;
- }
- if (enda >= starta) {
- newu = diffa = enda - starta + 1; /* set newu and diffa, may use both */
-
- if (starta == 0 && newu != nu->pntsu && (nu->flagu & CU_NURB_CYCLIC)) {
- cyclicu = newu;
- }
- else {
- if (enda == nu->pntsu - 1) {
- newu += cyclicu;
- }
- if (i == cu->actnu) {
- calc_duplicate_actvert(
- editnurb, newnurb, cu,
- starta, starta + diffa, cu->actvert - starta);
- }
-
- newnu = BKE_nurb_copy(nu, newu, 1);
- memcpy(newnu->bezt, &nu->bezt[starta], diffa * sizeof(BezTriple));
- if (newu != diffa) {
- memcpy(&newnu->bezt[diffa], nu->bezt, cyclicu * sizeof(BezTriple));
- if (i == cu->actnu) {
- calc_duplicate_actvert(
- editnurb, newnurb, cu,
- 0, cyclicu, newu - cyclicu + cu->actvert);
- }
- cyclicu = 0;
- }
-
- if (newu != nu->pntsu) {
- newnu->flagu &= ~CU_NURB_CYCLIC;
- }
-
- for (b = 0, bezt1 = newnu->bezt; b < newnu->pntsu; b++, bezt1++) {
- select_beztriple(bezt1, SELECT, flag, HIDDEN);
- }
-
- BLI_addtail(newnurb, newnu);
- }
- }
- }
-
- if (cyclicu != 0) {
- if (i == cu->actnu) {
- calc_duplicate_actvert(
- editnurb, newnurb, cu,
- 0, cyclicu, cu->actvert);
- }
-
- newnu = BKE_nurb_copy(nu, cyclicu, 1);
- memcpy(newnu->bezt, nu->bezt, cyclicu * sizeof(BezTriple));
- newnu->flagu &= ~CU_NURB_CYCLIC;
-
- for (b = 0, bezt1 = newnu->bezt; b < newnu->pntsu; b++, bezt1++) {
- select_beztriple(bezt1, SELECT, flag, HIDDEN);
- }
-
- BLI_addtail(newnurb, newnu);
- }
- }
- else if (nu->pntsv == 1) { /* because UV Nurb has a different method for dupli */
- for (a = 0, bp = nu->bp; a < nu->pntsu; a++, bp++) {
- enda = -1;
- starta = a;
- while (bp->f1 & flag) {
- if (!split) {
- select_bpoint(bp, DESELECT, flag, HIDDEN);
- }
- enda = a;
- if (a >= nu->pntsu - 1) {
- break;
- }
- a++;
- bp++;
- }
- if (enda >= starta) {
- newu = diffa = enda - starta + 1; /* set newu and diffa, may use both */
-
- if (starta == 0 && newu != nu->pntsu && (nu->flagu & CU_NURB_CYCLIC)) {
- cyclicu = newu;
- }
- else {
- if (enda == nu->pntsu - 1) {
- newu += cyclicu;
- }
- if (i == cu->actnu) {
- calc_duplicate_actvert(
- editnurb, newnurb, cu,
- starta, starta + diffa, cu->actvert - starta);
- }
-
- newnu = BKE_nurb_copy(nu, newu, 1);
- memcpy(newnu->bp, &nu->bp[starta], diffa * sizeof(BPoint));
- if (newu != diffa) {
- memcpy(&newnu->bp[diffa], nu->bp, cyclicu * sizeof(BPoint));
- if (i == cu->actnu) {
- calc_duplicate_actvert(
- editnurb, newnurb, cu,
- 0, cyclicu, newu - cyclicu + cu->actvert);
- }
- cyclicu = 0;
- }
-
- if (newu != nu->pntsu) {
- newnu->flagu &= ~CU_NURB_CYCLIC;
- }
-
- for (b = 0, bp1 = newnu->bp; b < newnu->pntsu; b++, bp1++) {
- select_bpoint(bp1, SELECT, flag, HIDDEN);
- }
-
- BLI_addtail(newnurb, newnu);
- }
- }
- }
-
- if (cyclicu != 0) {
- if (i == cu->actnu) {
- calc_duplicate_actvert(
- editnurb, newnurb, cu,
- 0, cyclicu, cu->actvert);
- }
-
- newnu = BKE_nurb_copy(nu, cyclicu, 1);
- memcpy(newnu->bp, nu->bp, cyclicu * sizeof(BPoint));
- newnu->flagu &= ~CU_NURB_CYCLIC;
-
- for (b = 0, bp1 = newnu->bp; b < newnu->pntsu; b++, bp1++) {
- select_bpoint(bp1, SELECT, flag, HIDDEN);
- }
-
- BLI_addtail(newnurb, newnu);
- }
- }
- else {
- if (ED_curve_nurb_select_check(v3d, nu)) {
- /* a rectangular area in nurb has to be selected and if splitting must be in U or V direction */
- usel = MEM_callocN(nu->pntsu, "adduplicateN3");
- bp = nu->bp;
- for (a = 0; a < nu->pntsv; a++) {
- for (b = 0; b < nu->pntsu; b++, bp++) {
- if (bp->f1 & flag) {
- usel[b]++;
- }
- }
- }
- newu = 0;
- newv = 0;
- for (a = 0; a < nu->pntsu; a++) {
- if (usel[a]) {
- if (newv == 0 || usel[a] == newv) {
- newv = usel[a];
- newu++;
- }
- else {
- newv = 0;
- break;
- }
- }
- }
- MEM_freeN(usel);
-
- if ((newu == 0 || newv == 0) ||
- (split && !isNurbselU(nu, &newv, SELECT) && !isNurbselV(nu, &newu, SELECT)))
- {
- if (G.debug & G_DEBUG) {
- printf("Can't duplicate Nurb\n");
- }
- }
- else {
- for (a = 0, bp1 = nu->bp; a < nu->pntsu * nu->pntsv; a++, bp1++) {
- newv = newu = 0;
-
- if ((bp1->f1 & flag) && !(bp1->f1 & SURF_SEEN)) {
- /* point selected, now loop over points in U and V directions */
- for (b = a % nu->pntsu, bp2 = bp1; b < nu->pntsu; b++, bp2++) {
- if (bp2->f1 & flag) {
- newu++;
- for (c = a / nu->pntsu, bp3 = bp2; c < nu->pntsv; c++, bp3 += nu->pntsu) {
- if (bp3->f1 & flag) {
- /* flag as seen so skipped on future iterations */
- bp3->f1 |= SURF_SEEN;
- if (newu == 1) {
- newv++;
- }
- }
- else {
- break;
- }
- }
- }
- else {
- break;
- }
- }
- }
-
- if ((newu + newv) > 2) {
- /* ignore single points */
- if (a == 0) {
- /* check if need to save cyclic selection and continue if so */
- if (newu == nu->pntsu && (nu->flagv & CU_NURB_CYCLIC)) {
- cyclicv = newv;
- }
- if (newv == nu->pntsv && (nu->flagu & CU_NURB_CYCLIC)) {
- cyclicu = newu;
- }
- if (cyclicu != 0 || cyclicv != 0) {
- continue;
- }
- }
-
- if (a + newu == nu->pntsu && cyclicu != 0) {
- /* cyclic in U direction */
- newnu = BKE_nurb_copy(nu, newu + cyclicu, newv);
- for (b = 0; b < newv; b++) {
- memcpy(&newnu->bp[b * newnu->pntsu], &nu->bp[b * nu->pntsu + a], newu * sizeof(BPoint));
- memcpy(&newnu->bp[b * newnu->pntsu + newu], &nu->bp[b * nu->pntsu], cyclicu * sizeof(BPoint));
- }
-
- if (cu->actnu == i) {
- for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) {
- starta = b * nu->pntsu + a;
- if (calc_duplicate_actvert(
- editnurb, newnurb, cu,
- cu->actvert, starta,
- cu->actvert % nu->pntsu + newu + b * newnu->pntsu))
- {
- /* actvert in cyclicu selection */
- break;
- }
- else if (calc_duplicate_actvert(
- editnurb, newnurb, cu,
- starta, starta + newu,
- cu->actvert - starta + b * newnu->pntsu))
- {
- /* actvert in 'current' iteration selection */
- break;
- }
- }
- }
- cyclicu = cyclicv = 0;
- }
- else if ((a / nu->pntsu) + newv == nu->pntsv && cyclicv != 0) {
- /* cyclic in V direction */
- newnu = BKE_nurb_copy(nu, newu, newv + cyclicv);
- memcpy(newnu->bp, &nu->bp[a], newu * newv * sizeof(BPoint));
- memcpy(&newnu->bp[newu * newv], nu->bp, newu * cyclicv * sizeof(BPoint));
-
- /* check for actvert in cylicv selection */
- if (cu->actnu == i) {
- calc_duplicate_actvert(
- editnurb, newnurb, cu,
- cu->actvert, a,
- (newu * newv) + cu->actvert);
- }
- cyclicu = cyclicv = 0;
- }
- else {
- newnu = BKE_nurb_copy(nu, newu, newv);
- for (b = 0; b < newv; b++) {
- memcpy(&newnu->bp[b * newu], &nu->bp[b * nu->pntsu + a], newu * sizeof(BPoint));
- }
- }
-
- /* general case if not handled by cyclicu or cyclicv */
- if (cu->actnu == i) {
- for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) {
- starta = b * nu->pntsu + a;
- if (calc_duplicate_actvert(
- editnurb, newnurb, cu,
- starta, starta + newu,
- cu->actvert - (a / nu->pntsu * nu->pntsu + diffa + (starta % nu->pntsu))))
- {
- break;
- }
- }
- }
- BLI_addtail(newnurb, newnu);
-
- if (newu != nu->pntsu) {
- newnu->flagu &= ~CU_NURB_CYCLIC;
- }
- if (newv != nu->pntsv) {
- newnu->flagv &= ~CU_NURB_CYCLIC;
- }
- }
- }
-
- if (cyclicu != 0 || cyclicv != 0) {
- /* copy start of a cyclic surface, or copying all selected points */
- newu = cyclicu == 0 ? nu->pntsu : cyclicu;
- newv = cyclicv == 0 ? nu->pntsv : cyclicv;
-
- newnu = BKE_nurb_copy(nu, newu, newv);
- for (b = 0; b < newv; b++) {
- memcpy(&newnu->bp[b * newu], &nu->bp[b * nu->pntsu], newu * sizeof(BPoint));
- }
-
- /* check for actvert in the unused cyclicuv selection */
- if (cu->actnu == i) {
- for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) {
- starta = b * nu->pntsu;
- if (calc_duplicate_actvert(
- editnurb, newnurb, cu,
- starta, starta + newu,
- cu->actvert - (diffa + (starta % nu->pntsu))))
- {
- break;
- }
- }
- }
- BLI_addtail(newnurb, newnu);
-
- if (newu != nu->pntsu) {
- newnu->flagu &= ~CU_NURB_CYCLIC;
- }
- if (newv != nu->pntsv) {
- newnu->flagv &= ~CU_NURB_CYCLIC;
- }
- }
-
- for (b = 0, bp1 = nu->bp; b < nu->pntsu * nu->pntsv; b++, bp1++) {
- bp1->f1 &= ~SURF_SEEN;
- if (!split) {
- select_bpoint(bp1, DESELECT, flag, HIDDEN);
- }
- }
- }
- }
- }
- }
-
- if (BLI_listbase_is_empty(newnurb) == false) {
- for (nu = newnurb->first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- if (split) {
- /* recalc first and last */
- BKE_nurb_handle_calc_simple(nu, &nu->bezt[0]);
- BKE_nurb_handle_calc_simple(nu, &nu->bezt[nu->pntsu - 1]);
- }
- }
- else {
- /* knots done after duplicate as pntsu may change */
- BKE_nurb_order_clamp_u(nu);
- BKE_nurb_knot_calc_u(nu);
-
- if (obedit->type == OB_SURF) {
- for (a = 0, bp = nu->bp; a < nu->pntsu * nu->pntsv; a++, bp++) {
- bp->f1 &= ~SURF_SEEN;
- }
-
- BKE_nurb_order_clamp_v(nu);
- BKE_nurb_knot_calc_v(nu);
- }
- }
- }
- }
+ const ListBase *editnurb, const ListBase *newnurb, Curve *cu, int start, int end, int vert)
+{
+ if ((start <= cu->actvert) && (end > cu->actvert)) {
+ cu->actvert = vert;
+ cu->actnu = BLI_listbase_count(editnurb) + BLI_listbase_count(newnurb);
+ return true;
+ }
+ return false;
+}
+
+static void adduplicateflagNurb(
+ Object *obedit, View3D *v3d, ListBase *newnurb, const short flag, const bool split)
+{
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu, *newnu;
+ BezTriple *bezt, *bezt1;
+ BPoint *bp, *bp1, *bp2, *bp3;
+ Curve *cu = (Curve *)obedit->data;
+ int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv, i;
+ char *usel;
+
+ for (i = 0, nu = editnurb->first; nu; i++, nu = nu->next) {
+ cyclicu = cyclicv = 0;
+ if (nu->type == CU_BEZIER) {
+ for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
+ enda = -1;
+ starta = a;
+ while ((bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag)) {
+ if (!split) {
+ select_beztriple(bezt, DESELECT, flag, HIDDEN);
+ }
+ enda = a;
+ if (a >= nu->pntsu - 1) {
+ break;
+ }
+ a++;
+ bezt++;
+ }
+ if (enda >= starta) {
+ newu = diffa = enda - starta + 1; /* set newu and diffa, may use both */
+
+ if (starta == 0 && newu != nu->pntsu && (nu->flagu & CU_NURB_CYCLIC)) {
+ cyclicu = newu;
+ }
+ else {
+ if (enda == nu->pntsu - 1) {
+ newu += cyclicu;
+ }
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu, starta, starta + diffa, cu->actvert - starta);
+ }
+
+ newnu = BKE_nurb_copy(nu, newu, 1);
+ memcpy(newnu->bezt, &nu->bezt[starta], diffa * sizeof(BezTriple));
+ if (newu != diffa) {
+ memcpy(&newnu->bezt[diffa], nu->bezt, cyclicu * sizeof(BezTriple));
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu, 0, cyclicu, newu - cyclicu + cu->actvert);
+ }
+ cyclicu = 0;
+ }
+
+ if (newu != nu->pntsu) {
+ newnu->flagu &= ~CU_NURB_CYCLIC;
+ }
+
+ for (b = 0, bezt1 = newnu->bezt; b < newnu->pntsu; b++, bezt1++) {
+ select_beztriple(bezt1, SELECT, flag, HIDDEN);
+ }
+
+ BLI_addtail(newnurb, newnu);
+ }
+ }
+ }
+
+ if (cyclicu != 0) {
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(editnurb, newnurb, cu, 0, cyclicu, cu->actvert);
+ }
+
+ newnu = BKE_nurb_copy(nu, cyclicu, 1);
+ memcpy(newnu->bezt, nu->bezt, cyclicu * sizeof(BezTriple));
+ newnu->flagu &= ~CU_NURB_CYCLIC;
+
+ for (b = 0, bezt1 = newnu->bezt; b < newnu->pntsu; b++, bezt1++) {
+ select_beztriple(bezt1, SELECT, flag, HIDDEN);
+ }
+
+ BLI_addtail(newnurb, newnu);
+ }
+ }
+ else if (nu->pntsv == 1) { /* because UV Nurb has a different method for dupli */
+ for (a = 0, bp = nu->bp; a < nu->pntsu; a++, bp++) {
+ enda = -1;
+ starta = a;
+ while (bp->f1 & flag) {
+ if (!split) {
+ select_bpoint(bp, DESELECT, flag, HIDDEN);
+ }
+ enda = a;
+ if (a >= nu->pntsu - 1) {
+ break;
+ }
+ a++;
+ bp++;
+ }
+ if (enda >= starta) {
+ newu = diffa = enda - starta + 1; /* set newu and diffa, may use both */
+
+ if (starta == 0 && newu != nu->pntsu && (nu->flagu & CU_NURB_CYCLIC)) {
+ cyclicu = newu;
+ }
+ else {
+ if (enda == nu->pntsu - 1) {
+ newu += cyclicu;
+ }
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu, starta, starta + diffa, cu->actvert - starta);
+ }
+
+ newnu = BKE_nurb_copy(nu, newu, 1);
+ memcpy(newnu->bp, &nu->bp[starta], diffa * sizeof(BPoint));
+ if (newu != diffa) {
+ memcpy(&newnu->bp[diffa], nu->bp, cyclicu * sizeof(BPoint));
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu, 0, cyclicu, newu - cyclicu + cu->actvert);
+ }
+ cyclicu = 0;
+ }
+
+ if (newu != nu->pntsu) {
+ newnu->flagu &= ~CU_NURB_CYCLIC;
+ }
+
+ for (b = 0, bp1 = newnu->bp; b < newnu->pntsu; b++, bp1++) {
+ select_bpoint(bp1, SELECT, flag, HIDDEN);
+ }
+
+ BLI_addtail(newnurb, newnu);
+ }
+ }
+ }
+
+ if (cyclicu != 0) {
+ if (i == cu->actnu) {
+ calc_duplicate_actvert(editnurb, newnurb, cu, 0, cyclicu, cu->actvert);
+ }
+
+ newnu = BKE_nurb_copy(nu, cyclicu, 1);
+ memcpy(newnu->bp, nu->bp, cyclicu * sizeof(BPoint));
+ newnu->flagu &= ~CU_NURB_CYCLIC;
+
+ for (b = 0, bp1 = newnu->bp; b < newnu->pntsu; b++, bp1++) {
+ select_bpoint(bp1, SELECT, flag, HIDDEN);
+ }
+
+ BLI_addtail(newnurb, newnu);
+ }
+ }
+ else {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+ /* a rectangular area in nurb has to be selected and if splitting must be in U or V direction */
+ usel = MEM_callocN(nu->pntsu, "adduplicateN3");
+ bp = nu->bp;
+ for (a = 0; a < nu->pntsv; a++) {
+ for (b = 0; b < nu->pntsu; b++, bp++) {
+ if (bp->f1 & flag) {
+ usel[b]++;
+ }
+ }
+ }
+ newu = 0;
+ newv = 0;
+ for (a = 0; a < nu->pntsu; a++) {
+ if (usel[a]) {
+ if (newv == 0 || usel[a] == newv) {
+ newv = usel[a];
+ newu++;
+ }
+ else {
+ newv = 0;
+ break;
+ }
+ }
+ }
+ MEM_freeN(usel);
+
+ if ((newu == 0 || newv == 0) ||
+ (split && !isNurbselU(nu, &newv, SELECT) && !isNurbselV(nu, &newu, SELECT))) {
+ if (G.debug & G_DEBUG) {
+ printf("Can't duplicate Nurb\n");
+ }
+ }
+ else {
+ for (a = 0, bp1 = nu->bp; a < nu->pntsu * nu->pntsv; a++, bp1++) {
+ newv = newu = 0;
+
+ if ((bp1->f1 & flag) && !(bp1->f1 & SURF_SEEN)) {
+ /* point selected, now loop over points in U and V directions */
+ for (b = a % nu->pntsu, bp2 = bp1; b < nu->pntsu; b++, bp2++) {
+ if (bp2->f1 & flag) {
+ newu++;
+ for (c = a / nu->pntsu, bp3 = bp2; c < nu->pntsv; c++, bp3 += nu->pntsu) {
+ if (bp3->f1 & flag) {
+ /* flag as seen so skipped on future iterations */
+ bp3->f1 |= SURF_SEEN;
+ if (newu == 1) {
+ newv++;
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ if ((newu + newv) > 2) {
+ /* ignore single points */
+ if (a == 0) {
+ /* check if need to save cyclic selection and continue if so */
+ if (newu == nu->pntsu && (nu->flagv & CU_NURB_CYCLIC)) {
+ cyclicv = newv;
+ }
+ if (newv == nu->pntsv && (nu->flagu & CU_NURB_CYCLIC)) {
+ cyclicu = newu;
+ }
+ if (cyclicu != 0 || cyclicv != 0) {
+ continue;
+ }
+ }
+
+ if (a + newu == nu->pntsu && cyclicu != 0) {
+ /* cyclic in U direction */
+ newnu = BKE_nurb_copy(nu, newu + cyclicu, newv);
+ for (b = 0; b < newv; b++) {
+ memcpy(&newnu->bp[b * newnu->pntsu],
+ &nu->bp[b * nu->pntsu + a],
+ newu * sizeof(BPoint));
+ memcpy(&newnu->bp[b * newnu->pntsu + newu],
+ &nu->bp[b * nu->pntsu],
+ cyclicu * sizeof(BPoint));
+ }
+
+ if (cu->actnu == i) {
+ for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) {
+ starta = b * nu->pntsu + a;
+ if (calc_duplicate_actvert(editnurb,
+ newnurb,
+ cu,
+ cu->actvert,
+ starta,
+ cu->actvert % nu->pntsu + newu +
+ b * newnu->pntsu)) {
+ /* actvert in cyclicu selection */
+ break;
+ }
+ else if (calc_duplicate_actvert(editnurb,
+ newnurb,
+ cu,
+ starta,
+ starta + newu,
+ cu->actvert - starta + b * newnu->pntsu)) {
+ /* actvert in 'current' iteration selection */
+ break;
+ }
+ }
+ }
+ cyclicu = cyclicv = 0;
+ }
+ else if ((a / nu->pntsu) + newv == nu->pntsv && cyclicv != 0) {
+ /* cyclic in V direction */
+ newnu = BKE_nurb_copy(nu, newu, newv + cyclicv);
+ memcpy(newnu->bp, &nu->bp[a], newu * newv * sizeof(BPoint));
+ memcpy(&newnu->bp[newu * newv], nu->bp, newu * cyclicv * sizeof(BPoint));
+
+ /* check for actvert in cylicv selection */
+ if (cu->actnu == i) {
+ calc_duplicate_actvert(
+ editnurb, newnurb, cu, cu->actvert, a, (newu * newv) + cu->actvert);
+ }
+ cyclicu = cyclicv = 0;
+ }
+ else {
+ newnu = BKE_nurb_copy(nu, newu, newv);
+ for (b = 0; b < newv; b++) {
+ memcpy(&newnu->bp[b * newu], &nu->bp[b * nu->pntsu + a], newu * sizeof(BPoint));
+ }
+ }
+
+ /* general case if not handled by cyclicu or cyclicv */
+ if (cu->actnu == i) {
+ for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) {
+ starta = b * nu->pntsu + a;
+ if (calc_duplicate_actvert(editnurb,
+ newnurb,
+ cu,
+ starta,
+ starta + newu,
+ cu->actvert - (a / nu->pntsu * nu->pntsu + diffa +
+ (starta % nu->pntsu)))) {
+ break;
+ }
+ }
+ }
+ BLI_addtail(newnurb, newnu);
+
+ if (newu != nu->pntsu) {
+ newnu->flagu &= ~CU_NURB_CYCLIC;
+ }
+ if (newv != nu->pntsv) {
+ newnu->flagv &= ~CU_NURB_CYCLIC;
+ }
+ }
+ }
+
+ if (cyclicu != 0 || cyclicv != 0) {
+ /* copy start of a cyclic surface, or copying all selected points */
+ newu = cyclicu == 0 ? nu->pntsu : cyclicu;
+ newv = cyclicv == 0 ? nu->pntsv : cyclicv;
+
+ newnu = BKE_nurb_copy(nu, newu, newv);
+ for (b = 0; b < newv; b++) {
+ memcpy(&newnu->bp[b * newu], &nu->bp[b * nu->pntsu], newu * sizeof(BPoint));
+ }
+
+ /* check for actvert in the unused cyclicuv selection */
+ if (cu->actnu == i) {
+ for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) {
+ starta = b * nu->pntsu;
+ if (calc_duplicate_actvert(editnurb,
+ newnurb,
+ cu,
+ starta,
+ starta + newu,
+ cu->actvert - (diffa + (starta % nu->pntsu)))) {
+ break;
+ }
+ }
+ }
+ BLI_addtail(newnurb, newnu);
+
+ if (newu != nu->pntsu) {
+ newnu->flagu &= ~CU_NURB_CYCLIC;
+ }
+ if (newv != nu->pntsv) {
+ newnu->flagv &= ~CU_NURB_CYCLIC;
+ }
+ }
+
+ for (b = 0, bp1 = nu->bp; b < nu->pntsu * nu->pntsv; b++, bp1++) {
+ bp1->f1 &= ~SURF_SEEN;
+ if (!split) {
+ select_bpoint(bp1, DESELECT, flag, HIDDEN);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (BLI_listbase_is_empty(newnurb) == false) {
+ for (nu = newnurb->first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ if (split) {
+ /* recalc first and last */
+ BKE_nurb_handle_calc_simple(nu, &nu->bezt[0]);
+ BKE_nurb_handle_calc_simple(nu, &nu->bezt[nu->pntsu - 1]);
+ }
+ }
+ else {
+ /* knots done after duplicate as pntsu may change */
+ BKE_nurb_order_clamp_u(nu);
+ BKE_nurb_knot_calc_u(nu);
+
+ if (obedit->type == OB_SURF) {
+ for (a = 0, bp = nu->bp; a < nu->pntsu * nu->pntsv; a++, bp++) {
+ bp->f1 &= ~SURF_SEEN;
+ }
+
+ BKE_nurb_order_clamp_v(nu);
+ BKE_nurb_knot_calc_v(nu);
+ }
+ }
+ }
+ }
}
/**************** switch direction operator ***************/
static int switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
-
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
-
- EditNurb *editnurb = cu->editnurb;
- Nurb *nu;
- int i;
-
- for (nu = editnurb->nurbs.first, i = 0; nu; nu = nu->next, i++) {
- if (ED_curve_nurb_select_check(v3d, nu)) {
- BKE_nurb_direction_switch(nu);
- keyData_switchDirectionNurb(cu, nu);
- if ((i == cu->actnu) && (cu->actvert != CU_ACT_NONE)) {
- cu->actvert = (nu->pntsu - 1) - cu->actvert;
- }
- }
- }
-
- if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
-
- DEG_id_tag_update(obedit->data, 0);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
+
+ EditNurb *editnurb = cu->editnurb;
+ Nurb *nu;
+ int i;
+
+ for (nu = editnurb->nurbs.first, i = 0; nu; nu = nu->next, i++) {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+ BKE_nurb_direction_switch(nu);
+ keyData_switchDirectionNurb(cu, nu);
+ if ((i == cu->actnu) && (cu->actvert != CU_ACT_NONE)) {
+ cu->actvert = (nu->pntsu - 1) - cu->actvert;
+ }
+ }
+ }
+
+ if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
+
+ DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_switch_direction(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Switch Direction";
- ot->description = "Switch direction of selected splines";
- ot->idname = "CURVE_OT_switch_direction";
+ /* identifiers */
+ ot->name = "Switch Direction";
+ ot->description = "Switch direction of selected splines";
+ ot->idname = "CURVE_OT_switch_direction";
- /* api callbacks */
- ot->exec = switch_direction_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = switch_direction_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/****************** set weight operator *******************/
static int set_goal_weight_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- float weight = RNA_float_get(op->ptr, "weight");
- int a;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->bezt) {
- for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
- if (bezt->f2 & SELECT) {
- bezt->weight = weight;
- }
- }
- }
- else if (nu->bp) {
- for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
- if (bp->f1 & SELECT) {
- bp->weight = weight;
- }
- }
- }
- }
-
- DEG_id_tag_update(obedit->data, 0);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
-
- return OPERATOR_FINISHED;
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ float weight = RNA_float_get(op->ptr, "weight");
+ int a;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
+ if (bezt->f2 & SELECT) {
+ bezt->weight = weight;
+ }
+ }
+ }
+ else if (nu->bp) {
+ for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
+ if (bp->f1 & SELECT) {
+ bp->weight = weight;
+ }
+ }
+ }
+ }
+
+ DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+
+ return OPERATOR_FINISHED;
}
void CURVE_OT_spline_weight_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Goal Weight";
- ot->description = "Set softbody goal weight for selected points";
- ot->idname = "CURVE_OT_spline_weight_set";
+ /* identifiers */
+ ot->name = "Set Goal Weight";
+ ot->description = "Set softbody goal weight for selected points";
+ ot->idname = "CURVE_OT_spline_weight_set";
- /* api callbacks */
- ot->exec = set_goal_weight_exec;
- ot->invoke = WM_operator_props_popup;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = set_goal_weight_exec;
+ ot->invoke = WM_operator_props_popup;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_float_factor(ot->srna, "weight", 1.0f, 0.0f, 1.0f, "Weight", "", 0.0f, 1.0f);
+ /* properties */
+ RNA_def_float_factor(ot->srna, "weight", 1.0f, 0.0f, 1.0f, "Weight", "", 0.0f, 1.0f);
}
/******************* set radius operator ******************/
static int set_radius_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- float radius = RNA_float_get(op->ptr, "radius");
- int a;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->bezt) {
- for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
- if (bezt->f2 & SELECT) {
- bezt->radius = radius;
- }
- }
- }
- else if (nu->bp) {
- for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
- if (bp->f1 & SELECT) {
- bp->radius = radius;
- }
- }
- }
- }
-
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
-
- return OPERATOR_FINISHED;
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ float radius = RNA_float_get(op->ptr, "radius");
+ int a;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
+ if (bezt->f2 & SELECT) {
+ bezt->radius = radius;
+ }
+ }
+ }
+ else if (nu->bp) {
+ for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
+ if (bp->f1 & SELECT) {
+ bp->radius = radius;
+ }
+ }
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+
+ return OPERATOR_FINISHED;
}
void CURVE_OT_radius_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Curve Radius";
- ot->description = "Set per-point radius which is used for bevel tapering";
- ot->idname = "CURVE_OT_radius_set";
+ /* identifiers */
+ ot->name = "Set Curve Radius";
+ ot->description = "Set per-point radius which is used for bevel tapering";
+ ot->idname = "CURVE_OT_radius_set";
- /* api callbacks */
- ot->exec = set_radius_exec;
- ot->invoke = WM_operator_props_popup;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = set_radius_exec;
+ ot->invoke = WM_operator_props_popup;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_float(ot->srna, "radius", 1.0f, 0.0f, OBJECT_ADD_SIZE_MAXF, "Radius", "", 0.0001f, 10.0f);
+ /* properties */
+ RNA_def_float(
+ ot->srna, "radius", 1.0f, 0.0f, OBJECT_ADD_SIZE_MAXF, "Radius", "", 0.0001f, 10.0f);
}
/********************* smooth operator ********************/
-static void smooth_single_bezt(
- BezTriple *bezt,
- const BezTriple *bezt_orig_prev, const BezTriple *bezt_orig_next,
- float factor)
+static void smooth_single_bezt(BezTriple *bezt,
+ const BezTriple *bezt_orig_prev,
+ const BezTriple *bezt_orig_next,
+ float factor)
{
- int i;
+ int i;
- BLI_assert(IN_RANGE_INCL(factor, 0.0f, 1.0f));
+ BLI_assert(IN_RANGE_INCL(factor, 0.0f, 1.0f));
- for (i = 0; i < 3; i++) {
- float val_old, val_new, offset;
+ for (i = 0; i < 3; i++) {
+ float val_old, val_new, offset;
- /* get single dimension pos of the mid handle */
- val_old = bezt->vec[1][i];
+ /* get single dimension pos of the mid handle */
+ val_old = bezt->vec[1][i];
- /* get the weights of the previous/next mid handles and calc offset */
- val_new = (bezt_orig_prev->vec[1][i] * 0.5f) + (bezt_orig_next->vec[1][i] * 0.5f);
- offset = (val_old * (1.0f - factor)) + (val_new * factor) - val_old;
+ /* get the weights of the previous/next mid handles and calc offset */
+ val_new = (bezt_orig_prev->vec[1][i] * 0.5f) + (bezt_orig_next->vec[1][i] * 0.5f);
+ offset = (val_old * (1.0f - factor)) + (val_new * factor) - val_old;
- /* offset midpoint and 2 handles */
- bezt->vec[1][i] += offset;
- bezt->vec[0][i] += offset;
- bezt->vec[2][i] += offset;
- }
+ /* offset midpoint and 2 handles */
+ bezt->vec[1][i] += offset;
+ bezt->vec[0][i] += offset;
+ bezt->vec[2][i] += offset;
+ }
}
/**
* Same as #smooth_single_bezt(), keep in sync.
*/
-static void smooth_single_bp(
- BPoint *bp,
- const BPoint *bp_orig_prev, const BPoint *bp_orig_next,
- float factor)
+static void smooth_single_bp(BPoint *bp,
+ const BPoint *bp_orig_prev,
+ const BPoint *bp_orig_next,
+ float factor)
{
- int i;
+ int i;
- BLI_assert(IN_RANGE_INCL(factor, 0.0f, 1.0f));
+ BLI_assert(IN_RANGE_INCL(factor, 0.0f, 1.0f));
- for (i = 0; i < 3; i++) {
- float val_old, val_new, offset;
+ for (i = 0; i < 3; i++) {
+ float val_old, val_new, offset;
- val_old = bp->vec[i];
- val_new = (bp_orig_prev->vec[i] * 0.5f) + (bp_orig_next->vec[i] * 0.5f);
- offset = (val_old * (1.0f - factor)) + (val_new * factor) - val_old;
+ val_old = bp->vec[i];
+ val_new = (bp_orig_prev->vec[i] * 0.5f) + (bp_orig_next->vec[i] * 0.5f);
+ offset = (val_old * (1.0f - factor)) + (val_new * factor) - val_old;
- bp->vec[i] += offset;
- }
+ bp->vec[i] += offset;
+ }
}
static int smooth_exec(bContext *C, wmOperator *UNUSED(op))
{
- const float factor = 1.0f / 6.0f;
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
-
- int a, a_end;
- bool changed = false;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->bezt) {
- /* duplicate the curve to use in weight calculation */
- const BezTriple *bezt_orig = MEM_dupallocN(nu->bezt);
- BezTriple *bezt;
- changed = false;
-
- /* check whether its cyclic or not, and set initial & final conditions */
- if (nu->flagu & CU_NURB_CYCLIC) {
- a = 0;
- a_end = nu->pntsu;
- }
- else {
- a = 1;
- a_end = nu->pntsu - 1;
- }
-
- /* for all the curve points */
- for (; a < a_end; a++) {
- /* respect selection */
- bezt = &nu->bezt[a];
- if (bezt->f2 & SELECT) {
- const BezTriple *bezt_orig_prev, *bezt_orig_next;
-
- bezt_orig_prev = &bezt_orig[mod_i(a - 1, nu->pntsu)];
- bezt_orig_next = &bezt_orig[mod_i(a + 1, nu->pntsu)];
-
- smooth_single_bezt(bezt, bezt_orig_prev, bezt_orig_next, factor);
-
- changed = true;
- }
- }
- MEM_freeN((void *)bezt_orig);
- if (changed) {
- BKE_nurb_handles_calc(nu);
- }
- }
- else if (nu->bp) {
- /* Same as above, keep these the same! */
- const BPoint *bp_orig = MEM_dupallocN(nu->bp);
- BPoint *bp;
-
- if (nu->flagu & CU_NURB_CYCLIC) {
- a = 0;
- a_end = nu->pntsu;
- }
- else {
- a = 1;
- a_end = nu->pntsu - 1;
- }
-
- for (; a < a_end; a++) {
- bp = &nu->bp[a];
- if (bp->f1 & SELECT) {
- const BPoint *bp_orig_prev, *bp_orig_next;
-
- bp_orig_prev = &bp_orig[mod_i(a - 1, nu->pntsu)];
- bp_orig_next = &bp_orig[mod_i(a + 1, nu->pntsu)];
-
- smooth_single_bp(bp, bp_orig_prev, bp_orig_next, factor);
- }
- }
- MEM_freeN((void *)bp_orig);
- }
- }
-
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
-
- return OPERATOR_FINISHED;
+ const float factor = 1.0f / 6.0f;
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+
+ int a, a_end;
+ bool changed = false;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ /* duplicate the curve to use in weight calculation */
+ const BezTriple *bezt_orig = MEM_dupallocN(nu->bezt);
+ BezTriple *bezt;
+ changed = false;
+
+ /* check whether its cyclic or not, and set initial & final conditions */
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ a = 0;
+ a_end = nu->pntsu;
+ }
+ else {
+ a = 1;
+ a_end = nu->pntsu - 1;
+ }
+
+ /* for all the curve points */
+ for (; a < a_end; a++) {
+ /* respect selection */
+ bezt = &nu->bezt[a];
+ if (bezt->f2 & SELECT) {
+ const BezTriple *bezt_orig_prev, *bezt_orig_next;
+
+ bezt_orig_prev = &bezt_orig[mod_i(a - 1, nu->pntsu)];
+ bezt_orig_next = &bezt_orig[mod_i(a + 1, nu->pntsu)];
+
+ smooth_single_bezt(bezt, bezt_orig_prev, bezt_orig_next, factor);
+
+ changed = true;
+ }
+ }
+ MEM_freeN((void *)bezt_orig);
+ if (changed) {
+ BKE_nurb_handles_calc(nu);
+ }
+ }
+ else if (nu->bp) {
+ /* Same as above, keep these the same! */
+ const BPoint *bp_orig = MEM_dupallocN(nu->bp);
+ BPoint *bp;
+
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ a = 0;
+ a_end = nu->pntsu;
+ }
+ else {
+ a = 1;
+ a_end = nu->pntsu - 1;
+ }
+
+ for (; a < a_end; a++) {
+ bp = &nu->bp[a];
+ if (bp->f1 & SELECT) {
+ const BPoint *bp_orig_prev, *bp_orig_next;
+
+ bp_orig_prev = &bp_orig[mod_i(a - 1, nu->pntsu)];
+ bp_orig_next = &bp_orig[mod_i(a + 1, nu->pntsu)];
+
+ smooth_single_bp(bp, bp_orig_prev, bp_orig_next, factor);
+ }
+ }
+ MEM_freeN((void *)bp_orig);
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+
+ return OPERATOR_FINISHED;
}
void CURVE_OT_smooth(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Smooth";
- ot->description = "Flatten angles of selected points";
- ot->idname = "CURVE_OT_smooth";
+ /* identifiers */
+ ot->name = "Smooth";
+ ot->description = "Flatten angles of selected points";
+ ot->idname = "CURVE_OT_smooth";
- /* api callbacks */
- ot->exec = smooth_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = smooth_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* -------------------------------------------------------------------- */
@@ -2823,418 +2840,439 @@ void CURVE_OT_smooth(wmOperatorType *ot)
* TODO: support cyclic curves
*/
-static void curve_smooth_value(ListBase *editnurb,
- const int bezt_offsetof, const int bp_offset)
+static void curve_smooth_value(ListBase *editnurb, const int bezt_offsetof, const int bp_offset)
{
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
- /* use for smoothing */
- int last_sel;
- int start_sel, end_sel; /* selection indices, inclusive */
- float start_rad, end_rad, fac, range;
+ /* use for smoothing */
+ int last_sel;
+ int start_sel, end_sel; /* selection indices, inclusive */
+ float start_rad, end_rad, fac, range;
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->bezt) {
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
#define BEZT_VALUE(bezt) (*((float *)((char *)(bezt) + bezt_offsetof)))
- for (last_sel = 0; last_sel < nu->pntsu; last_sel++) {
- /* loop over selection segments of a curve, smooth each */
-
- /* Start BezTriple code,
- * this is duplicated below for points, make sure these functions stay in sync */
- start_sel = -1;
- for (bezt = &nu->bezt[last_sel], a = last_sel; a < nu->pntsu; a++, bezt++) {
- if (bezt->f2 & SELECT) {
- start_sel = a;
- break;
- }
- }
- /* in case there are no other selected verts */
- end_sel = start_sel;
- for (bezt = &nu->bezt[start_sel + 1], a = start_sel + 1; a < nu->pntsu; a++, bezt++) {
- if ((bezt->f2 & SELECT) == 0) {
- break;
- }
- end_sel = a;
- }
-
- if (start_sel == -1) {
- last_sel = nu->pntsu; /* next... */
- }
- else {
- last_sel = end_sel; /* before we modify it */
-
- /* now blend between start and end sel */
- start_rad = end_rad = FLT_MAX;
-
- if (start_sel == end_sel) {
- /* simple, only 1 point selected */
- if (start_sel > 0) { start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]); }
- if (end_sel != -1 && end_sel < nu->pntsu) { end_rad = BEZT_VALUE(&nu->bezt[start_sel + 1]); }
-
- if (start_rad != FLT_MAX && end_rad >= FLT_MAX) { BEZT_VALUE(&nu->bezt[start_sel]) = (start_rad + end_rad) / 2.0f; }
- else if (start_rad != FLT_MAX) { BEZT_VALUE(&nu->bezt[start_sel]) = start_rad; }
- else if (end_rad != FLT_MAX) { BEZT_VALUE(&nu->bezt[start_sel]) = end_rad; }
- }
- else {
- /* if endpoints selected, then use them */
- if (start_sel == 0) {
- start_rad = BEZT_VALUE(&nu->bezt[start_sel]);
- start_sel++; /* we don't want to edit the selected endpoint */
- }
- else {
- start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]);
- }
- if (end_sel == nu->pntsu - 1) {
- end_rad = BEZT_VALUE(&nu->bezt[end_sel]);
- end_sel--; /* we don't want to edit the selected endpoint */
- }
- else {
- end_rad = BEZT_VALUE(&nu->bezt[end_sel + 1]);
- }
-
- /* Now Blend between the points */
- range = (float)(end_sel - start_sel) + 2.0f;
- for (bezt = &nu->bezt[start_sel], a = start_sel; a <= end_sel; a++, bezt++) {
- fac = (float)(1 + a - start_sel) / range;
- BEZT_VALUE(bezt) = start_rad * (1.0f - fac) + end_rad * fac;
- }
- }
- }
- }
+ for (last_sel = 0; last_sel < nu->pntsu; last_sel++) {
+ /* loop over selection segments of a curve, smooth each */
+
+ /* Start BezTriple code,
+ * this is duplicated below for points, make sure these functions stay in sync */
+ start_sel = -1;
+ for (bezt = &nu->bezt[last_sel], a = last_sel; a < nu->pntsu; a++, bezt++) {
+ if (bezt->f2 & SELECT) {
+ start_sel = a;
+ break;
+ }
+ }
+ /* in case there are no other selected verts */
+ end_sel = start_sel;
+ for (bezt = &nu->bezt[start_sel + 1], a = start_sel + 1; a < nu->pntsu; a++, bezt++) {
+ if ((bezt->f2 & SELECT) == 0) {
+ break;
+ }
+ end_sel = a;
+ }
+
+ if (start_sel == -1) {
+ last_sel = nu->pntsu; /* next... */
+ }
+ else {
+ last_sel = end_sel; /* before we modify it */
+
+ /* now blend between start and end sel */
+ start_rad = end_rad = FLT_MAX;
+
+ if (start_sel == end_sel) {
+ /* simple, only 1 point selected */
+ if (start_sel > 0) {
+ start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]);
+ }
+ if (end_sel != -1 && end_sel < nu->pntsu) {
+ end_rad = BEZT_VALUE(&nu->bezt[start_sel + 1]);
+ }
+
+ if (start_rad != FLT_MAX && end_rad >= FLT_MAX) {
+ BEZT_VALUE(&nu->bezt[start_sel]) = (start_rad + end_rad) / 2.0f;
+ }
+ else if (start_rad != FLT_MAX) {
+ BEZT_VALUE(&nu->bezt[start_sel]) = start_rad;
+ }
+ else if (end_rad != FLT_MAX) {
+ BEZT_VALUE(&nu->bezt[start_sel]) = end_rad;
+ }
+ }
+ else {
+ /* if endpoints selected, then use them */
+ if (start_sel == 0) {
+ start_rad = BEZT_VALUE(&nu->bezt[start_sel]);
+ start_sel++; /* we don't want to edit the selected endpoint */
+ }
+ else {
+ start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]);
+ }
+ if (end_sel == nu->pntsu - 1) {
+ end_rad = BEZT_VALUE(&nu->bezt[end_sel]);
+ end_sel--; /* we don't want to edit the selected endpoint */
+ }
+ else {
+ end_rad = BEZT_VALUE(&nu->bezt[end_sel + 1]);
+ }
+
+ /* Now Blend between the points */
+ range = (float)(end_sel - start_sel) + 2.0f;
+ for (bezt = &nu->bezt[start_sel], a = start_sel; a <= end_sel; a++, bezt++) {
+ fac = (float)(1 + a - start_sel) / range;
+ BEZT_VALUE(bezt) = start_rad * (1.0f - fac) + end_rad * fac;
+ }
+ }
+ }
+ }
#undef BEZT_VALUE
- }
- else if (nu->bp) {
+ }
+ else if (nu->bp) {
#define BP_VALUE(bp) (*((float *)((char *)(bp) + bp_offset)))
- /* Same as above, keep these the same! */
- for (last_sel = 0; last_sel < nu->pntsu; last_sel++) {
- /* loop over selection segments of a curve, smooth each */
-
- /* Start BezTriple code,
- * this is duplicated below for points, make sure these functions stay in sync */
- start_sel = -1;
- for (bp = &nu->bp[last_sel], a = last_sel; a < nu->pntsu; a++, bp++) {
- if (bp->f1 & SELECT) {
- start_sel = a;
- break;
- }
- }
- /* in case there are no other selected verts */
- end_sel = start_sel;
- for (bp = &nu->bp[start_sel + 1], a = start_sel + 1; a < nu->pntsu; a++, bp++) {
- if ((bp->f1 & SELECT) == 0) {
- break;
- }
- end_sel = a;
- }
-
- if (start_sel == -1) {
- last_sel = nu->pntsu; /* next... */
- }
- else {
- last_sel = end_sel; /* before we modify it */
-
- /* now blend between start and end sel */
- start_rad = end_rad = FLT_MAX;
-
- if (start_sel == end_sel) {
- /* simple, only 1 point selected */
- if (start_sel > 0) { start_rad = BP_VALUE(&nu->bp[start_sel - 1]); }
- if (end_sel != -1 && end_sel < nu->pntsu) { end_rad = BP_VALUE(&nu->bp[start_sel + 1]); }
-
- if (start_rad != FLT_MAX && end_rad != FLT_MAX) { BP_VALUE(&nu->bp[start_sel]) = (start_rad + end_rad) / 2; }
- else if (start_rad != FLT_MAX) { BP_VALUE(&nu->bp[start_sel]) = start_rad; }
- else if (end_rad != FLT_MAX) { BP_VALUE(&nu->bp[start_sel]) = end_rad; }
- }
- else {
- /* if endpoints selected, then use them */
- if (start_sel == 0) {
- start_rad = BP_VALUE(&nu->bp[start_sel]);
- start_sel++; /* we don't want to edit the selected endpoint */
- }
- else {
- start_rad = BP_VALUE(&nu->bp[start_sel - 1]);
- }
- if (end_sel == nu->pntsu - 1) {
- end_rad = BP_VALUE(&nu->bp[end_sel]);
- end_sel--; /* we don't want to edit the selected endpoint */
- }
- else {
- end_rad = BP_VALUE(&nu->bp[end_sel + 1]);
- }
-
- /* Now Blend between the points */
- range = (float)(end_sel - start_sel) + 2.0f;
- for (bp = &nu->bp[start_sel], a = start_sel; a <= end_sel; a++, bp++) {
- fac = (float)(1 + a - start_sel) / range;
- BP_VALUE(bp) = start_rad * (1.0f - fac) + end_rad * fac;
- }
- }
- }
- }
+ /* Same as above, keep these the same! */
+ for (last_sel = 0; last_sel < nu->pntsu; last_sel++) {
+ /* loop over selection segments of a curve, smooth each */
+
+ /* Start BezTriple code,
+ * this is duplicated below for points, make sure these functions stay in sync */
+ start_sel = -1;
+ for (bp = &nu->bp[last_sel], a = last_sel; a < nu->pntsu; a++, bp++) {
+ if (bp->f1 & SELECT) {
+ start_sel = a;
+ break;
+ }
+ }
+ /* in case there are no other selected verts */
+ end_sel = start_sel;
+ for (bp = &nu->bp[start_sel + 1], a = start_sel + 1; a < nu->pntsu; a++, bp++) {
+ if ((bp->f1 & SELECT) == 0) {
+ break;
+ }
+ end_sel = a;
+ }
+
+ if (start_sel == -1) {
+ last_sel = nu->pntsu; /* next... */
+ }
+ else {
+ last_sel = end_sel; /* before we modify it */
+
+ /* now blend between start and end sel */
+ start_rad = end_rad = FLT_MAX;
+
+ if (start_sel == end_sel) {
+ /* simple, only 1 point selected */
+ if (start_sel > 0) {
+ start_rad = BP_VALUE(&nu->bp[start_sel - 1]);
+ }
+ if (end_sel != -1 && end_sel < nu->pntsu) {
+ end_rad = BP_VALUE(&nu->bp[start_sel + 1]);
+ }
+
+ if (start_rad != FLT_MAX && end_rad != FLT_MAX) {
+ BP_VALUE(&nu->bp[start_sel]) = (start_rad + end_rad) / 2;
+ }
+ else if (start_rad != FLT_MAX) {
+ BP_VALUE(&nu->bp[start_sel]) = start_rad;
+ }
+ else if (end_rad != FLT_MAX) {
+ BP_VALUE(&nu->bp[start_sel]) = end_rad;
+ }
+ }
+ else {
+ /* if endpoints selected, then use them */
+ if (start_sel == 0) {
+ start_rad = BP_VALUE(&nu->bp[start_sel]);
+ start_sel++; /* we don't want to edit the selected endpoint */
+ }
+ else {
+ start_rad = BP_VALUE(&nu->bp[start_sel - 1]);
+ }
+ if (end_sel == nu->pntsu - 1) {
+ end_rad = BP_VALUE(&nu->bp[end_sel]);
+ end_sel--; /* we don't want to edit the selected endpoint */
+ }
+ else {
+ end_rad = BP_VALUE(&nu->bp[end_sel + 1]);
+ }
+
+ /* Now Blend between the points */
+ range = (float)(end_sel - start_sel) + 2.0f;
+ for (bp = &nu->bp[start_sel], a = start_sel; a <= end_sel; a++, bp++) {
+ fac = (float)(1 + a - start_sel) / range;
+ BP_VALUE(bp) = start_rad * (1.0f - fac) + end_rad * fac;
+ }
+ }
+ }
+ }
#undef BP_VALUE
- }
- }
+ }
+ }
}
static int curve_smooth_weight_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
- curve_smooth_value(editnurb, offsetof(BezTriple, weight), offsetof(BPoint, weight));
+ curve_smooth_value(editnurb, offsetof(BezTriple, weight), offsetof(BPoint, weight));
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void CURVE_OT_smooth_weight(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Smooth Curve Weight";
- ot->description = "Interpolate weight of selected points";
- ot->idname = "CURVE_OT_smooth_weight";
+ /* identifiers */
+ ot->name = "Smooth Curve Weight";
+ ot->description = "Interpolate weight of selected points";
+ ot->idname = "CURVE_OT_smooth_weight";
- /* api clastbacks */
- ot->exec = curve_smooth_weight_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api clastbacks */
+ ot->exec = curve_smooth_weight_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int curve_smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
- curve_smooth_value(editnurb, offsetof(BezTriple, radius), offsetof(BPoint, radius));
+ curve_smooth_value(editnurb, offsetof(BezTriple, radius), offsetof(BPoint, radius));
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void CURVE_OT_smooth_radius(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Smooth Curve Radius";
- ot->description = "Interpolate radii of selected points";
- ot->idname = "CURVE_OT_smooth_radius";
+ /* identifiers */
+ ot->name = "Smooth Curve Radius";
+ ot->description = "Interpolate radii of selected points";
+ ot->idname = "CURVE_OT_smooth_radius";
- /* api clastbacks */
- ot->exec = curve_smooth_radius_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api clastbacks */
+ ot->exec = curve_smooth_radius_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int curve_smooth_tilt_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
- curve_smooth_value(editnurb, offsetof(BezTriple, tilt), offsetof(BPoint, tilt));
+ curve_smooth_value(editnurb, offsetof(BezTriple, tilt), offsetof(BPoint, tilt));
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void CURVE_OT_smooth_tilt(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Smooth Curve Tilt";
- ot->description = "Interpolate tilt of selected points";
- ot->idname = "CURVE_OT_smooth_tilt";
+ /* identifiers */
+ ot->name = "Smooth Curve Tilt";
+ ot->description = "Interpolate tilt of selected points";
+ ot->idname = "CURVE_OT_smooth_tilt";
- /* api clastbacks */
- ot->exec = curve_smooth_tilt_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api clastbacks */
+ ot->exec = curve_smooth_tilt_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/********************** hide operator *********************/
static int hide_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- const bool invert = RNA_boolean_get(op->ptr, "unselected");
-
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
-
- if (!(invert || ED_curve_select_check(v3d, cu->editnurb))) {
- continue;
- }
-
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- BPoint *bp;
- BezTriple *bezt;
- int a, sel;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- sel = 0;
- while (a--) {
- if (invert == 0 && BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
- bezt->hide = 1;
- }
- else if (invert && !BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
- bezt->hide = 1;
- }
- if (bezt->hide) {
- sel++;
- }
- bezt++;
- }
- if (sel == nu->pntsu) {
- nu->hide = 1;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- sel = 0;
- while (a--) {
- if (invert == 0 && (bp->f1 & SELECT)) {
- select_bpoint(bp, DESELECT, SELECT, HIDDEN);
- bp->hide = 1;
- }
- else if (invert && (bp->f1 & SELECT) == 0) {
- select_bpoint(bp, DESELECT, SELECT, HIDDEN);
- bp->hide = 1;
- }
- if (bp->hide) {
- sel++;
- }
- bp++;
- }
- if (sel == nu->pntsu * nu->pntsv) {
- nu->hide = 1;
- }
- }
- }
-
- DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- BKE_curve_nurb_vert_active_validate(obedit->data);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ const bool invert = RNA_boolean_get(op->ptr, "unselected");
+
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+
+ if (!(invert || ED_curve_select_check(v3d, cu->editnurb))) {
+ continue;
+ }
+
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ int a, sel;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ sel = 0;
+ while (a--) {
+ if (invert == 0 && BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
+ bezt->hide = 1;
+ }
+ else if (invert && !BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
+ bezt->hide = 1;
+ }
+ if (bezt->hide) {
+ sel++;
+ }
+ bezt++;
+ }
+ if (sel == nu->pntsu) {
+ nu->hide = 1;
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ sel = 0;
+ while (a--) {
+ if (invert == 0 && (bp->f1 & SELECT)) {
+ select_bpoint(bp, DESELECT, SELECT, HIDDEN);
+ bp->hide = 1;
+ }
+ else if (invert && (bp->f1 & SELECT) == 0) {
+ select_bpoint(bp, DESELECT, SELECT, HIDDEN);
+ bp->hide = 1;
+ }
+ if (bp->hide) {
+ sel++;
+ }
+ bp++;
+ }
+ if (sel == nu->pntsu * nu->pntsv) {
+ nu->hide = 1;
+ }
+ }
+ }
+
+ DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ BKE_curve_nurb_vert_active_validate(obedit->data);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_hide(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Hide Selected";
- ot->idname = "CURVE_OT_hide";
- ot->description = "Hide (un)selected control points";
+ /* identifiers */
+ ot->name = "Hide Selected";
+ ot->idname = "CURVE_OT_hide";
+ ot->description = "Hide (un)selected control points";
- /* api callbacks */
- ot->exec = hide_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = hide_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected");
+ /* props */
+ RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected");
}
/********************** reveal operator *********************/
static int reveal_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- const bool select = RNA_boolean_get(op->ptr, "select");
- bool changed_multi = false;
-
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- BPoint *bp;
- BezTriple *bezt;
- int a;
- bool changed = false;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- nu->hide = 0;
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- if (bezt->hide) {
- select_beztriple(bezt, select, SELECT, HIDDEN);
- bezt->hide = 0;
- changed = true;
- }
- bezt++;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- if (bp->hide) {
- select_bpoint(bp, select, SELECT, HIDDEN);
- bp->hide = 0;
- changed = true;
- }
- bp++;
- }
- }
- }
-
- if (changed) {
- DEG_id_tag_update(obedit->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- changed_multi = true;
- }
- }
- MEM_freeN(objects);
- return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ const bool select = RNA_boolean_get(op->ptr, "select");
+ bool changed_multi = false;
+
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ int a;
+ bool changed = false;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ nu->hide = 0;
+ if (nu->type == CU_BEZIER) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ while (a--) {
+ if (bezt->hide) {
+ select_beztriple(bezt, select, SELECT, HIDDEN);
+ bezt->hide = 0;
+ changed = true;
+ }
+ bezt++;
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ if (bp->hide) {
+ select_bpoint(bp, select, SELECT, HIDDEN);
+ bp->hide = 0;
+ changed = true;
+ }
+ bp++;
+ }
+ }
+ }
+
+ if (changed) {
+ DEG_id_tag_update(obedit->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ changed_multi = true;
+ }
+ }
+ MEM_freeN(objects);
+ return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void CURVE_OT_reveal(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Reveal Hidden";
- ot->idname = "CURVE_OT_reveal";
- ot->description = "Reveal hidden control points";
+ /* identifiers */
+ ot->name = "Reveal Hidden";
+ ot->idname = "CURVE_OT_reveal";
+ ot->description = "Reveal hidden control points";
- /* api callbacks */
- ot->exec = reveal_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = reveal_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "select", true, "Select", "");
+ RNA_def_boolean(ot->srna, "select", true, "Select", "");
}
/********************** subdivide operator *********************/
@@ -3245,779 +3283,814 @@ void CURVE_OT_reveal(wmOperatorType *ot)
*/
static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts)
{
- Curve *cu = obedit->data;
- EditNurb *editnurb = cu->editnurb;
- Nurb *nu;
- BezTriple *bezt, *beztnew, *beztn;
- BPoint *bp, *prevbp, *bpnew, *bpn;
- float vec[15];
- int a, b, sel, amount, *usel, *vsel, i;
- float factor;
-
- // printf("*** subdivideNurb: entering subdivide\n");
-
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- amount = 0;
- if (nu->type == CU_BEZIER) {
- BezTriple *nextbezt;
-
- /*
- * Insert a point into a 2D Bezier curve.
- * Endpoints are preserved. Otherwise, all selected and inserted points are
- * newly created. Old points are discarded.
- */
- /* count */
- a = nu->pntsu;
- bezt = nu->bezt;
- while (a--) {
- nextbezt = BKE_nurb_bezt_get_next(nu, bezt);
- if (nextbezt == NULL) {
- break;
- }
-
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt) && BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, nextbezt)) {
- amount += number_cuts;
- }
- bezt++;
- }
-
- if (amount) {
- /* insert */
- beztnew = (BezTriple *)MEM_mallocN((amount + nu->pntsu) * sizeof(BezTriple), "subdivNurb");
- beztn = beztnew;
- a = nu->pntsu;
- bezt = nu->bezt;
- while (a--) {
- memcpy(beztn, bezt, sizeof(BezTriple));
- keyIndex_updateBezt(editnurb, bezt, beztn, 1);
- beztn++;
-
- nextbezt = BKE_nurb_bezt_get_next(nu, bezt);
- if (nextbezt == NULL) {
- break;
- }
-
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt) && BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, nextbezt)) {
- float prevvec[3][3];
-
- memcpy(prevvec, bezt->vec, sizeof(float) * 9);
-
- for (i = 0; i < number_cuts; i++) {
- factor = 1.0f / (number_cuts + 1 - i);
-
- memcpy(beztn, nextbezt, sizeof(BezTriple));
-
- /* midpoint subdividing */
- interp_v3_v3v3(vec, prevvec[1], prevvec[2], factor);
- interp_v3_v3v3(vec + 3, prevvec[2], nextbezt->vec[0], factor);
- interp_v3_v3v3(vec + 6, nextbezt->vec[0], nextbezt->vec[1], factor);
-
- interp_v3_v3v3(vec + 9, vec, vec + 3, factor);
- interp_v3_v3v3(vec + 12, vec + 3, vec + 6, factor);
-
- /* change handle of prev beztn */
- copy_v3_v3((beztn - 1)->vec[2], vec);
- /* new point */
- copy_v3_v3(beztn->vec[0], vec + 9);
- interp_v3_v3v3(beztn->vec[1], vec + 9, vec + 12, factor);
- copy_v3_v3(beztn->vec[2], vec + 12);
- /* handle of next bezt */
- if (a == 0 && i == number_cuts - 1 && (nu->flagu & CU_NURB_CYCLIC)) { copy_v3_v3(beztnew->vec[0], vec + 6); }
- else { copy_v3_v3(nextbezt->vec[0], vec + 6); }
-
- beztn->radius = (bezt->radius + nextbezt->radius) / 2;
- beztn->weight = (bezt->weight + nextbezt->weight) / 2;
-
- memcpy(prevvec, beztn->vec, sizeof(float) * 9);
- beztn++;
- }
- }
-
- bezt++;
- }
-
- MEM_freeN(nu->bezt);
- nu->bezt = beztnew;
- nu->pntsu += amount;
-
- BKE_nurb_handles_calc(nu);
- }
- } /* End of 'if (nu->type == CU_BEZIER)' */
- else if (nu->pntsv == 1) {
- BPoint *nextbp;
-
- /*
- * All flat lines (ie. co-planar), except flat Nurbs. Flat NURB curves
- * are handled together with the regular NURB plane division, as it
- * should be. I split it off just now, let's see if it is
- * stable... nzc 30-5-'00
- */
- /* count */
- a = nu->pntsu;
- bp = nu->bp;
- while (a--) {
- nextbp = BKE_nurb_bpoint_get_next(nu, bp);
- if (nextbp == NULL) {
- break;
- }
-
- if ((bp->f1 & SELECT) && (nextbp->f1 & SELECT)) {
- amount += number_cuts;
- }
- bp++;
- }
-
- if (amount) {
- /* insert */
- bpnew = (BPoint *)MEM_mallocN((amount + nu->pntsu) * sizeof(BPoint), "subdivNurb2");
- bpn = bpnew;
-
- a = nu->pntsu;
- bp = nu->bp;
-
- while (a--) {
- /* Copy "old" point. */
- memcpy(bpn, bp, sizeof(BPoint));
- keyIndex_updateBP(editnurb, bp, bpn, 1);
- bpn++;
-
- nextbp = BKE_nurb_bpoint_get_next(nu, bp);
- if (nextbp == NULL) {
- break;
- }
-
- if ((bp->f1 & SELECT) && (nextbp->f1 & SELECT)) {
- // printf("*** subdivideNurb: insert 'linear' point\n");
- for (i = 0; i < number_cuts; i++) {
- factor = (float)(i + 1) / (number_cuts + 1);
-
- memcpy(bpn, nextbp, sizeof(BPoint));
- interp_v4_v4v4(bpn->vec, bp->vec, nextbp->vec, factor);
- bpn++;
- }
-
- }
- bp++;
- }
-
- MEM_freeN(nu->bp);
- nu->bp = bpnew;
- nu->pntsu += amount;
-
- if (nu->type & CU_NURBS) {
- BKE_nurb_knot_calc_u(nu);
- }
- }
- } /* End of 'else if (nu->pntsv == 1)' */
- else if (nu->type == CU_NURBS) {
- /* This is a very strange test ... */
- /**
- * Subdivide NURB surfaces - nzc 30-5-'00 -
- *
- * Subdivision of a NURB curve can be effected by adding a
- * control point (insertion of a knot), or by raising the
- * degree of the functions used to build the NURB. The
- * expression
- *
- * degree = #knots - #controlpoints + 1 (J Walter piece)
- * degree = #knots - #controlpoints (Blender
- * implementation)
- * ( this is confusing.... what is true? Another concern
- * is that the JW piece allows the curve to become
- * explicitly 1st order derivative discontinuous, while
- * this is not what we want here... )
- *
- * is an invariant for a single NURB curve. Raising the degree
- * of the NURB is done elsewhere; the degree is assumed
- * constant during this operation. Degree is a property shared
- * by all controlpoints in a curve (even though it is stored
- * per control point - this can be misleading).
- * Adding a knot is done by searching for the place in the
- * knot vector where a certain knot value must be inserted, or
- * by picking an appropriate knot value between two existing
- * ones. The number of controlpoints that is influenced by the
- * insertion depends on the order of the curve. A certain
- * minimum number of knots is needed to form high-order
- * curves, as can be seen from the equation above. In Blender,
- * currently NURBs may be up to 6th order, so we modify at
- * most 6 points. One point is added. For an n-degree curve,
- * n points are discarded, and n+1 points inserted
- * (so effectively, n points are modified). (that holds for
- * the JW piece, but it seems not for our NURBs)
- * In practice, the knot spacing is copied, but the tail
- * (the points following the insertion point) need to be
- * offset to keep the knot series ascending. The knot series
- * is always a series of monotonically ascending integers in
- * Blender. When not enough control points are available to
- * fit the order, duplicates of the endpoints are added as
- * needed.
- */
- /* selection-arrays */
- usel = MEM_callocN(sizeof(int) * nu->pntsu, "subivideNurb3");
- vsel = MEM_callocN(sizeof(int) * nu->pntsv, "subivideNurb3");
- sel = 0;
-
- /* Count the number of selected points. */
- bp = nu->bp;
- for (a = 0; a < nu->pntsv; a++) {
- for (b = 0; b < nu->pntsu; b++) {
- if (bp->f1 & SELECT) {
- usel[b]++;
- vsel[a]++;
- sel++;
- }
- bp++;
- }
- }
- if (sel == (nu->pntsu * nu->pntsv)) { /* subdivide entire nurb */
- /* Global subdivision is a special case of partial
- * subdivision. Strange it is considered separately... */
-
- /* count of nodes (after subdivision) along U axis */
- int countu = nu->pntsu + (nu->pntsu - 1) * number_cuts;
-
- /* total count of nodes after subdivision */
- int tot = ((number_cuts + 1) * nu->pntsu - number_cuts) * ((number_cuts + 1) * nu->pntsv - number_cuts);
-
- bpn = bpnew = MEM_mallocN(tot * sizeof(BPoint), "subdivideNurb4");
- bp = nu->bp;
- /* first subdivide rows */
- for (a = 0; a < nu->pntsv; a++) {
- for (b = 0; b < nu->pntsu; b++) {
- *bpn = *bp;
- keyIndex_updateBP(editnurb, bp, bpn, 1);
- bpn++;
- bp++;
- if (b < nu->pntsu - 1) {
- prevbp = bp - 1;
- for (i = 0; i < number_cuts; i++) {
- factor = (float)(i + 1) / (number_cuts + 1);
- *bpn = *bp;
- interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor);
- bpn++;
- }
- }
- }
- bpn += number_cuts * countu;
- }
- /* now insert new */
- bpn = bpnew + ((number_cuts + 1) * nu->pntsu - number_cuts);
- bp = bpnew + (number_cuts + 1) * ((number_cuts + 1) * nu->pntsu - number_cuts);
- prevbp = bpnew;
- for (a = 1; a < nu->pntsv; a++) {
-
- for (b = 0; b < (number_cuts + 1) * nu->pntsu - number_cuts; b++) {
- BPoint *tmp = bpn;
- for (i = 0; i < number_cuts; i++) {
- factor = (float)(i + 1) / (number_cuts + 1);
- *tmp = *bp;
- interp_v4_v4v4(tmp->vec, prevbp->vec, bp->vec, factor);
- tmp += countu;
- }
- bp++;
- prevbp++;
- bpn++;
- }
- bp += number_cuts * countu;
- bpn += number_cuts * countu;
- prevbp += number_cuts * countu;
- }
- MEM_freeN(nu->bp);
- nu->bp = bpnew;
- nu->pntsu = (number_cuts + 1) * nu->pntsu - number_cuts;
- nu->pntsv = (number_cuts + 1) * nu->pntsv - number_cuts;
- BKE_nurb_knot_calc_u(nu);
- BKE_nurb_knot_calc_v(nu);
- } /* End of 'if (sel == nu->pntsu * nu->pntsv)' (subdivide entire NURB) */
- else {
- /* subdivide in v direction? */
- sel = 0;
- for (a = 0; a < nu->pntsv - 1; a++) {
- if (vsel[a] == nu->pntsu && vsel[a + 1] == nu->pntsu) {
- sel += number_cuts;
- }
- }
-
- if (sel) { /* V ! */
- bpn = bpnew = MEM_mallocN((sel + nu->pntsv) * nu->pntsu * sizeof(BPoint), "subdivideNurb4");
- bp = nu->bp;
- for (a = 0; a < nu->pntsv; a++) {
- for (b = 0; b < nu->pntsu; b++) {
- *bpn = *bp;
- keyIndex_updateBP(editnurb, bp, bpn, 1);
- bpn++;
- bp++;
- }
- if ( (a < nu->pntsv - 1) && vsel[a] == nu->pntsu && vsel[a + 1] == nu->pntsu) {
- for (i = 0; i < number_cuts; i++) {
- factor = (float)(i + 1) / (number_cuts + 1);
- prevbp = bp - nu->pntsu;
- for (b = 0; b < nu->pntsu; b++) {
- /*
- * This simple bisection must be replaces by a
- * subtle resampling of a number of points. Our
- * task is made slightly easier because each
- * point in our curve is a separate data
- * node. (is it?)
- */
- *bpn = *prevbp;
- interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor);
- bpn++;
-
- prevbp++;
- bp++;
- }
- bp -= nu->pntsu;
- }
- }
- }
- MEM_freeN(nu->bp);
- nu->bp = bpnew;
- nu->pntsv += sel;
- BKE_nurb_knot_calc_v(nu);
- }
- else {
- /* or in u direction? */
- sel = 0;
- for (a = 0; a < nu->pntsu - 1; a++) {
- if (usel[a] == nu->pntsv && usel[a + 1] == nu->pntsv) {
- sel += number_cuts;
- }
- }
-
- if (sel) { /* U ! */
- /* Inserting U points is sort of 'default' Flat curves only get */
- /* U points inserted in them. */
- bpn = bpnew = MEM_mallocN((sel + nu->pntsu) * nu->pntsv * sizeof(BPoint), "subdivideNurb4");
- bp = nu->bp;
- for (a = 0; a < nu->pntsv; a++) {
- for (b = 0; b < nu->pntsu; b++) {
- *bpn = *bp;
- keyIndex_updateBP(editnurb, bp, bpn, 1);
- bpn++;
- bp++;
- if ( (b < nu->pntsu - 1) && usel[b] == nu->pntsv && usel[b + 1] == nu->pntsv) {
- /*
- * One thing that bugs me here is that the
- * orders of things are not the same as in
- * the JW piece. Also, this implies that we
- * handle at most 3rd order curves? I miss
- * some symmetry here...
- */
- for (i = 0; i < number_cuts; i++) {
- factor = (float)(i + 1) / (number_cuts + 1);
- prevbp = bp - 1;
- *bpn = *prevbp;
- interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor);
- bpn++;
- }
- }
- }
- }
- MEM_freeN(nu->bp);
- nu->bp = bpnew;
- nu->pntsu += sel;
- BKE_nurb_knot_calc_u(nu); /* shift knots forward */
- }
- }
- }
- MEM_freeN(usel);
- MEM_freeN(vsel);
-
- } /* End of 'if (nu->type == CU_NURBS)' */
- }
+ Curve *cu = obedit->data;
+ EditNurb *editnurb = cu->editnurb;
+ Nurb *nu;
+ BezTriple *bezt, *beztnew, *beztn;
+ BPoint *bp, *prevbp, *bpnew, *bpn;
+ float vec[15];
+ int a, b, sel, amount, *usel, *vsel, i;
+ float factor;
+
+ // printf("*** subdivideNurb: entering subdivide\n");
+
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ amount = 0;
+ if (nu->type == CU_BEZIER) {
+ BezTriple *nextbezt;
+
+ /*
+ * Insert a point into a 2D Bezier curve.
+ * Endpoints are preserved. Otherwise, all selected and inserted points are
+ * newly created. Old points are discarded.
+ */
+ /* count */
+ a = nu->pntsu;
+ bezt = nu->bezt;
+ while (a--) {
+ nextbezt = BKE_nurb_bezt_get_next(nu, bezt);
+ if (nextbezt == NULL) {
+ break;
+ }
+
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt) &&
+ BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, nextbezt)) {
+ amount += number_cuts;
+ }
+ bezt++;
+ }
+
+ if (amount) {
+ /* insert */
+ beztnew = (BezTriple *)MEM_mallocN((amount + nu->pntsu) * sizeof(BezTriple), "subdivNurb");
+ beztn = beztnew;
+ a = nu->pntsu;
+ bezt = nu->bezt;
+ while (a--) {
+ memcpy(beztn, bezt, sizeof(BezTriple));
+ keyIndex_updateBezt(editnurb, bezt, beztn, 1);
+ beztn++;
+
+ nextbezt = BKE_nurb_bezt_get_next(nu, bezt);
+ if (nextbezt == NULL) {
+ break;
+ }
+
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt) &&
+ BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, nextbezt)) {
+ float prevvec[3][3];
+
+ memcpy(prevvec, bezt->vec, sizeof(float) * 9);
+
+ for (i = 0; i < number_cuts; i++) {
+ factor = 1.0f / (number_cuts + 1 - i);
+
+ memcpy(beztn, nextbezt, sizeof(BezTriple));
+
+ /* midpoint subdividing */
+ interp_v3_v3v3(vec, prevvec[1], prevvec[2], factor);
+ interp_v3_v3v3(vec + 3, prevvec[2], nextbezt->vec[0], factor);
+ interp_v3_v3v3(vec + 6, nextbezt->vec[0], nextbezt->vec[1], factor);
+
+ interp_v3_v3v3(vec + 9, vec, vec + 3, factor);
+ interp_v3_v3v3(vec + 12, vec + 3, vec + 6, factor);
+
+ /* change handle of prev beztn */
+ copy_v3_v3((beztn - 1)->vec[2], vec);
+ /* new point */
+ copy_v3_v3(beztn->vec[0], vec + 9);
+ interp_v3_v3v3(beztn->vec[1], vec + 9, vec + 12, factor);
+ copy_v3_v3(beztn->vec[2], vec + 12);
+ /* handle of next bezt */
+ if (a == 0 && i == number_cuts - 1 && (nu->flagu & CU_NURB_CYCLIC)) {
+ copy_v3_v3(beztnew->vec[0], vec + 6);
+ }
+ else {
+ copy_v3_v3(nextbezt->vec[0], vec + 6);
+ }
+
+ beztn->radius = (bezt->radius + nextbezt->radius) / 2;
+ beztn->weight = (bezt->weight + nextbezt->weight) / 2;
+
+ memcpy(prevvec, beztn->vec, sizeof(float) * 9);
+ beztn++;
+ }
+ }
+
+ bezt++;
+ }
+
+ MEM_freeN(nu->bezt);
+ nu->bezt = beztnew;
+ nu->pntsu += amount;
+
+ BKE_nurb_handles_calc(nu);
+ }
+ } /* End of 'if (nu->type == CU_BEZIER)' */
+ else if (nu->pntsv == 1) {
+ BPoint *nextbp;
+
+ /*
+ * All flat lines (ie. co-planar), except flat Nurbs. Flat NURB curves
+ * are handled together with the regular NURB plane division, as it
+ * should be. I split it off just now, let's see if it is
+ * stable... nzc 30-5-'00
+ */
+ /* count */
+ a = nu->pntsu;
+ bp = nu->bp;
+ while (a--) {
+ nextbp = BKE_nurb_bpoint_get_next(nu, bp);
+ if (nextbp == NULL) {
+ break;
+ }
+
+ if ((bp->f1 & SELECT) && (nextbp->f1 & SELECT)) {
+ amount += number_cuts;
+ }
+ bp++;
+ }
+
+ if (amount) {
+ /* insert */
+ bpnew = (BPoint *)MEM_mallocN((amount + nu->pntsu) * sizeof(BPoint), "subdivNurb2");
+ bpn = bpnew;
+
+ a = nu->pntsu;
+ bp = nu->bp;
+
+ while (a--) {
+ /* Copy "old" point. */
+ memcpy(bpn, bp, sizeof(BPoint));
+ keyIndex_updateBP(editnurb, bp, bpn, 1);
+ bpn++;
+
+ nextbp = BKE_nurb_bpoint_get_next(nu, bp);
+ if (nextbp == NULL) {
+ break;
+ }
+
+ if ((bp->f1 & SELECT) && (nextbp->f1 & SELECT)) {
+ // printf("*** subdivideNurb: insert 'linear' point\n");
+ for (i = 0; i < number_cuts; i++) {
+ factor = (float)(i + 1) / (number_cuts + 1);
+
+ memcpy(bpn, nextbp, sizeof(BPoint));
+ interp_v4_v4v4(bpn->vec, bp->vec, nextbp->vec, factor);
+ bpn++;
+ }
+ }
+ bp++;
+ }
+
+ MEM_freeN(nu->bp);
+ nu->bp = bpnew;
+ nu->pntsu += amount;
+
+ if (nu->type & CU_NURBS) {
+ BKE_nurb_knot_calc_u(nu);
+ }
+ }
+ } /* End of 'else if (nu->pntsv == 1)' */
+ else if (nu->type == CU_NURBS) {
+ /* This is a very strange test ... */
+ /**
+ * Subdivide NURB surfaces - nzc 30-5-'00 -
+ *
+ * Subdivision of a NURB curve can be effected by adding a
+ * control point (insertion of a knot), or by raising the
+ * degree of the functions used to build the NURB. The
+ * expression
+ *
+ * degree = #knots - #controlpoints + 1 (J Walter piece)
+ * degree = #knots - #controlpoints (Blender
+ * implementation)
+ * ( this is confusing.... what is true? Another concern
+ * is that the JW piece allows the curve to become
+ * explicitly 1st order derivative discontinuous, while
+ * this is not what we want here... )
+ *
+ * is an invariant for a single NURB curve. Raising the degree
+ * of the NURB is done elsewhere; the degree is assumed
+ * constant during this operation. Degree is a property shared
+ * by all controlpoints in a curve (even though it is stored
+ * per control point - this can be misleading).
+ * Adding a knot is done by searching for the place in the
+ * knot vector where a certain knot value must be inserted, or
+ * by picking an appropriate knot value between two existing
+ * ones. The number of controlpoints that is influenced by the
+ * insertion depends on the order of the curve. A certain
+ * minimum number of knots is needed to form high-order
+ * curves, as can be seen from the equation above. In Blender,
+ * currently NURBs may be up to 6th order, so we modify at
+ * most 6 points. One point is added. For an n-degree curve,
+ * n points are discarded, and n+1 points inserted
+ * (so effectively, n points are modified). (that holds for
+ * the JW piece, but it seems not for our NURBs)
+ * In practice, the knot spacing is copied, but the tail
+ * (the points following the insertion point) need to be
+ * offset to keep the knot series ascending. The knot series
+ * is always a series of monotonically ascending integers in
+ * Blender. When not enough control points are available to
+ * fit the order, duplicates of the endpoints are added as
+ * needed.
+ */
+ /* selection-arrays */
+ usel = MEM_callocN(sizeof(int) * nu->pntsu, "subivideNurb3");
+ vsel = MEM_callocN(sizeof(int) * nu->pntsv, "subivideNurb3");
+ sel = 0;
+
+ /* Count the number of selected points. */
+ bp = nu->bp;
+ for (a = 0; a < nu->pntsv; a++) {
+ for (b = 0; b < nu->pntsu; b++) {
+ if (bp->f1 & SELECT) {
+ usel[b]++;
+ vsel[a]++;
+ sel++;
+ }
+ bp++;
+ }
+ }
+ if (sel == (nu->pntsu * nu->pntsv)) { /* subdivide entire nurb */
+ /* Global subdivision is a special case of partial
+ * subdivision. Strange it is considered separately... */
+
+ /* count of nodes (after subdivision) along U axis */
+ int countu = nu->pntsu + (nu->pntsu - 1) * number_cuts;
+
+ /* total count of nodes after subdivision */
+ int tot = ((number_cuts + 1) * nu->pntsu - number_cuts) *
+ ((number_cuts + 1) * nu->pntsv - number_cuts);
+
+ bpn = bpnew = MEM_mallocN(tot * sizeof(BPoint), "subdivideNurb4");
+ bp = nu->bp;
+ /* first subdivide rows */
+ for (a = 0; a < nu->pntsv; a++) {
+ for (b = 0; b < nu->pntsu; b++) {
+ *bpn = *bp;
+ keyIndex_updateBP(editnurb, bp, bpn, 1);
+ bpn++;
+ bp++;
+ if (b < nu->pntsu - 1) {
+ prevbp = bp - 1;
+ for (i = 0; i < number_cuts; i++) {
+ factor = (float)(i + 1) / (number_cuts + 1);
+ *bpn = *bp;
+ interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor);
+ bpn++;
+ }
+ }
+ }
+ bpn += number_cuts * countu;
+ }
+ /* now insert new */
+ bpn = bpnew + ((number_cuts + 1) * nu->pntsu - number_cuts);
+ bp = bpnew + (number_cuts + 1) * ((number_cuts + 1) * nu->pntsu - number_cuts);
+ prevbp = bpnew;
+ for (a = 1; a < nu->pntsv; a++) {
+
+ for (b = 0; b < (number_cuts + 1) * nu->pntsu - number_cuts; b++) {
+ BPoint *tmp = bpn;
+ for (i = 0; i < number_cuts; i++) {
+ factor = (float)(i + 1) / (number_cuts + 1);
+ *tmp = *bp;
+ interp_v4_v4v4(tmp->vec, prevbp->vec, bp->vec, factor);
+ tmp += countu;
+ }
+ bp++;
+ prevbp++;
+ bpn++;
+ }
+ bp += number_cuts * countu;
+ bpn += number_cuts * countu;
+ prevbp += number_cuts * countu;
+ }
+ MEM_freeN(nu->bp);
+ nu->bp = bpnew;
+ nu->pntsu = (number_cuts + 1) * nu->pntsu - number_cuts;
+ nu->pntsv = (number_cuts + 1) * nu->pntsv - number_cuts;
+ BKE_nurb_knot_calc_u(nu);
+ BKE_nurb_knot_calc_v(nu);
+ } /* End of 'if (sel == nu->pntsu * nu->pntsv)' (subdivide entire NURB) */
+ else {
+ /* subdivide in v direction? */
+ sel = 0;
+ for (a = 0; a < nu->pntsv - 1; a++) {
+ if (vsel[a] == nu->pntsu && vsel[a + 1] == nu->pntsu) {
+ sel += number_cuts;
+ }
+ }
+
+ if (sel) { /* V ! */
+ bpn = bpnew = MEM_mallocN((sel + nu->pntsv) * nu->pntsu * sizeof(BPoint),
+ "subdivideNurb4");
+ bp = nu->bp;
+ for (a = 0; a < nu->pntsv; a++) {
+ for (b = 0; b < nu->pntsu; b++) {
+ *bpn = *bp;
+ keyIndex_updateBP(editnurb, bp, bpn, 1);
+ bpn++;
+ bp++;
+ }
+ if ((a < nu->pntsv - 1) && vsel[a] == nu->pntsu && vsel[a + 1] == nu->pntsu) {
+ for (i = 0; i < number_cuts; i++) {
+ factor = (float)(i + 1) / (number_cuts + 1);
+ prevbp = bp - nu->pntsu;
+ for (b = 0; b < nu->pntsu; b++) {
+ /*
+ * This simple bisection must be replaces by a
+ * subtle resampling of a number of points. Our
+ * task is made slightly easier because each
+ * point in our curve is a separate data
+ * node. (is it?)
+ */
+ *bpn = *prevbp;
+ interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor);
+ bpn++;
+
+ prevbp++;
+ bp++;
+ }
+ bp -= nu->pntsu;
+ }
+ }
+ }
+ MEM_freeN(nu->bp);
+ nu->bp = bpnew;
+ nu->pntsv += sel;
+ BKE_nurb_knot_calc_v(nu);
+ }
+ else {
+ /* or in u direction? */
+ sel = 0;
+ for (a = 0; a < nu->pntsu - 1; a++) {
+ if (usel[a] == nu->pntsv && usel[a + 1] == nu->pntsv) {
+ sel += number_cuts;
+ }
+ }
+
+ if (sel) { /* U ! */
+ /* Inserting U points is sort of 'default' Flat curves only get */
+ /* U points inserted in them. */
+ bpn = bpnew = MEM_mallocN((sel + nu->pntsu) * nu->pntsv * sizeof(BPoint),
+ "subdivideNurb4");
+ bp = nu->bp;
+ for (a = 0; a < nu->pntsv; a++) {
+ for (b = 0; b < nu->pntsu; b++) {
+ *bpn = *bp;
+ keyIndex_updateBP(editnurb, bp, bpn, 1);
+ bpn++;
+ bp++;
+ if ((b < nu->pntsu - 1) && usel[b] == nu->pntsv && usel[b + 1] == nu->pntsv) {
+ /*
+ * One thing that bugs me here is that the
+ * orders of things are not the same as in
+ * the JW piece. Also, this implies that we
+ * handle at most 3rd order curves? I miss
+ * some symmetry here...
+ */
+ for (i = 0; i < number_cuts; i++) {
+ factor = (float)(i + 1) / (number_cuts + 1);
+ prevbp = bp - 1;
+ *bpn = *prevbp;
+ interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor);
+ bpn++;
+ }
+ }
+ }
+ }
+ MEM_freeN(nu->bp);
+ nu->bp = bpnew;
+ nu->pntsu += sel;
+ BKE_nurb_knot_calc_u(nu); /* shift knots forward */
+ }
+ }
+ }
+ MEM_freeN(usel);
+ MEM_freeN(vsel);
+
+ } /* End of 'if (nu->type == CU_NURBS)' */
+ }
}
static int subdivide_exec(bContext *C, wmOperator *op)
{
- const int number_cuts = RNA_int_get(op->ptr, "number_cuts");
+ const int number_cuts = RNA_int_get(op->ptr, "number_cuts");
- Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
+ Main *bmain = CTX_data_main(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
- subdividenurb(obedit, v3d, number_cuts);
+ subdividenurb(obedit, v3d, number_cuts);
- if (ED_curve_updateAnimPaths(bmain, cu)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
+ if (ED_curve_updateAnimPaths(bmain, cu)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, cu);
- DEG_id_tag_update(obedit->data, 0);
- }
- MEM_freeN(objects);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, cu);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void CURVE_OT_subdivide(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Subdivide";
- ot->description = "Subdivide selected segments";
- ot->idname = "CURVE_OT_subdivide";
+ /* identifiers */
+ ot->name = "Subdivide";
+ ot->description = "Subdivide selected segments";
+ ot->idname = "CURVE_OT_subdivide";
- /* api callbacks */
- ot->exec = subdivide_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = subdivide_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, 1000, "Number of cuts", "", 1, 10);
- /* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, 1000, "Number of cuts", "", 1, 10);
+ /* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/******************** find nearest ************************/
-static void ED_curve_pick_vert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
-{
- struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; bool is_changed; } *data = userData;
-
- short flag;
- float dist_test;
-
- if (bp) {
- flag = bp->f1;
- }
- else {
- 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;
- }
-}
-
-bool ED_curve_pick_vert(
- ViewContext *vc, short sel,
- Nurb **r_nurb, BezTriple **r_bezt, BPoint **r_bp, short *r_handle,
- Base **r_base)
-{
- /* (sel == 1): selected gets a disadvantage */
- /* in nurb and bezt or bp the nearest is written */
- /* return 0 1 2: handlepunt */
- struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; bool is_changed; } data = {NULL};
-
- data.dist = ED_view3d_select_dist_px();
- data.hpoint = 0;
- data.select = sel;
- data.mval_fl[0] = vc->mval[0];
- data.mval_fl[1] = vc->mval[1];
-
- uint bases_len;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(vc->view_layer, vc->v3d, &bases_len);
- for (uint base_index = 0; base_index < bases_len; base_index++) {
- Base *base = bases[base_index];
- data.is_changed = false;
-
- ED_view3d_viewcontext_init_object(vc, base->object);
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- nurbs_foreachScreenVert(vc, ED_curve_pick_vert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
-
- if (r_base && data.is_changed) {
- *r_base = base;
- }
- }
- MEM_freeN(bases);
-
- *r_nurb = data.nurb;
- *r_bezt = data.bezt;
- *r_bp = data.bp;
-
- if (r_handle) {
- *r_handle = data.hpoint;
- }
-
- return (data.bezt || data.bp);
+static void ED_curve_pick_vert__doClosest(
+ void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
+{
+ struct {
+ BPoint *bp;
+ BezTriple *bezt;
+ Nurb *nurb;
+ float dist;
+ int hpoint, select;
+ float mval_fl[2];
+ bool is_changed;
+ } *data = userData;
+
+ short flag;
+ float dist_test;
+
+ if (bp) {
+ flag = bp->f1;
+ }
+ else {
+ 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;
+ }
+}
+
+bool ED_curve_pick_vert(ViewContext *vc,
+ short sel,
+ Nurb **r_nurb,
+ BezTriple **r_bezt,
+ BPoint **r_bp,
+ short *r_handle,
+ Base **r_base)
+{
+ /* (sel == 1): selected gets a disadvantage */
+ /* in nurb and bezt or bp the nearest is written */
+ /* return 0 1 2: handlepunt */
+ struct {
+ BPoint *bp;
+ BezTriple *bezt;
+ Nurb *nurb;
+ float dist;
+ int hpoint, select;
+ float mval_fl[2];
+ bool is_changed;
+ } data = {NULL};
+
+ data.dist = ED_view3d_select_dist_px();
+ data.hpoint = 0;
+ data.select = sel;
+ data.mval_fl[0] = vc->mval[0];
+ data.mval_fl[1] = vc->mval[1];
+
+ uint bases_len;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
+ vc->view_layer, vc->v3d, &bases_len);
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Base *base = bases[base_index];
+ data.is_changed = false;
+
+ ED_view3d_viewcontext_init_object(vc, base->object);
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ nurbs_foreachScreenVert(vc, ED_curve_pick_vert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+
+ if (r_base && data.is_changed) {
+ *r_base = base;
+ }
+ }
+ MEM_freeN(bases);
+
+ *r_nurb = data.nurb;
+ *r_bezt = data.bezt;
+ *r_bp = data.bp;
+
+ if (r_handle) {
+ *r_handle = data.hpoint;
+ }
+
+ return (data.bezt || data.bp);
}
static void findselectedNurbvert(
- 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 */
- ListBase *editnurb = &cu->editnurb->nurbs;
- Nurb *nu1;
- BezTriple *bezt1;
- BPoint *bp1;
- int a;
-
- *r_nu = NULL;
- *r_bezt = NULL;
- *r_bp = NULL;
-
- for (nu1 = editnurb->first; nu1; nu1 = nu1->next) {
- if (nu1->type == CU_BEZIER) {
- bezt1 = nu1->bezt;
- a = nu1->pntsu;
- while (a--) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1)) {
- if (*r_nu != NULL && *r_nu != nu1) {
- *r_nu = NULL;
- *r_bp = NULL;
- *r_bezt = NULL;
- return;
- }
- else if (*r_bezt || *r_bp) {
- *r_bp = NULL;
- *r_bezt = NULL;
- }
- else {
- *r_bezt = bezt1;
- *r_nu = nu1;
- }
- }
- bezt1++;
- }
- }
- else {
- bp1 = nu1->bp;
- a = nu1->pntsu * nu1->pntsv;
- while (a--) {
- if (bp1->f1 & SELECT) {
- if (*r_nu != NULL && *r_nu != nu1) {
- *r_bp = NULL;
- *r_bezt = NULL;
- *r_nu = NULL;
- return;
- }
- else if (*r_bezt || *r_bp) {
- *r_bp = NULL;
- *r_bezt = NULL;
- }
- else {
- *r_bp = bp1;
- *r_nu = nu1;
- }
- }
- bp1++;
- }
- }
- }
+ 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 */
+ ListBase *editnurb = &cu->editnurb->nurbs;
+ Nurb *nu1;
+ BezTriple *bezt1;
+ BPoint *bp1;
+ int a;
+
+ *r_nu = NULL;
+ *r_bezt = NULL;
+ *r_bp = NULL;
+
+ for (nu1 = editnurb->first; nu1; nu1 = nu1->next) {
+ if (nu1->type == CU_BEZIER) {
+ bezt1 = nu1->bezt;
+ a = nu1->pntsu;
+ while (a--) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1)) {
+ if (*r_nu != NULL && *r_nu != nu1) {
+ *r_nu = NULL;
+ *r_bp = NULL;
+ *r_bezt = NULL;
+ return;
+ }
+ else if (*r_bezt || *r_bp) {
+ *r_bp = NULL;
+ *r_bezt = NULL;
+ }
+ else {
+ *r_bezt = bezt1;
+ *r_nu = nu1;
+ }
+ }
+ bezt1++;
+ }
+ }
+ else {
+ bp1 = nu1->bp;
+ a = nu1->pntsu * nu1->pntsv;
+ while (a--) {
+ if (bp1->f1 & SELECT) {
+ if (*r_nu != NULL && *r_nu != nu1) {
+ *r_bp = NULL;
+ *r_bezt = NULL;
+ *r_nu = NULL;
+ return;
+ }
+ else if (*r_bezt || *r_bp) {
+ *r_bp = NULL;
+ *r_bezt = NULL;
+ }
+ else {
+ *r_bp = bp1;
+ *r_nu = nu1;
+ }
+ }
+ bp1++;
+ }
+ }
+ }
}
/***************** set spline type operator *******************/
static int set_spline_type_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- Object *obedit = CTX_data_edit_object(C);
- View3D *v3d = CTX_wm_view3d(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- bool changed = false;
- bool changed_size = false;
- const bool use_handles = RNA_boolean_get(op->ptr, "use_handles");
- const int type = RNA_enum_get(op->ptr, "type");
-
- if (type == CU_CARDINAL || type == CU_BSPLINE) {
- BKE_report(op->reports, RPT_ERROR, "Not yet implemented");
- return OPERATOR_CANCELLED;
- }
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (ED_curve_nurb_select_check(v3d, nu)) {
- const int pntsu_prev = nu->pntsu;
- if (BKE_nurb_type_convert(nu, type, use_handles)) {
- changed = true;
- if (pntsu_prev != nu->pntsu) {
- changed_size = true;
- }
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "No conversion possible");
- }
- }
- }
-
- if (changed) {
- if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
-
- DEG_id_tag_update(obedit->data, 0);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
-
- if (changed_size) {
- Curve *cu = obedit->data;
- cu->actvert = CU_ACT_NONE;
- }
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ Main *bmain = CTX_data_main(C);
+ Object *obedit = CTX_data_edit_object(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ bool changed = false;
+ bool changed_size = false;
+ const bool use_handles = RNA_boolean_get(op->ptr, "use_handles");
+ const int type = RNA_enum_get(op->ptr, "type");
+
+ if (type == CU_CARDINAL || type == CU_BSPLINE) {
+ BKE_report(op->reports, RPT_ERROR, "Not yet implemented");
+ return OPERATOR_CANCELLED;
+ }
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+ const int pntsu_prev = nu->pntsu;
+ if (BKE_nurb_type_convert(nu, type, use_handles)) {
+ changed = true;
+ if (pntsu_prev != nu->pntsu) {
+ changed_size = true;
+ }
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "No conversion possible");
+ }
+ }
+ }
+
+ if (changed) {
+ if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
+
+ DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+
+ if (changed_size) {
+ Curve *cu = obedit->data;
+ cu->actvert = CU_ACT_NONE;
+ }
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void CURVE_OT_spline_type_set(wmOperatorType *ot)
{
- static const EnumPropertyItem type_items[] = {
- {CU_POLY, "POLY", 0, "Poly", ""},
- {CU_BEZIER, "BEZIER", 0, "Bezier", ""},
-// {CU_CARDINAL, "CARDINAL", 0, "Cardinal", ""},
-// {CU_BSPLINE, "B_SPLINE", 0, "B-Spline", ""},
- {CU_NURBS, "NURBS", 0, "NURBS", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
- /* identifiers */
- ot->name = "Set Spline Type";
- ot->description = "Set type of active spline";
- ot->idname = "CURVE_OT_spline_type_set";
-
- /* api callbacks */
- ot->exec = set_spline_type_exec;
- ot->invoke = WM_menu_invoke;
- ot->poll = ED_operator_editcurve;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", type_items, CU_POLY, "Type", "Spline type");
- RNA_def_boolean(ot->srna, "use_handles", 0, "Handles", "Use handles when converting bezier curves into polygons");
+ static const EnumPropertyItem type_items[] = {
+ {CU_POLY, "POLY", 0, "Poly", ""},
+ {CU_BEZIER, "BEZIER", 0, "Bezier", ""},
+ // {CU_CARDINAL, "CARDINAL", 0, "Cardinal", ""},
+ // {CU_BSPLINE, "B_SPLINE", 0, "B-Spline", ""},
+ {CU_NURBS, "NURBS", 0, "NURBS", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* identifiers */
+ ot->name = "Set Spline Type";
+ ot->description = "Set type of active spline";
+ ot->idname = "CURVE_OT_spline_type_set";
+
+ /* api callbacks */
+ ot->exec = set_spline_type_exec;
+ ot->invoke = WM_menu_invoke;
+ ot->poll = ED_operator_editcurve;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "type", type_items, CU_POLY, "Type", "Spline type");
+ RNA_def_boolean(ot->srna,
+ "use_handles",
+ 0,
+ "Handles",
+ "Use handles when converting bezier curves into polygons");
}
/***************** set handle type operator *******************/
static int set_handle_type_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- const int handle_type = RNA_enum_get(op->ptr, "type");
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ const int handle_type = RNA_enum_get(op->ptr, "type");
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
- ListBase *editnurb = object_editcurve_get(obedit);
- BKE_nurbList_handles_set(editnurb, handle_type);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ BKE_nurbList_handles_set(editnurb, handle_type);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_handle_type_set(wmOperatorType *ot)
{
- /* keep in sync with graphkeys_handle_type_items */
- static const EnumPropertyItem editcurve_handle_type_items[] = {
- {HD_AUTO, "AUTOMATIC", 0, "Automatic", ""},
- {HD_VECT, "VECTOR", 0, "Vector", ""},
- {5, "ALIGNED", 0, "Aligned", ""},
- {6, "FREE_ALIGN", 0, "Free", ""},
- {3, "TOGGLE_FREE_ALIGN", 0, "Toggle Free/Align", ""},
- {0, NULL, 0, NULL, NULL},
- };
+ /* keep in sync with graphkeys_handle_type_items */
+ static const EnumPropertyItem editcurve_handle_type_items[] = {
+ {HD_AUTO, "AUTOMATIC", 0, "Automatic", ""},
+ {HD_VECT, "VECTOR", 0, "Vector", ""},
+ {5, "ALIGNED", 0, "Aligned", ""},
+ {6, "FREE_ALIGN", 0, "Free", ""},
+ {3, "TOGGLE_FREE_ALIGN", 0, "Toggle Free/Align", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
- /* identifiers */
- ot->name = "Set Handle Type";
- ot->description = "Set type of handles for selected control points";
- ot->idname = "CURVE_OT_handle_type_set";
+ /* identifiers */
+ ot->name = "Set Handle Type";
+ ot->description = "Set type of handles for selected control points";
+ ot->idname = "CURVE_OT_handle_type_set";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = set_handle_type_exec;
- ot->poll = ED_operator_editcurve;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = set_handle_type_exec;
+ ot->poll = ED_operator_editcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", editcurve_handle_type_items, 1, "Type", "Spline type");
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "type", editcurve_handle_type_items, 1, "Type", "Spline type");
}
/***************** recalculate handles operator **********************/
static int curve_normals_make_consistent_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
- const bool calc_length = RNA_boolean_get(op->ptr, "calc_length");
+ const bool calc_length = RNA_boolean_get(op->ptr, "calc_length");
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
- ListBase *editnurb = object_editcurve_get(obedit);
- BKE_nurbList_handles_recalculate(editnurb, calc_length, SELECT);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ BKE_nurbList_handles_recalculate(editnurb, calc_length, SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_normals_make_consistent(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Recalc Normals";
- ot->description = "Recalculate the direction of selected handles";
- ot->idname = "CURVE_OT_normals_make_consistent";
+ /* identifiers */
+ ot->name = "Recalc Normals";
+ ot->description = "Recalculate the direction of selected handles";
+ ot->idname = "CURVE_OT_normals_make_consistent";
- /* api callbacks */
- ot->exec = curve_normals_make_consistent_exec;
- ot->poll = ED_operator_editcurve;
+ /* api callbacks */
+ ot->exec = curve_normals_make_consistent_exec;
+ ot->poll = ED_operator_editcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- RNA_def_boolean(ot->srna, "calc_length", false, "Length", "Recalculate handle length");
+ /* props */
+ RNA_def_boolean(ot->srna, "calc_length", false, "Length", "Recalculate handle length");
}
/***************** make segment operator **********************/
@@ -4026,94 +4099,94 @@ void CURVE_OT_normals_make_consistent(wmOperatorType *ot)
static void switchdirection_knots(float *base, int tot)
{
- float *fp1, *fp2, *tempf;
- int a;
-
- if (base == NULL || tot == 0) {
- return;
- }
-
- /* reverse knots */
- a = tot;
- fp1 = base;
- fp2 = fp1 + (a - 1);
- a /= 2;
- while (fp1 != fp2 && a > 0) {
- SWAP(float, *fp1, *fp2);
- a--;
- fp1++;
- fp2--;
- }
-
- /* and make in increasing order again */
- a = tot - 1;
- fp1 = base;
- fp2 = tempf = MEM_mallocN(sizeof(float) * tot, "switchdirect");
- while (a--) {
- fp2[0] = fabsf(fp1[1] - fp1[0]);
- fp1++;
- fp2++;
- }
- fp2[0] = 0.0f;
-
- a = tot - 1;
- fp1 = base;
- fp2 = tempf;
- fp1[0] = 0.0;
- fp1++;
- while (a--) {
- fp1[0] = fp1[-1] + fp2[0];
- fp1++;
- fp2++;
- }
- MEM_freeN(tempf);
+ float *fp1, *fp2, *tempf;
+ int a;
+
+ if (base == NULL || tot == 0) {
+ return;
+ }
+
+ /* reverse knots */
+ a = tot;
+ fp1 = base;
+ fp2 = fp1 + (a - 1);
+ a /= 2;
+ while (fp1 != fp2 && a > 0) {
+ SWAP(float, *fp1, *fp2);
+ a--;
+ fp1++;
+ fp2--;
+ }
+
+ /* and make in increasing order again */
+ a = tot - 1;
+ fp1 = base;
+ fp2 = tempf = MEM_mallocN(sizeof(float) * tot, "switchdirect");
+ while (a--) {
+ fp2[0] = fabsf(fp1[1] - fp1[0]);
+ fp1++;
+ fp2++;
+ }
+ fp2[0] = 0.0f;
+
+ a = tot - 1;
+ fp1 = base;
+ fp2 = tempf;
+ fp1[0] = 0.0;
+ fp1++;
+ while (a--) {
+ fp1[0] = fp1[-1] + fp2[0];
+ fp1++;
+ fp2++;
+ }
+ MEM_freeN(tempf);
}
static void rotate_direction_nurb(Nurb *nu)
{
- BPoint *bp1, *bp2, *temp;
- int u, v;
+ BPoint *bp1, *bp2, *temp;
+ int u, v;
- SWAP(int, nu->pntsu, nu->pntsv);
- SWAP(short, nu->orderu, nu->orderv);
- SWAP(short, nu->resolu, nu->resolv);
- SWAP(short, nu->flagu, nu->flagv);
+ SWAP(int, nu->pntsu, nu->pntsv);
+ SWAP(short, nu->orderu, nu->orderv);
+ SWAP(short, nu->resolu, nu->resolv);
+ SWAP(short, nu->flagu, nu->flagv);
- SWAP(float *, nu->knotsu, nu->knotsv);
- switchdirection_knots(nu->knotsv, KNOTSV(nu));
+ SWAP(float *, nu->knotsu, nu->knotsv);
+ switchdirection_knots(nu->knotsv, KNOTSV(nu));
- temp = MEM_dupallocN(nu->bp);
- bp1 = nu->bp;
- for (v = 0; v < nu->pntsv; v++) {
- for (u = 0; u < nu->pntsu; u++, bp1++) {
- bp2 = temp + (nu->pntsu - u - 1) * (nu->pntsv) + v;
- *bp1 = *bp2;
- }
- }
+ temp = MEM_dupallocN(nu->bp);
+ bp1 = nu->bp;
+ for (v = 0; v < nu->pntsv; v++) {
+ for (u = 0; u < nu->pntsu; u++, bp1++) {
+ bp2 = temp + (nu->pntsu - u - 1) * (nu->pntsv) + v;
+ *bp1 = *bp2;
+ }
+ }
- MEM_freeN(temp);
+ MEM_freeN(temp);
}
static bool is_u_selected(Nurb *nu, int u)
{
- BPoint *bp;
- int v;
+ BPoint *bp;
+ int v;
- /* what about resolu == 2? */
- bp = &nu->bp[u];
- for (v = 0; v < nu->pntsv - 1; v++, bp += nu->pntsu) {
- if ((v != 0) && (bp->f1 & SELECT)) {
- return true;
- }
- }
+ /* what about resolu == 2? */
+ bp = &nu->bp[u];
+ for (v = 0; v < nu->pntsv - 1; v++, bp += nu->pntsu) {
+ if ((v != 0) && (bp->f1 & SELECT)) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
typedef struct NurbSort {
- struct NurbSort *next, *prev;
- Nurb *nu;
- float vec[3];
+ struct NurbSort *next, *prev;
+ Nurb *nu;
+ float vec[3];
} NurbSort;
static ListBase nsortbase = {NULL, NULL};
@@ -4121,2837 +4194,2877 @@ static ListBase nsortbase = {NULL, NULL};
static void make_selection_list_nurb(View3D *v3d, ListBase *editnurb)
{
- ListBase nbase = {NULL, NULL};
- NurbSort *nus, *nustest, *headdo, *taildo;
- Nurb *nu;
- BPoint *bp;
- float dist, headdist, taildist;
- int a;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (ED_curve_nurb_select_check(v3d, nu)) {
-
- nus = (NurbSort *)MEM_callocN(sizeof(NurbSort), "sort");
- BLI_addhead(&nbase, nus);
- nus->nu = nu;
-
- bp = nu->bp;
- a = nu->pntsu;
- while (a--) {
- add_v3_v3(nus->vec, bp->vec);
- bp++;
- }
- mul_v3_fl(nus->vec, 1.0f / (float)nu->pntsu);
-
-
- }
- }
-
- /* just add the first one */
- nus = nbase.first;
- BLI_remlink(&nbase, nus);
- BLI_addtail(&nsortbase, nus);
-
- /* now add, either at head or tail, the closest one */
- while (nbase.first) {
-
- headdist = taildist = 1.0e30;
- headdo = taildo = NULL;
-
- nustest = nbase.first;
- while (nustest) {
- dist = len_v3v3(nustest->vec, ((NurbSort *)nsortbase.first)->vec);
-
- if (dist < headdist) {
- headdist = dist;
- headdo = nustest;
- }
- dist = len_v3v3(nustest->vec, ((NurbSort *)nsortbase.last)->vec);
-
- if (dist < taildist) {
- taildist = dist;
- taildo = nustest;
- }
- nustest = nustest->next;
- }
-
- if (headdist < taildist) {
- BLI_remlink(&nbase, headdo);
- BLI_addhead(&nsortbase, headdo);
- }
- else {
- BLI_remlink(&nbase, taildo);
- BLI_addtail(&nsortbase, taildo);
- }
- }
+ ListBase nbase = {NULL, NULL};
+ NurbSort *nus, *nustest, *headdo, *taildo;
+ Nurb *nu;
+ BPoint *bp;
+ float dist, headdist, taildist;
+ int a;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+
+ nus = (NurbSort *)MEM_callocN(sizeof(NurbSort), "sort");
+ BLI_addhead(&nbase, nus);
+ nus->nu = nu;
+
+ bp = nu->bp;
+ a = nu->pntsu;
+ while (a--) {
+ add_v3_v3(nus->vec, bp->vec);
+ bp++;
+ }
+ mul_v3_fl(nus->vec, 1.0f / (float)nu->pntsu);
+ }
+ }
+
+ /* just add the first one */
+ nus = nbase.first;
+ BLI_remlink(&nbase, nus);
+ BLI_addtail(&nsortbase, nus);
+
+ /* now add, either at head or tail, the closest one */
+ while (nbase.first) {
+
+ headdist = taildist = 1.0e30;
+ headdo = taildo = NULL;
+
+ nustest = nbase.first;
+ while (nustest) {
+ dist = len_v3v3(nustest->vec, ((NurbSort *)nsortbase.first)->vec);
+
+ if (dist < headdist) {
+ headdist = dist;
+ headdo = nustest;
+ }
+ dist = len_v3v3(nustest->vec, ((NurbSort *)nsortbase.last)->vec);
+
+ if (dist < taildist) {
+ taildist = dist;
+ taildo = nustest;
+ }
+ nustest = nustest->next;
+ }
+
+ if (headdist < taildist) {
+ BLI_remlink(&nbase, headdo);
+ BLI_addhead(&nsortbase, headdo);
+ }
+ else {
+ BLI_remlink(&nbase, taildo);
+ BLI_addtail(&nsortbase, taildo);
+ }
+ }
}
enum {
- CURVE_MERGE_OK = 0,
- CURVE_MERGE_ERR_FEW_SELECTION,
- CURVE_MERGE_ERR_RESOLUTION_ALL,
- CURVE_MERGE_ERR_RESOLUTION_SOME,
+ CURVE_MERGE_OK = 0,
+ CURVE_MERGE_ERR_FEW_SELECTION,
+ CURVE_MERGE_ERR_RESOLUTION_ALL,
+ CURVE_MERGE_ERR_RESOLUTION_SOME,
};
static bool merge_2_nurb(Curve *cu, ListBase *editnurb, Nurb *nu1, Nurb *nu2)
{
- BPoint *bp, *bp1, *bp2, *temp;
- float len1, len2;
- int origu, u, v;
-
- /* first nurbs will be changed to make u = resolu-1 selected */
- /* 2nd nurbs will be changed to make u = 0 selected */
-
- /* first nurbs: u = resolu-1 selected */
-
- if (is_u_selected(nu1, nu1->pntsu - 1)) {
- /* pass */
- }
- else {
- /* For 2D curves blender uses (orderv = 0). It doesn't make any sense mathematically. */
- /* but after rotating (orderu = 0) will be confusing. */
- if (nu1->orderv == 0) {
- nu1->orderv = 1;
- }
-
- rotate_direction_nurb(nu1);
- if (is_u_selected(nu1, nu1->pntsu - 1)) {
- /* pass */
- }
- else {
- rotate_direction_nurb(nu1);
- if (is_u_selected(nu1, nu1->pntsu - 1)) {
- /* pass */
- }
- else {
- rotate_direction_nurb(nu1);
- if (is_u_selected(nu1, nu1->pntsu - 1)) {
- /* pass */
- }
- else {
- /* rotate again, now its OK! */
- if (nu1->pntsv != 1) {
- rotate_direction_nurb(nu1);
- }
- return true;
- }
- }
- }
- }
-
- /* 2nd nurbs: u = 0 selected */
- if (is_u_selected(nu2, 0)) {
- /* pass */
- }
- else {
- if (nu2->orderv == 0) {
- nu2->orderv = 1;
- }
- rotate_direction_nurb(nu2);
- if (is_u_selected(nu2, 0)) {
- /* pass */
- }
- else {
- rotate_direction_nurb(nu2);
- if (is_u_selected(nu2, 0)) {
- /* pass */
- }
- else {
- rotate_direction_nurb(nu2);
- if (is_u_selected(nu2, 0)) {
- /* pass */
- }
- else {
- /* rotate again, now its OK! */
- if (nu1->pntsu == 1) {
- rotate_direction_nurb(nu1);
- }
- if (nu2->pntsv != 1) {
- rotate_direction_nurb(nu2);
- }
- return true;
- }
- }
- }
- }
-
- if (nu1->pntsv != nu2->pntsv) {
- return false;
- }
-
- /* ok, now nu1 has the rightmost column and nu2 the leftmost column selected */
- /* maybe we need a 'v' flip of nu2? */
-
- bp1 = &nu1->bp[nu1->pntsu - 1];
- bp2 = nu2->bp;
- len1 = 0.0;
-
- for (v = 0; v < nu1->pntsv; v++, bp1 += nu1->pntsu, bp2 += nu2->pntsu) {
- len1 += len_v3v3(bp1->vec, bp2->vec);
- }
-
- bp1 = &nu1->bp[nu1->pntsu - 1];
- bp2 = &nu2->bp[nu2->pntsu * (nu2->pntsv - 1)];
- len2 = 0.0;
-
- for (v = 0; v < nu1->pntsv; v++, bp1 += nu1->pntsu, bp2 -= nu2->pntsu) {
- len2 += len_v3v3(bp1->vec, bp2->vec);
- }
-
- /* merge */
- origu = nu1->pntsu;
- nu1->pntsu += nu2->pntsu;
- if (nu1->orderu < 3 && nu1->orderu < nu1->pntsu) {
- nu1->orderu++;
- }
- if (nu1->orderv < 3 && nu1->orderv < nu1->pntsv) {
- nu1->orderv++;
- }
- temp = nu1->bp;
- nu1->bp = MEM_mallocN(nu1->pntsu * nu1->pntsv * sizeof(BPoint), "mergeBP");
-
- bp = nu1->bp;
- bp1 = temp;
-
- for (v = 0; v < nu1->pntsv; v++) {
-
- /* switch direction? */
- if (len1 < len2) {
- bp2 = &nu2->bp[v * nu2->pntsu];
- }
- else {
- bp2 = &nu2->bp[(nu1->pntsv - v - 1) * nu2->pntsu];
- }
-
- for (u = 0; u < nu1->pntsu; u++, bp++) {
- if (u < origu) {
- keyIndex_updateBP(cu->editnurb, bp1, bp, 1);
- *bp = *bp1; bp1++;
- select_bpoint(bp, SELECT, SELECT, HIDDEN);
- }
- else {
- keyIndex_updateBP(cu->editnurb, bp2, bp, 1);
- *bp = *bp2; bp2++;
- }
- }
- }
-
- if (nu1->type == CU_NURBS) {
- /* merge knots */
- BKE_nurb_knot_calc_u(nu1);
-
- /* make knots, for merged curved for example */
- BKE_nurb_knot_calc_v(nu1);
- }
-
- MEM_freeN(temp);
- BLI_remlink(editnurb, nu2);
- BKE_nurb_free(nu2);
- return true;
+ BPoint *bp, *bp1, *bp2, *temp;
+ float len1, len2;
+ int origu, u, v;
+
+ /* first nurbs will be changed to make u = resolu-1 selected */
+ /* 2nd nurbs will be changed to make u = 0 selected */
+
+ /* first nurbs: u = resolu-1 selected */
+
+ if (is_u_selected(nu1, nu1->pntsu - 1)) {
+ /* pass */
+ }
+ else {
+ /* For 2D curves blender uses (orderv = 0). It doesn't make any sense mathematically. */
+ /* but after rotating (orderu = 0) will be confusing. */
+ if (nu1->orderv == 0) {
+ nu1->orderv = 1;
+ }
+
+ rotate_direction_nurb(nu1);
+ if (is_u_selected(nu1, nu1->pntsu - 1)) {
+ /* pass */
+ }
+ else {
+ rotate_direction_nurb(nu1);
+ if (is_u_selected(nu1, nu1->pntsu - 1)) {
+ /* pass */
+ }
+ else {
+ rotate_direction_nurb(nu1);
+ if (is_u_selected(nu1, nu1->pntsu - 1)) {
+ /* pass */
+ }
+ else {
+ /* rotate again, now its OK! */
+ if (nu1->pntsv != 1) {
+ rotate_direction_nurb(nu1);
+ }
+ return true;
+ }
+ }
+ }
+ }
+
+ /* 2nd nurbs: u = 0 selected */
+ if (is_u_selected(nu2, 0)) {
+ /* pass */
+ }
+ else {
+ if (nu2->orderv == 0) {
+ nu2->orderv = 1;
+ }
+ rotate_direction_nurb(nu2);
+ if (is_u_selected(nu2, 0)) {
+ /* pass */
+ }
+ else {
+ rotate_direction_nurb(nu2);
+ if (is_u_selected(nu2, 0)) {
+ /* pass */
+ }
+ else {
+ rotate_direction_nurb(nu2);
+ if (is_u_selected(nu2, 0)) {
+ /* pass */
+ }
+ else {
+ /* rotate again, now its OK! */
+ if (nu1->pntsu == 1) {
+ rotate_direction_nurb(nu1);
+ }
+ if (nu2->pntsv != 1) {
+ rotate_direction_nurb(nu2);
+ }
+ return true;
+ }
+ }
+ }
+ }
+
+ if (nu1->pntsv != nu2->pntsv) {
+ return false;
+ }
+
+ /* ok, now nu1 has the rightmost column and nu2 the leftmost column selected */
+ /* maybe we need a 'v' flip of nu2? */
+
+ bp1 = &nu1->bp[nu1->pntsu - 1];
+ bp2 = nu2->bp;
+ len1 = 0.0;
+
+ for (v = 0; v < nu1->pntsv; v++, bp1 += nu1->pntsu, bp2 += nu2->pntsu) {
+ len1 += len_v3v3(bp1->vec, bp2->vec);
+ }
+
+ bp1 = &nu1->bp[nu1->pntsu - 1];
+ bp2 = &nu2->bp[nu2->pntsu * (nu2->pntsv - 1)];
+ len2 = 0.0;
+
+ for (v = 0; v < nu1->pntsv; v++, bp1 += nu1->pntsu, bp2 -= nu2->pntsu) {
+ len2 += len_v3v3(bp1->vec, bp2->vec);
+ }
+
+ /* merge */
+ origu = nu1->pntsu;
+ nu1->pntsu += nu2->pntsu;
+ if (nu1->orderu < 3 && nu1->orderu < nu1->pntsu) {
+ nu1->orderu++;
+ }
+ if (nu1->orderv < 3 && nu1->orderv < nu1->pntsv) {
+ nu1->orderv++;
+ }
+ temp = nu1->bp;
+ nu1->bp = MEM_mallocN(nu1->pntsu * nu1->pntsv * sizeof(BPoint), "mergeBP");
+
+ bp = nu1->bp;
+ bp1 = temp;
+
+ for (v = 0; v < nu1->pntsv; v++) {
+
+ /* switch direction? */
+ if (len1 < len2) {
+ bp2 = &nu2->bp[v * nu2->pntsu];
+ }
+ else {
+ bp2 = &nu2->bp[(nu1->pntsv - v - 1) * nu2->pntsu];
+ }
+
+ for (u = 0; u < nu1->pntsu; u++, bp++) {
+ if (u < origu) {
+ keyIndex_updateBP(cu->editnurb, bp1, bp, 1);
+ *bp = *bp1;
+ bp1++;
+ select_bpoint(bp, SELECT, SELECT, HIDDEN);
+ }
+ else {
+ keyIndex_updateBP(cu->editnurb, bp2, bp, 1);
+ *bp = *bp2;
+ bp2++;
+ }
+ }
+ }
+
+ if (nu1->type == CU_NURBS) {
+ /* merge knots */
+ BKE_nurb_knot_calc_u(nu1);
+
+ /* make knots, for merged curved for example */
+ BKE_nurb_knot_calc_v(nu1);
+ }
+
+ MEM_freeN(temp);
+ BLI_remlink(editnurb, nu2);
+ BKE_nurb_free(nu2);
+ return true;
}
static int merge_nurb(View3D *v3d, Object *obedit)
{
- Curve *cu = obedit->data;
- ListBase *editnurb = object_editcurve_get(obedit);
- NurbSort *nus1, *nus2;
- bool ok = true;
-
- make_selection_list_nurb(v3d, editnurb);
-
- if (nsortbase.first == nsortbase.last) {
- BLI_freelistN(&nsortbase);
- return CURVE_MERGE_ERR_FEW_SELECTION;
- }
-
- nus1 = nsortbase.first;
- nus2 = nus1->next;
-
- /* resolution match, to avoid uv rotations */
- if (nus1->nu->pntsv == 1) {
- if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) {
- /* pass */
- }
- else {
- ok = false;
- }
- }
- else if (nus2->nu->pntsv == 1) {
- if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) {
- /* pass */
- }
- else {
- ok = false;
- }
- }
- else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) {
- /* pass */
- }
- else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) {
- /* pass */
- }
- else {
- ok = false;
- }
-
- if (ok == false) {
- BLI_freelistN(&nsortbase);
- return CURVE_MERGE_ERR_RESOLUTION_ALL;
- }
-
- while (nus2) {
- /* There is a change a few curves merged properly, but not all.
- * In this case we still update the curve, yet report the error. */
- ok &= merge_2_nurb(cu, editnurb, nus1->nu, nus2->nu);
- nus2 = nus2->next;
- }
-
- BLI_freelistN(&nsortbase);
- BKE_curve_nurb_active_set(obedit->data, NULL);
-
- return ok ? CURVE_MERGE_OK : CURVE_MERGE_ERR_RESOLUTION_SOME;
+ Curve *cu = obedit->data;
+ ListBase *editnurb = object_editcurve_get(obedit);
+ NurbSort *nus1, *nus2;
+ bool ok = true;
+
+ make_selection_list_nurb(v3d, editnurb);
+
+ if (nsortbase.first == nsortbase.last) {
+ BLI_freelistN(&nsortbase);
+ return CURVE_MERGE_ERR_FEW_SELECTION;
+ }
+
+ nus1 = nsortbase.first;
+ nus2 = nus1->next;
+
+ /* resolution match, to avoid uv rotations */
+ if (nus1->nu->pntsv == 1) {
+ if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) {
+ /* pass */
+ }
+ else {
+ ok = false;
+ }
+ }
+ else if (nus2->nu->pntsv == 1) {
+ if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) {
+ /* pass */
+ }
+ else {
+ ok = false;
+ }
+ }
+ else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) {
+ /* pass */
+ }
+ else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) {
+ /* pass */
+ }
+ else {
+ ok = false;
+ }
+
+ if (ok == false) {
+ BLI_freelistN(&nsortbase);
+ return CURVE_MERGE_ERR_RESOLUTION_ALL;
+ }
+
+ while (nus2) {
+ /* There is a change a few curves merged properly, but not all.
+ * In this case we still update the curve, yet report the error. */
+ ok &= merge_2_nurb(cu, editnurb, nus1->nu, nus2->nu);
+ nus2 = nus2->next;
+ }
+
+ BLI_freelistN(&nsortbase);
+ BKE_curve_nurb_active_set(obedit->data, NULL);
+
+ return ok ? CURVE_MERGE_OK : CURVE_MERGE_ERR_RESOLUTION_SOME;
}
static int make_segment_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- struct {
- int changed;
- int unselected;
- int error_selected_few;
- int error_resolution;
- int error_generic;
- } status = {0};
-
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
-
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- status.unselected++;
- continue;
- }
-
- ListBase *nubase = object_editcurve_get(obedit);
- Nurb *nu, *nu1 = NULL, *nu2 = NULL;
- BPoint *bp;
- bool ok = false;
-
- /* first decide if this is a surface merge! */
- if (obedit->type == OB_SURF) {
- nu = nubase->first;
- }
- else {
- nu = NULL;
- }
-
- while (nu) {
- const int nu_select_num = ED_curve_nurb_select_count(v3d, nu);
- if (nu_select_num) {
-
- if (nu->pntsu > 1 && nu->pntsv > 1) {
- break;
- }
-
- if (nu_select_num > 1) {
- break;
- }
- else {
- /* only 1 selected, not first or last, a little complex, but intuitive */
- if (nu->pntsv == 1) {
- if ((nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) {
- /* pass */
- }
- else {
- break;
- }
- }
- }
- }
- nu = nu->next;
- }
-
- if (nu) {
- int merge_result = merge_nurb(v3d, obedit);
- switch (merge_result) {
- case CURVE_MERGE_OK:
- status.changed++;
- goto curve_merge_tag_object;
- case CURVE_MERGE_ERR_RESOLUTION_SOME:
- status.error_resolution++;
- goto curve_merge_tag_object;
- case CURVE_MERGE_ERR_FEW_SELECTION:
- status.error_selected_few++;
- break;
- case CURVE_MERGE_ERR_RESOLUTION_ALL:
- status.error_resolution++;
- break;
- }
- continue;
- }
-
- /* find both nurbs and points, nu1 will be put behind nu2 */
- for (nu = nubase->first; nu; nu = nu->next) {
- if (nu->pntsu == 1) {
- nu->flagu &= ~CU_NURB_CYCLIC;
- }
-
- if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* not cyclic */
- if (nu->type == CU_BEZIER) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, &(nu->bezt[nu->pntsu - 1]))) {
- /* Last point is selected, preferred for nu2 */
- if (nu2 == NULL) {
- nu2 = nu;
- }
- else if (nu1 == NULL) {
- nu1 = nu;
-
- /* Just in case both of first/last CV are selected check
- * whether we really need to switch the direction.
- */
- if (!BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, nu1->bezt)) {
- BKE_nurb_direction_switch(nu1);
- keyData_switchDirectionNurb(cu, nu1);
- }
- }
- }
- else if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, nu->bezt)) {
- /* First point is selected, preferred for nu1 */
- if (nu1 == NULL) {
- nu1 = nu;
- }
- else if (nu2 == NULL) {
- nu2 = nu;
-
- /* Just in case both of first/last CV are selected check
- * whether we really need to switch the direction.
- */
- if (!BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, &(nu->bezt[nu2->pntsu - 1]))) {
- BKE_nurb_direction_switch(nu2);
- keyData_switchDirectionNurb(cu, nu2);
- }
- }
- }
- }
- else if (nu->pntsv == 1) {
- /* Same logic as above: if first point is selected spline is
- * preferred for nu1, if last point is selected spline is
- * preferred for u2u.
- */
-
- bp = nu->bp;
- if (bp[nu->pntsu - 1].f1 & SELECT) {
- if (nu2 == NULL) {
- nu2 = nu;
- }
- else if (nu1 == NULL) {
- nu1 = nu;
-
- if ((bp->f1 & SELECT) == 0) {
- BKE_nurb_direction_switch(nu);
- keyData_switchDirectionNurb(cu, nu);
- }
- }
- }
- else if (bp->f1 & SELECT) {
- if (nu1 == NULL) {
- nu1 = nu;
- }
- else if (nu2 == NULL) {
- nu2 = nu;
-
- if ((bp[nu->pntsu - 1].f1 & SELECT) == 0) {
- BKE_nurb_direction_switch(nu);
- keyData_switchDirectionNurb(cu, nu);
- }
- }
- }
- }
- }
-
- if (nu1 && nu2) {
- /* Got second spline, no need to loop over rest of the splines. */
- break;
- }
- }
-
- if ((nu1 && nu2) && (nu1 != nu2)) {
- if (nu1->type == nu2->type) {
- if (nu1->type == CU_BEZIER) {
- BezTriple *bezt = (BezTriple *)MEM_mallocN((nu1->pntsu + nu2->pntsu) * sizeof(BezTriple), "addsegmentN");
- ED_curve_beztcpy(cu->editnurb, bezt, nu2->bezt, nu2->pntsu);
- ED_curve_beztcpy(cu->editnurb, bezt + nu2->pntsu, nu1->bezt, nu1->pntsu);
-
- MEM_freeN(nu1->bezt);
- nu1->bezt = bezt;
- nu1->pntsu += nu2->pntsu;
- BLI_remlink(nubase, nu2);
- keyIndex_delNurb(cu->editnurb, nu2);
- BKE_nurb_free(nu2); nu2 = NULL;
- BKE_nurb_handles_calc(nu1);
- }
- else {
- bp = (BPoint *)MEM_mallocN((nu1->pntsu + nu2->pntsu) * sizeof(BPoint), "addsegmentN2");
- ED_curve_bpcpy(cu->editnurb, bp, nu2->bp, nu2->pntsu);
- ED_curve_bpcpy(cu->editnurb, bp + nu2->pntsu, nu1->bp, nu1->pntsu);
- MEM_freeN(nu1->bp);
- nu1->bp = bp;
-
- /* a = nu1->pntsu + nu1->orderu; */ /* UNUSED */
-
- nu1->pntsu += nu2->pntsu;
- BLI_remlink(nubase, nu2);
-
- /* now join the knots */
- if (nu1->type == CU_NURBS) {
- if (nu1->knotsu != NULL) {
- MEM_freeN(nu1->knotsu);
- nu1->knotsu = NULL;
- }
-
- BKE_nurb_knot_calc_u(nu1);
- }
- keyIndex_delNurb(cu->editnurb, nu2);
- BKE_nurb_free(nu2); nu2 = NULL;
- }
-
- BKE_curve_nurb_active_set(cu, nu1); /* for selected */
- ok = true;
- }
- }
- else if ((nu1 && !nu2) || (!nu1 && nu2)) {
- if (nu2) {
- SWAP(Nurb *, nu1, nu2);
- }
-
- if (!(nu1->flagu & CU_NURB_CYCLIC) && nu1->pntsu > 1) {
- if (nu1->type == CU_BEZIER && BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, nu1->bezt) &&
- BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, &nu1->bezt[nu1->pntsu - 1]))
- {
- nu1->flagu |= CU_NURB_CYCLIC;
- BKE_nurb_handles_calc(nu1);
- ok = true;
- }
- else if (nu1->type == CU_NURBS && nu1->bp->f1 & SELECT && (nu1->bp[nu1->pntsu - 1].f1 & SELECT)) {
- nu1->flagu |= CU_NURB_CYCLIC;
- BKE_nurb_knot_calc_u(nu1);
- ok = true;
- }
- }
- }
-
- if (!ok) {
- status.error_generic++;
- continue;
- }
-
- if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
-
- status.changed++;
-
-curve_merge_tag_object:
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- MEM_freeN(objects);
-
- if (status.unselected == objects_len) {
- BKE_report(op->reports, RPT_ERROR, "No points were selected");
- return OPERATOR_CANCELLED;
- }
-
- const int tot_errors = status.error_selected_few + status.error_resolution + status.error_generic;
- if (tot_errors > 0) {
- /* Some curves changed, but some curves failed: don't explain why it failed. */
- if (status.changed) {
- BKE_reportf(op->reports,
- RPT_INFO,
- tot_errors == 1 ? "%d curve could not make segments" :
- "%d curves could not make segments",
- tot_errors);
- return OPERATOR_FINISHED;
- }
-
- /* All curves failed: If there is more than one error give a generic error report. */
- if (((status.error_selected_few ? 1 : 0) +
- (status.error_resolution ? 1 : 0) +
- (status.error_generic ? 1 : 0)) > 1)
- {
- BKE_report(op->reports, RPT_ERROR, "Could not make new segments");
- }
-
- /* All curves failed due to the same error. */
- if (status.error_selected_few) {
- BKE_report(op->reports, RPT_ERROR, "Too few selections to merge");
- }
- else if (status.error_resolution) {
- BKE_report(op->reports, RPT_ERROR, "Resolution does not match");
- }
- else {
- BLI_assert(status.error_generic);
- BKE_report(op->reports, RPT_ERROR, "Cannot make segment");
- }
- return OPERATOR_CANCELLED;
- }
-
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ struct {
+ int changed;
+ int unselected;
+ int error_selected_few;
+ int error_resolution;
+ int error_generic;
+ } status = {0};
+
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ status.unselected++;
+ continue;
+ }
+
+ ListBase *nubase = object_editcurve_get(obedit);
+ Nurb *nu, *nu1 = NULL, *nu2 = NULL;
+ BPoint *bp;
+ bool ok = false;
+
+ /* first decide if this is a surface merge! */
+ if (obedit->type == OB_SURF) {
+ nu = nubase->first;
+ }
+ else {
+ nu = NULL;
+ }
+
+ while (nu) {
+ const int nu_select_num = ED_curve_nurb_select_count(v3d, nu);
+ if (nu_select_num) {
+
+ if (nu->pntsu > 1 && nu->pntsv > 1) {
+ break;
+ }
+
+ if (nu_select_num > 1) {
+ break;
+ }
+ else {
+ /* only 1 selected, not first or last, a little complex, but intuitive */
+ if (nu->pntsv == 1) {
+ if ((nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) {
+ /* pass */
+ }
+ else {
+ break;
+ }
+ }
+ }
+ }
+ nu = nu->next;
+ }
+
+ if (nu) {
+ int merge_result = merge_nurb(v3d, obedit);
+ switch (merge_result) {
+ case CURVE_MERGE_OK:
+ status.changed++;
+ goto curve_merge_tag_object;
+ case CURVE_MERGE_ERR_RESOLUTION_SOME:
+ status.error_resolution++;
+ goto curve_merge_tag_object;
+ case CURVE_MERGE_ERR_FEW_SELECTION:
+ status.error_selected_few++;
+ break;
+ case CURVE_MERGE_ERR_RESOLUTION_ALL:
+ status.error_resolution++;
+ break;
+ }
+ continue;
+ }
+
+ /* find both nurbs and points, nu1 will be put behind nu2 */
+ for (nu = nubase->first; nu; nu = nu->next) {
+ if (nu->pntsu == 1) {
+ nu->flagu &= ~CU_NURB_CYCLIC;
+ }
+
+ if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* not cyclic */
+ if (nu->type == CU_BEZIER) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, &(nu->bezt[nu->pntsu - 1]))) {
+ /* Last point is selected, preferred for nu2 */
+ if (nu2 == NULL) {
+ nu2 = nu;
+ }
+ else if (nu1 == NULL) {
+ nu1 = nu;
+
+ /* Just in case both of first/last CV are selected check
+ * whether we really need to switch the direction.
+ */
+ if (!BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, nu1->bezt)) {
+ BKE_nurb_direction_switch(nu1);
+ keyData_switchDirectionNurb(cu, nu1);
+ }
+ }
+ }
+ else if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, nu->bezt)) {
+ /* First point is selected, preferred for nu1 */
+ if (nu1 == NULL) {
+ nu1 = nu;
+ }
+ else if (nu2 == NULL) {
+ nu2 = nu;
+
+ /* Just in case both of first/last CV are selected check
+ * whether we really need to switch the direction.
+ */
+ if (!BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, &(nu->bezt[nu2->pntsu - 1]))) {
+ BKE_nurb_direction_switch(nu2);
+ keyData_switchDirectionNurb(cu, nu2);
+ }
+ }
+ }
+ }
+ else if (nu->pntsv == 1) {
+ /* Same logic as above: if first point is selected spline is
+ * preferred for nu1, if last point is selected spline is
+ * preferred for u2u.
+ */
+
+ bp = nu->bp;
+ if (bp[nu->pntsu - 1].f1 & SELECT) {
+ if (nu2 == NULL) {
+ nu2 = nu;
+ }
+ else if (nu1 == NULL) {
+ nu1 = nu;
+
+ if ((bp->f1 & SELECT) == 0) {
+ BKE_nurb_direction_switch(nu);
+ keyData_switchDirectionNurb(cu, nu);
+ }
+ }
+ }
+ else if (bp->f1 & SELECT) {
+ if (nu1 == NULL) {
+ nu1 = nu;
+ }
+ else if (nu2 == NULL) {
+ nu2 = nu;
+
+ if ((bp[nu->pntsu - 1].f1 & SELECT) == 0) {
+ BKE_nurb_direction_switch(nu);
+ keyData_switchDirectionNurb(cu, nu);
+ }
+ }
+ }
+ }
+ }
+
+ if (nu1 && nu2) {
+ /* Got second spline, no need to loop over rest of the splines. */
+ break;
+ }
+ }
+
+ if ((nu1 && nu2) && (nu1 != nu2)) {
+ if (nu1->type == nu2->type) {
+ if (nu1->type == CU_BEZIER) {
+ BezTriple *bezt = (BezTriple *)MEM_mallocN((nu1->pntsu + nu2->pntsu) * sizeof(BezTriple),
+ "addsegmentN");
+ ED_curve_beztcpy(cu->editnurb, bezt, nu2->bezt, nu2->pntsu);
+ ED_curve_beztcpy(cu->editnurb, bezt + nu2->pntsu, nu1->bezt, nu1->pntsu);
+
+ MEM_freeN(nu1->bezt);
+ nu1->bezt = bezt;
+ nu1->pntsu += nu2->pntsu;
+ BLI_remlink(nubase, nu2);
+ keyIndex_delNurb(cu->editnurb, nu2);
+ BKE_nurb_free(nu2);
+ nu2 = NULL;
+ BKE_nurb_handles_calc(nu1);
+ }
+ else {
+ bp = (BPoint *)MEM_mallocN((nu1->pntsu + nu2->pntsu) * sizeof(BPoint), "addsegmentN2");
+ ED_curve_bpcpy(cu->editnurb, bp, nu2->bp, nu2->pntsu);
+ ED_curve_bpcpy(cu->editnurb, bp + nu2->pntsu, nu1->bp, nu1->pntsu);
+ MEM_freeN(nu1->bp);
+ nu1->bp = bp;
+
+ /* a = nu1->pntsu + nu1->orderu; */ /* UNUSED */
+
+ nu1->pntsu += nu2->pntsu;
+ BLI_remlink(nubase, nu2);
+
+ /* now join the knots */
+ if (nu1->type == CU_NURBS) {
+ if (nu1->knotsu != NULL) {
+ MEM_freeN(nu1->knotsu);
+ nu1->knotsu = NULL;
+ }
+
+ BKE_nurb_knot_calc_u(nu1);
+ }
+ keyIndex_delNurb(cu->editnurb, nu2);
+ BKE_nurb_free(nu2);
+ nu2 = NULL;
+ }
+
+ BKE_curve_nurb_active_set(cu, nu1); /* for selected */
+ ok = true;
+ }
+ }
+ else if ((nu1 && !nu2) || (!nu1 && nu2)) {
+ if (nu2) {
+ SWAP(Nurb *, nu1, nu2);
+ }
+
+ if (!(nu1->flagu & CU_NURB_CYCLIC) && nu1->pntsu > 1) {
+ if (nu1->type == CU_BEZIER && BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, nu1->bezt) &&
+ BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, &nu1->bezt[nu1->pntsu - 1])) {
+ nu1->flagu |= CU_NURB_CYCLIC;
+ BKE_nurb_handles_calc(nu1);
+ ok = true;
+ }
+ else if (nu1->type == CU_NURBS && nu1->bp->f1 & SELECT &&
+ (nu1->bp[nu1->pntsu - 1].f1 & SELECT)) {
+ nu1->flagu |= CU_NURB_CYCLIC;
+ BKE_nurb_knot_calc_u(nu1);
+ ok = true;
+ }
+ }
+ }
+
+ if (!ok) {
+ status.error_generic++;
+ continue;
+ }
+
+ if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
+
+ status.changed++;
+
+ curve_merge_tag_object:
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ MEM_freeN(objects);
+
+ if (status.unselected == objects_len) {
+ BKE_report(op->reports, RPT_ERROR, "No points were selected");
+ return OPERATOR_CANCELLED;
+ }
+
+ const int tot_errors = status.error_selected_few + status.error_resolution +
+ status.error_generic;
+ if (tot_errors > 0) {
+ /* Some curves changed, but some curves failed: don't explain why it failed. */
+ if (status.changed) {
+ BKE_reportf(op->reports,
+ RPT_INFO,
+ tot_errors == 1 ? "%d curve could not make segments" :
+ "%d curves could not make segments",
+ tot_errors);
+ return OPERATOR_FINISHED;
+ }
+
+ /* All curves failed: If there is more than one error give a generic error report. */
+ if (((status.error_selected_few ? 1 : 0) + (status.error_resolution ? 1 : 0) +
+ (status.error_generic ? 1 : 0)) > 1) {
+ BKE_report(op->reports, RPT_ERROR, "Could not make new segments");
+ }
+
+ /* All curves failed due to the same error. */
+ if (status.error_selected_few) {
+ BKE_report(op->reports, RPT_ERROR, "Too few selections to merge");
+ }
+ else if (status.error_resolution) {
+ BKE_report(op->reports, RPT_ERROR, "Resolution does not match");
+ }
+ else {
+ BLI_assert(status.error_generic);
+ BKE_report(op->reports, RPT_ERROR, "Cannot make segment");
+ }
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
}
void CURVE_OT_make_segment(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Make Segment";
- ot->idname = "CURVE_OT_make_segment";
- ot->description = "Join two curves by their selected ends";
+ /* identifiers */
+ ot->name = "Make Segment";
+ ot->idname = "CURVE_OT_make_segment";
+ ot->description = "Join two curves by their selected ends";
- /* api callbacks */
- ot->exec = make_segment_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = make_segment_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/***************** pick select from 3d view **********************/
-bool ED_curve_editnurb_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
-{
- ViewContext vc;
- Nurb *nu;
- BezTriple *bezt = NULL;
- BPoint *bp = NULL;
- Base *basact = NULL;
- short hand;
-
- view3d_operator_needs_opengl(C);
- ED_view3d_viewcontext_init(C, &vc);
- copy_v2_v2_int(vc.mval, mval);
-
- if (ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, &hand, &basact)) {
- Object *obedit = basact->object;
- Curve *cu = obedit->data;
- ListBase *editnurb = object_editcurve_get(obedit);
- const void *vert = BKE_curve_vert_active_get(cu);
-
- if (!extend && !deselect && !toggle) {
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(vc.view_layer, vc.v3d, &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *ob_iter = objects[ob_index];
-
- ED_curve_deselect_all(((Curve *)ob_iter->data)->editnurb);
-
- DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
- }
- MEM_freeN(objects);
- }
-
- if (extend) {
- if (bezt) {
- if (hand == 1) {
- select_beztriple(bezt, SELECT, SELECT, HIDDEN);
- }
- else {
- if (hand == 0) {
- bezt->f1 |= SELECT;
- }
- else {
- bezt->f3 |= SELECT;
- }
- }
- BKE_curve_nurb_vert_active_set(cu, nu, bezt);
- }
- else {
- select_bpoint(bp, SELECT, SELECT, HIDDEN);
- BKE_curve_nurb_vert_active_set(cu, nu, bp);
- }
- }
- else if (deselect) {
- if (bezt) {
- if (hand == 1) {
- select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
- if (bezt == vert) {
- cu->actvert = CU_ACT_NONE;
- }
- }
- else if (hand == 0) {
- bezt->f1 &= ~SELECT;
- }
- else {
- bezt->f3 &= ~SELECT;
- }
- }
- else {
- select_bpoint(bp, DESELECT, SELECT, HIDDEN);
- if (bp == vert) {
- cu->actvert = CU_ACT_NONE;
- }
- }
- }
- else if (toggle) {
- if (bezt) {
- if (hand == 1) {
- if (bezt->f2 & SELECT) {
- select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
- if (bezt == vert) {
- cu->actvert = CU_ACT_NONE;
- }
- }
- else {
- select_beztriple(bezt, SELECT, SELECT, HIDDEN);
- BKE_curve_nurb_vert_active_set(cu, nu, bezt);
- }
- }
- else if (hand == 0) {
- bezt->f1 ^= SELECT;
- }
- else {
- bezt->f3 ^= SELECT;
- }
- }
- else {
- if (bp->f1 & SELECT) {
- select_bpoint(bp, DESELECT, SELECT, HIDDEN);
- if (bp == vert) {
- cu->actvert = CU_ACT_NONE;
- }
- }
- else {
- select_bpoint(bp, SELECT, SELECT, HIDDEN);
- BKE_curve_nurb_vert_active_set(cu, nu, bp);
- }
- }
- }
- else {
- BKE_nurbList_flag_set(editnurb, 0);
-
- if (bezt) {
-
- if (hand == 1) {
- select_beztriple(bezt, SELECT, SELECT, HIDDEN);
- }
- else {
- if (hand == 0) {
- bezt->f1 |= SELECT;
- }
- else {
- bezt->f3 |= SELECT;
- }
- }
- BKE_curve_nurb_vert_active_set(cu, nu, bezt);
- }
- else {
- select_bpoint(bp, SELECT, SELECT, HIDDEN);
- BKE_curve_nurb_vert_active_set(cu, nu, bp);
- }
- }
-
- if (nu != BKE_curve_nurb_active_get(cu)) {
- cu->actvert = CU_ACT_NONE;
- BKE_curve_nurb_active_set(cu, nu);
- }
-
- if (vc.view_layer->basact != basact) {
- ED_object_base_activate(C, basact);
- }
-
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
-
- return true;
- }
-
- return false;
+bool ED_curve_editnurb_select_pick(
+ bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
+{
+ ViewContext vc;
+ Nurb *nu;
+ BezTriple *bezt = NULL;
+ BPoint *bp = NULL;
+ Base *basact = NULL;
+ short hand;
+
+ view3d_operator_needs_opengl(C);
+ ED_view3d_viewcontext_init(C, &vc);
+ copy_v2_v2_int(vc.mval, mval);
+
+ if (ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, &hand, &basact)) {
+ Object *obedit = basact->object;
+ Curve *cu = obedit->data;
+ ListBase *editnurb = object_editcurve_get(obedit);
+ const void *vert = BKE_curve_vert_active_get(cu);
+
+ if (!extend && !deselect && !toggle) {
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ vc.view_layer, vc.v3d, &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob_iter = objects[ob_index];
+
+ ED_curve_deselect_all(((Curve *)ob_iter->data)->editnurb);
+
+ DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
+ }
+ MEM_freeN(objects);
+ }
+
+ if (extend) {
+ if (bezt) {
+ if (hand == 1) {
+ select_beztriple(bezt, SELECT, SELECT, HIDDEN);
+ }
+ else {
+ if (hand == 0) {
+ bezt->f1 |= SELECT;
+ }
+ else {
+ bezt->f3 |= SELECT;
+ }
+ }
+ BKE_curve_nurb_vert_active_set(cu, nu, bezt);
+ }
+ else {
+ select_bpoint(bp, SELECT, SELECT, HIDDEN);
+ BKE_curve_nurb_vert_active_set(cu, nu, bp);
+ }
+ }
+ else if (deselect) {
+ if (bezt) {
+ if (hand == 1) {
+ select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
+ if (bezt == vert) {
+ cu->actvert = CU_ACT_NONE;
+ }
+ }
+ else if (hand == 0) {
+ bezt->f1 &= ~SELECT;
+ }
+ else {
+ bezt->f3 &= ~SELECT;
+ }
+ }
+ else {
+ select_bpoint(bp, DESELECT, SELECT, HIDDEN);
+ if (bp == vert) {
+ cu->actvert = CU_ACT_NONE;
+ }
+ }
+ }
+ else if (toggle) {
+ if (bezt) {
+ if (hand == 1) {
+ if (bezt->f2 & SELECT) {
+ select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
+ if (bezt == vert) {
+ cu->actvert = CU_ACT_NONE;
+ }
+ }
+ else {
+ select_beztriple(bezt, SELECT, SELECT, HIDDEN);
+ BKE_curve_nurb_vert_active_set(cu, nu, bezt);
+ }
+ }
+ else if (hand == 0) {
+ bezt->f1 ^= SELECT;
+ }
+ else {
+ bezt->f3 ^= SELECT;
+ }
+ }
+ else {
+ if (bp->f1 & SELECT) {
+ select_bpoint(bp, DESELECT, SELECT, HIDDEN);
+ if (bp == vert) {
+ cu->actvert = CU_ACT_NONE;
+ }
+ }
+ else {
+ select_bpoint(bp, SELECT, SELECT, HIDDEN);
+ BKE_curve_nurb_vert_active_set(cu, nu, bp);
+ }
+ }
+ }
+ else {
+ BKE_nurbList_flag_set(editnurb, 0);
+
+ if (bezt) {
+
+ if (hand == 1) {
+ select_beztriple(bezt, SELECT, SELECT, HIDDEN);
+ }
+ else {
+ if (hand == 0) {
+ bezt->f1 |= SELECT;
+ }
+ else {
+ bezt->f3 |= SELECT;
+ }
+ }
+ BKE_curve_nurb_vert_active_set(cu, nu, bezt);
+ }
+ else {
+ select_bpoint(bp, SELECT, SELECT, HIDDEN);
+ BKE_curve_nurb_vert_active_set(cu, nu, bp);
+ }
+ }
+
+ if (nu != BKE_curve_nurb_active_get(cu)) {
+ cu->actvert = CU_ACT_NONE;
+ BKE_curve_nurb_active_set(cu, nu);
+ }
+
+ if (vc.view_layer->basact != basact) {
+ ED_object_base_activate(C, basact);
+ }
+
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
+ return true;
+ }
+
+ return false;
}
/******************** spin operator ***********************/
/* 'cent' is in object space and 'dvec' in worldspace.
*/
-bool ed_editnurb_spin(float viewmat[4][4], View3D *v3d, Object *obedit, const float axis[3], const float cent[3])
-{
- Curve *cu = (Curve *)obedit->data;
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- float cmat[3][3], tmat[3][3], imat[3][3];
- float bmat[3][3], rotmat[3][3], scalemat1[3][3], scalemat2[3][3];
- float persmat[3][3], persinv[3][3];
- bool ok, changed = false;
- int a;
-
- copy_m3_m4(persmat, viewmat);
- invert_m3_m3(persinv, persmat);
-
- /* imat and center and size */
- copy_m3_m4(bmat, obedit->obmat);
- invert_m3_m3(imat, bmat);
-
- axis_angle_to_mat3(cmat, axis, M_PI / 4.0);
- mul_m3_m3m3(tmat, cmat, bmat);
- mul_m3_m3m3(rotmat, imat, tmat);
-
- unit_m3(scalemat1);
- scalemat1[0][0] = M_SQRT2;
- scalemat1[1][1] = M_SQRT2;
-
- mul_m3_m3m3(tmat, persmat, bmat);
- mul_m3_m3m3(cmat, scalemat1, tmat);
- mul_m3_m3m3(tmat, persinv, cmat);
- mul_m3_m3m3(scalemat1, imat, tmat);
-
- unit_m3(scalemat2);
- scalemat2[0][0] /= (float)M_SQRT2;
- scalemat2[1][1] /= (float)M_SQRT2;
-
- mul_m3_m3m3(tmat, persmat, bmat);
- mul_m3_m3m3(cmat, scalemat2, tmat);
- mul_m3_m3m3(tmat, persinv, cmat);
- mul_m3_m3m3(scalemat2, imat, tmat);
-
- ok = true;
-
- for (a = 0; a < 7; a++) {
- ok = ed_editnurb_extrude_flag(cu->editnurb, SELECT);
-
- if (ok == false) {
- return changed;
- }
-
- changed = true;
-
- rotateflagNurb(editnurb, SELECT, cent, rotmat);
-
- if ((a & 1) == 0) {
- rotateflagNurb(editnurb, SELECT, cent, scalemat1);
- weightflagNurb(editnurb, SELECT, 0.25 * M_SQRT2);
- }
- else {
- rotateflagNurb(editnurb, SELECT, cent, scalemat2);
- weightflagNurb(editnurb, SELECT, 4.0 / M_SQRT2);
- }
- }
-
- if (ok) {
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (ED_curve_nurb_select_check(v3d, nu)) {
- nu->orderv = 4;
- nu->flagv |= CU_NURB_CYCLIC;
- BKE_nurb_knot_calc_v(nu);
- }
- }
- }
-
- return changed;
+bool ed_editnurb_spin(
+ float viewmat[4][4], View3D *v3d, Object *obedit, const float axis[3], const float cent[3])
+{
+ Curve *cu = (Curve *)obedit->data;
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ float cmat[3][3], tmat[3][3], imat[3][3];
+ float bmat[3][3], rotmat[3][3], scalemat1[3][3], scalemat2[3][3];
+ float persmat[3][3], persinv[3][3];
+ bool ok, changed = false;
+ int a;
+
+ copy_m3_m4(persmat, viewmat);
+ invert_m3_m3(persinv, persmat);
+
+ /* imat and center and size */
+ copy_m3_m4(bmat, obedit->obmat);
+ invert_m3_m3(imat, bmat);
+
+ axis_angle_to_mat3(cmat, axis, M_PI / 4.0);
+ mul_m3_m3m3(tmat, cmat, bmat);
+ mul_m3_m3m3(rotmat, imat, tmat);
+
+ unit_m3(scalemat1);
+ scalemat1[0][0] = M_SQRT2;
+ scalemat1[1][1] = M_SQRT2;
+
+ mul_m3_m3m3(tmat, persmat, bmat);
+ mul_m3_m3m3(cmat, scalemat1, tmat);
+ mul_m3_m3m3(tmat, persinv, cmat);
+ mul_m3_m3m3(scalemat1, imat, tmat);
+
+ unit_m3(scalemat2);
+ scalemat2[0][0] /= (float)M_SQRT2;
+ scalemat2[1][1] /= (float)M_SQRT2;
+
+ mul_m3_m3m3(tmat, persmat, bmat);
+ mul_m3_m3m3(cmat, scalemat2, tmat);
+ mul_m3_m3m3(tmat, persinv, cmat);
+ mul_m3_m3m3(scalemat2, imat, tmat);
+
+ ok = true;
+
+ for (a = 0; a < 7; a++) {
+ ok = ed_editnurb_extrude_flag(cu->editnurb, SELECT);
+
+ if (ok == false) {
+ return changed;
+ }
+
+ changed = true;
+
+ rotateflagNurb(editnurb, SELECT, cent, rotmat);
+
+ if ((a & 1) == 0) {
+ rotateflagNurb(editnurb, SELECT, cent, scalemat1);
+ weightflagNurb(editnurb, SELECT, 0.25 * M_SQRT2);
+ }
+ else {
+ rotateflagNurb(editnurb, SELECT, cent, scalemat2);
+ weightflagNurb(editnurb, SELECT, 4.0 / M_SQRT2);
+ }
+ }
+
+ if (ok) {
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+ nu->orderv = 4;
+ nu->flagv |= CU_NURB_CYCLIC;
+ BKE_nurb_knot_calc_v(nu);
+ }
+ }
+ }
+
+ return changed;
}
static int spin_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = ED_view3d_context_rv3d(C);
- float cent[3], axis[3], viewmat[4][4];
- int ok = -1;
-
- RNA_float_get_array(op->ptr, "center", cent);
- RNA_float_get_array(op->ptr, "axis", axis);
-
- if (rv3d) {
- copy_m4_m4(viewmat, rv3d->viewmat);
- }
- else {
- unit_m4(viewmat);
- }
-
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = (Curve *)obedit->data;
-
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
-
- invert_m4_m4(obedit->imat, obedit->obmat);
- mul_m4_v3(obedit->imat, cent);
-
- if (!ed_editnurb_spin(viewmat, v3d, obedit, axis, cent)) {
- ok = MAX2(ok, 0);
- continue;
- }
-
- ok = 1;
- if (ED_curve_updateAnimPaths(bmain, cu)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
-
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- MEM_freeN(objects);
-
- if (ok == 0) {
- BKE_report(op->reports, RPT_ERROR, "Cannot spin");
- }
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = ED_view3d_context_rv3d(C);
+ float cent[3], axis[3], viewmat[4][4];
+ int ok = -1;
+
+ RNA_float_get_array(op->ptr, "center", cent);
+ RNA_float_get_array(op->ptr, "axis", axis);
+
+ if (rv3d) {
+ copy_m4_m4(viewmat, rv3d->viewmat);
+ }
+ else {
+ unit_m4(viewmat);
+ }
+
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = (Curve *)obedit->data;
+
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
+
+ invert_m4_m4(obedit->imat, obedit->obmat);
+ mul_m4_v3(obedit->imat, cent);
+
+ if (!ed_editnurb_spin(viewmat, v3d, obedit, axis, cent)) {
+ ok = MAX2(ok, 0);
+ continue;
+ }
+
+ ok = 1;
+ if (ED_curve_updateAnimPaths(bmain, cu)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ MEM_freeN(objects);
+
+ if (ok == 0) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot spin");
+ }
+ return OPERATOR_FINISHED;
}
static int spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- Scene *scene = CTX_data_scene(C);
- RegionView3D *rv3d = ED_view3d_context_rv3d(C);
- float axis[3] = {0.0f, 0.0f, 1.0f};
+ Scene *scene = CTX_data_scene(C);
+ RegionView3D *rv3d = ED_view3d_context_rv3d(C);
+ float axis[3] = {0.0f, 0.0f, 1.0f};
- if (rv3d) {
- copy_v3_v3(axis, rv3d->viewinv[2]);
- }
+ if (rv3d) {
+ copy_v3_v3(axis, rv3d->viewinv[2]);
+ }
- RNA_float_set_array(op->ptr, "center", scene->cursor.location);
- RNA_float_set_array(op->ptr, "axis", axis);
+ RNA_float_set_array(op->ptr, "center", scene->cursor.location);
+ RNA_float_set_array(op->ptr, "axis", axis);
- return spin_exec(C, op);
+ return spin_exec(C, op);
}
void CURVE_OT_spin(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Spin";
- ot->idname = "CURVE_OT_spin";
- ot->description = "Extrude selected boundary row around pivot point and current view axis";
-
- /* api callbacks */
- ot->exec = spin_exec;
- ot->invoke = spin_invoke;
- ot->poll = ED_operator_editsurf;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -OBJECT_ADD_SIZE_MAXF, OBJECT_ADD_SIZE_MAXF,
- "Center", "Center in global view space", -1000.0f, 1000.0f);
- RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -1.0f, 1.0f);
+ /* identifiers */
+ ot->name = "Spin";
+ ot->idname = "CURVE_OT_spin";
+ ot->description = "Extrude selected boundary row around pivot point and current view axis";
+
+ /* api callbacks */
+ ot->exec = spin_exec;
+ ot->invoke = spin_invoke;
+ ot->poll = ED_operator_editsurf;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_float_vector_xyz(ot->srna,
+ "center",
+ 3,
+ NULL,
+ -OBJECT_ADD_SIZE_MAXF,
+ OBJECT_ADD_SIZE_MAXF,
+ "Center",
+ "Center in global view space",
+ -1000.0f,
+ 1000.0f);
+ RNA_def_float_vector(
+ ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -1.0f, 1.0f);
}
/***************** extrude vertex operator **********************/
static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb, View3D *v3d)
{
- Nurb *nu = NULL;
- Nurb *nu_last = NULL;
-
- bool changed = false;
-
- Nurb *cu_actnu;
- union {
- BezTriple *bezt;
- BPoint *bp;
- void *p;
- } cu_actvert;
+ Nurb *nu = NULL;
+ Nurb *nu_last = NULL;
- if (BLI_listbase_is_empty(&editnurb->nurbs)) {
- return changed;
- }
+ bool changed = false;
- BKE_curve_nurb_vert_active_get(cu, &cu_actnu, &cu_actvert.p);
- BKE_curve_nurb_vert_active_set(cu, NULL, NULL);
+ Nurb *cu_actnu;
+ union {
+ BezTriple *bezt;
+ BPoint *bp;
+ void *p;
+ } cu_actvert;
- /* first pass (endpoints) */
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ if (BLI_listbase_is_empty(&editnurb->nurbs)) {
+ return changed;
+ }
- if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) {
- continue;
- }
+ BKE_curve_nurb_vert_active_get(cu, &cu_actnu, &cu_actvert.p);
+ BKE_curve_nurb_vert_active_set(cu, NULL, NULL);
+
+ /* first pass (endpoints) */
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
+ if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) {
+ continue;
+ }
- /* Check to see if the first bezier point is selected */
- if (nu->pntsu > 0 && nu->bezt != NULL) {
- BezTriple *nu_bezt_old = nu->bezt;
- BezTriple *bezt = nu->bezt;
+ if (nu->type == CU_BEZIER) {
+
+ /* Check to see if the first bezier point is selected */
+ if (nu->pntsu > 0 && nu->bezt != NULL) {
+ BezTriple *nu_bezt_old = nu->bezt;
+ BezTriple *bezt = nu->bezt;
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- BezTriple *bezt_new;
- BEZT_DESEL_ALL(bezt);
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ BezTriple *bezt_new;
+ BEZT_DESEL_ALL(bezt);
- bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__);
- ED_curve_beztcpy(editnurb, bezt_new + 1, bezt, nu->pntsu);
- *bezt_new = *bezt;
+ bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__);
+ ED_curve_beztcpy(editnurb, bezt_new + 1, bezt, nu->pntsu);
+ *bezt_new = *bezt;
+ MEM_freeN(nu->bezt);
+ nu->bezt = bezt_new;
- MEM_freeN(nu->bezt);
- nu->bezt = bezt_new;
+ nu->pntsu += 1;
- nu->pntsu += 1;
+ if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) {
+ cu_actvert.bezt = (cu_actvert.bezt == bezt) ?
+ bezt_new :
+ &nu->bezt[(cu_actvert.bezt - nu_bezt_old) + 1];
+ BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt);
+ }
- if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) {
- cu_actvert.bezt = (cu_actvert.bezt == bezt) ?
- bezt_new : &nu->bezt[(cu_actvert.bezt - nu_bezt_old) + 1];
- BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt);
- }
+ BEZT_SEL_ALL(bezt_new);
+ changed = true;
+ }
+ }
- BEZT_SEL_ALL(bezt_new);
- changed = true;
- }
- }
-
- /* Check to see if the last bezier point is selected */
- if (nu->pntsu > 1) {
- BezTriple *nu_bezt_old = nu->bezt;
- BezTriple *bezt = &nu->bezt[nu->pntsu - 1];
-
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- BezTriple *bezt_new;
- BEZT_DESEL_ALL(bezt);
-
- bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__);
- ED_curve_beztcpy(editnurb, bezt_new, nu->bezt, nu->pntsu);
- bezt_new[nu->pntsu] = *bezt;
-
- MEM_freeN(nu->bezt);
- nu->bezt = bezt_new;
-
- bezt_new += nu->pntsu;
- nu->pntsu += 1;
-
- if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) {
- cu_actvert.bezt = (cu_actvert.bezt == bezt) ?
- bezt_new : &nu->bezt[cu_actvert.bezt - nu_bezt_old];
- BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt);
- }
-
- BEZT_SEL_ALL(bezt_new);
- changed = true;
- }
- }
- }
- else {
-
- /* Check to see if the first bpoint is selected */
- if (nu->pntsu > 0 && nu->bp != NULL) {
- BPoint *nu_bp_old = nu->bp;
- BPoint *bp = nu->bp;
-
- if (bp->f1 & SELECT) {
- BPoint *bp_new;
- bp->f1 &= ~SELECT;
-
- bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__);
- ED_curve_bpcpy(editnurb, bp_new + 1, bp, nu->pntsu);
- *bp_new = *bp;
-
- MEM_freeN(nu->bp);
- nu->bp = bp_new;
-
- nu->pntsu += 1;
- BKE_nurb_knot_calc_u(nu);
-
- if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) {
- cu_actvert.bp = (cu_actvert.bp == bp) ?
- bp_new : &nu->bp[(cu_actvert.bp - nu_bp_old) + 1];
- BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp);
- }
-
- bp_new->f1 |= SELECT;
- changed = true;
- }
- }
-
- /* Check to see if the last bpoint is selected */
- if (nu->pntsu > 1) {
- BPoint *nu_bp_old = nu->bp;
- BPoint *bp = &nu->bp[nu->pntsu - 1];
-
- if (bp->f1 & SELECT) {
- BPoint *bp_new;
- bp->f1 &= ~SELECT;
-
- bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__);
- ED_curve_bpcpy(editnurb, bp_new, nu->bp, nu->pntsu);
- bp_new[nu->pntsu] = *bp;
-
- MEM_freeN(nu->bp);
- nu->bp = bp_new;
-
- bp_new += nu->pntsu;
- nu->pntsu += 1;
-
- if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) {
- cu_actvert.bp = (cu_actvert.bp == bp) ?
- bp_new : &nu->bp[cu_actvert.bp - nu_bp_old];
- BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp);
- }
-
- BKE_nurb_knot_calc_u(nu);
-
- bp_new->f1 |= SELECT;
- changed = true;
- }
- }
- }
- }
-
- /* second pass (interior points) */
- nu_last = editnurb->nurbs.last;
- for (nu = editnurb->nurbs.first; (nu != nu_last->next); nu = nu->next) {
- int i, i_end;
-
- if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) {
- /* all points are interior */
- i = 0;
- i_end = nu->pntsu;
- }
- else {
- /* skip endpoints */
- i = 1;
- i_end = nu->pntsu - 1;
- }
-
- if (nu->type == CU_BEZIER) {
- BezTriple *bezt;
-
- for (bezt = &nu->bezt[i]; i < i_end; i++, bezt++) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- Nurb *nurb_new;
- BezTriple *bezt_new;
-
- BEZT_DESEL_ALL(bezt);
- nurb_new = BKE_nurb_copy(nu, 1, 1);
- nurb_new->flagu &= ~CU_NURB_CYCLIC;
- BLI_addtail(&editnurb->nurbs, nurb_new);
- bezt_new = nurb_new->bezt;
- ED_curve_beztcpy(editnurb, bezt_new, bezt, 1);
- BEZT_SEL_ALL(bezt_new);
-
- if (cu_actvert.bezt == bezt || cu_actnu == NULL) {
- BKE_curve_nurb_vert_active_set(cu, nurb_new, bezt_new);
- }
-
- changed = true;
- }
- }
- }
- else {
- BPoint *bp;
-
- for (bp = &nu->bp[i]; i < i_end; i++, bp++) {
- if (bp->f1 & SELECT) {
- Nurb *nurb_new;
- BPoint *bp_new;
-
- bp->f1 &= ~SELECT;
- nurb_new = BKE_nurb_copy(nu, 1, 1);
- nurb_new->flagu &= ~CU_NURB_CYCLIC;
- BLI_addtail(&editnurb->nurbs, nurb_new);
- bp_new = nurb_new->bp;
- ED_curve_bpcpy(editnurb, bp_new, bp, 1);
- bp_new->f1 |= SELECT;
-
- if (cu_actvert.bp == bp || cu_actnu == NULL) {
- BKE_curve_nurb_vert_active_set(cu, nurb_new, bp_new);
- }
-
- changed = true;
- }
- }
- }
- }
-
- if (changed == false) {
- BKE_curve_nurb_vert_active_set(cu, cu_actnu, cu_actvert.p);
- }
-
- return changed;
+ /* Check to see if the last bezier point is selected */
+ if (nu->pntsu > 1) {
+ BezTriple *nu_bezt_old = nu->bezt;
+ BezTriple *bezt = &nu->bezt[nu->pntsu - 1];
+
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ BezTriple *bezt_new;
+ BEZT_DESEL_ALL(bezt);
+
+ bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__);
+ ED_curve_beztcpy(editnurb, bezt_new, nu->bezt, nu->pntsu);
+ bezt_new[nu->pntsu] = *bezt;
+
+ MEM_freeN(nu->bezt);
+ nu->bezt = bezt_new;
+
+ bezt_new += nu->pntsu;
+ nu->pntsu += 1;
+
+ if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) {
+ cu_actvert.bezt = (cu_actvert.bezt == bezt) ? bezt_new :
+ &nu->bezt[cu_actvert.bezt - nu_bezt_old];
+ BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt);
+ }
+
+ BEZT_SEL_ALL(bezt_new);
+ changed = true;
+ }
+ }
+ }
+ else {
+
+ /* Check to see if the first bpoint is selected */
+ if (nu->pntsu > 0 && nu->bp != NULL) {
+ BPoint *nu_bp_old = nu->bp;
+ BPoint *bp = nu->bp;
+
+ if (bp->f1 & SELECT) {
+ BPoint *bp_new;
+ bp->f1 &= ~SELECT;
+
+ bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__);
+ ED_curve_bpcpy(editnurb, bp_new + 1, bp, nu->pntsu);
+ *bp_new = *bp;
+
+ MEM_freeN(nu->bp);
+ nu->bp = bp_new;
+
+ nu->pntsu += 1;
+ BKE_nurb_knot_calc_u(nu);
+
+ if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) {
+ cu_actvert.bp = (cu_actvert.bp == bp) ? bp_new :
+ &nu->bp[(cu_actvert.bp - nu_bp_old) + 1];
+ BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp);
+ }
+
+ bp_new->f1 |= SELECT;
+ changed = true;
+ }
+ }
+
+ /* Check to see if the last bpoint is selected */
+ if (nu->pntsu > 1) {
+ BPoint *nu_bp_old = nu->bp;
+ BPoint *bp = &nu->bp[nu->pntsu - 1];
+
+ if (bp->f1 & SELECT) {
+ BPoint *bp_new;
+ bp->f1 &= ~SELECT;
+
+ bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__);
+ ED_curve_bpcpy(editnurb, bp_new, nu->bp, nu->pntsu);
+ bp_new[nu->pntsu] = *bp;
+
+ MEM_freeN(nu->bp);
+ nu->bp = bp_new;
+
+ bp_new += nu->pntsu;
+ nu->pntsu += 1;
+
+ if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) {
+ cu_actvert.bp = (cu_actvert.bp == bp) ? bp_new : &nu->bp[cu_actvert.bp - nu_bp_old];
+ BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp);
+ }
+
+ BKE_nurb_knot_calc_u(nu);
+
+ bp_new->f1 |= SELECT;
+ changed = true;
+ }
+ }
+ }
+ }
+
+ /* second pass (interior points) */
+ nu_last = editnurb->nurbs.last;
+ for (nu = editnurb->nurbs.first; (nu != nu_last->next); nu = nu->next) {
+ int i, i_end;
+
+ if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) {
+ /* all points are interior */
+ i = 0;
+ i_end = nu->pntsu;
+ }
+ else {
+ /* skip endpoints */
+ i = 1;
+ i_end = nu->pntsu - 1;
+ }
+
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt;
+
+ for (bezt = &nu->bezt[i]; i < i_end; i++, bezt++) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ Nurb *nurb_new;
+ BezTriple *bezt_new;
+
+ BEZT_DESEL_ALL(bezt);
+ nurb_new = BKE_nurb_copy(nu, 1, 1);
+ nurb_new->flagu &= ~CU_NURB_CYCLIC;
+ BLI_addtail(&editnurb->nurbs, nurb_new);
+ bezt_new = nurb_new->bezt;
+ ED_curve_beztcpy(editnurb, bezt_new, bezt, 1);
+ BEZT_SEL_ALL(bezt_new);
+
+ if (cu_actvert.bezt == bezt || cu_actnu == NULL) {
+ BKE_curve_nurb_vert_active_set(cu, nurb_new, bezt_new);
+ }
+
+ changed = true;
+ }
+ }
+ }
+ else {
+ BPoint *bp;
+
+ for (bp = &nu->bp[i]; i < i_end; i++, bp++) {
+ if (bp->f1 & SELECT) {
+ Nurb *nurb_new;
+ BPoint *bp_new;
+
+ bp->f1 &= ~SELECT;
+ nurb_new = BKE_nurb_copy(nu, 1, 1);
+ nurb_new->flagu &= ~CU_NURB_CYCLIC;
+ BLI_addtail(&editnurb->nurbs, nurb_new);
+ bp_new = nurb_new->bp;
+ ED_curve_bpcpy(editnurb, bp_new, bp, 1);
+ bp_new->f1 |= SELECT;
+
+ if (cu_actvert.bp == bp || cu_actnu == NULL) {
+ BKE_curve_nurb_vert_active_set(cu, nurb_new, bp_new);
+ }
+
+ changed = true;
+ }
+ }
+ }
+ }
+
+ if (changed == false) {
+ BKE_curve_nurb_vert_active_set(cu, cu_actnu, cu_actvert.p);
+ }
+
+ return changed;
}
/***************** add vertex operator **********************/
-static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, View3D *v3d, const float location_init[3])
-{
- Nurb *nu;
-
- float center[3];
- float temp[3];
- uint verts_len;
- bool changed = false;
-
- zero_v3(center);
- verts_len = 0;
-
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- int i;
- if (nu->type == CU_BEZIER) {
- BezTriple *bezt;
-
- for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- add_v3_v3(center, bezt->vec[1]);
- verts_len += 1;
- }
- }
- }
- else {
- BPoint *bp;
-
- for (i = 0, bp = nu->bp; i < nu->pntsu; i++, bp++) {
- if (bp->f1 & SELECT) {
- add_v3_v3(center, bp->vec);
- verts_len += 1;
- }
- }
- }
- }
-
- if (verts_len && ed_editcurve_extrude(cu, editnurb, v3d)) {
- float ofs[3];
- int i;
-
- mul_v3_fl(center, 1.0f / (float)verts_len);
- sub_v3_v3v3(ofs, location_init, center);
-
- if ((cu->flag & CU_3D) == 0) {
- ofs[2] = 0.0f;
- }
-
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- BezTriple *bezt;
- for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- add_v3_v3(bezt->vec[0], ofs);
- add_v3_v3(bezt->vec[1], ofs);
- add_v3_v3(bezt->vec[2], ofs);
-
- if (((nu->flagu & CU_NURB_CYCLIC) == 0) &&
- (i == 0 || i == nu->pntsu - 1))
- {
- BKE_nurb_handle_calc_simple_auto(nu, bezt);
- }
- }
- }
-
- BKE_nurb_handles_calc(nu);
- }
- else {
- BPoint *bp;
-
- for (i = 0, bp = nu->bp; i < nu->pntsu; i++, bp++) {
- if (bp->f1 & SELECT) {
- add_v3_v3(bp->vec, ofs);
- }
- }
- }
- }
- changed = true;
- }
- else {
- float location[3];
-
- copy_v3_v3(location, location_init);
-
- if ((cu->flag & CU_3D) == 0) {
- location[2] = 0.0f;
- }
-
- /* nothing selected: create a new curve */
- nu = BKE_curve_nurb_active_get(cu);
-
- if (!nu || nu->type == CU_BEZIER) {
- Nurb *nurb_new;
- BezTriple *bezt_new;
-
- if (nu) {
- nurb_new = BKE_nurb_copy(nu, 1, 1);
- }
- else {
- nurb_new = MEM_callocN(sizeof(Nurb), "BLI_editcurve_addvert new_bezt_nurb 2");
- nurb_new->type = CU_BEZIER;
- nurb_new->resolu = cu->resolu;
- nurb_new->orderu = 4;
- nurb_new->flag |= CU_SMOOTH;
- BKE_nurb_bezierPoints_add(nurb_new, 1);
-
- if ((cu->flag & CU_3D) == 0) {
- nurb_new->flag |= CU_2D;
- }
- }
- BLI_addtail(&editnurb->nurbs, nurb_new);
-
- bezt_new = nurb_new->bezt;
-
- BEZT_SEL_ALL(bezt_new);
-
- bezt_new->h1 = HD_AUTO;
- bezt_new->h2 = HD_AUTO;
-
- temp[0] = 1.0f;
- temp[1] = 0.0f;
- temp[2] = 0.0f;
-
- copy_v3_v3(bezt_new->vec[1], location);
- sub_v3_v3v3(bezt_new->vec[0], bezt_new->vec[1], temp);
- add_v3_v3v3(bezt_new->vec[2], bezt_new->vec[1], temp);
-
- changed = true;
- }
- else {
- Nurb *nurb_new;
- BPoint *bp_new;
-
- {
- nurb_new = MEM_callocN(sizeof(Nurb), __func__);
- nurb_new->type = CU_POLY;
- nurb_new->resolu = cu->resolu;
- nurb_new->flag |= CU_SMOOTH;
- nurb_new->orderu = 4;
- BKE_nurb_points_add(nurb_new, 1);
-
- if ((cu->flag & CU_3D) == 0) {
- nurb_new->flag |= CU_2D;
- }
- }
- BLI_addtail(&editnurb->nurbs, nurb_new);
-
- bp_new = nurb_new->bp;
-
- bp_new->f1 |= SELECT;
-
- copy_v3_v3(bp_new->vec, location);
- bp_new->vec[3] = 1.0f;
-
- BKE_nurb_knot_calc_u(nurb_new);
-
- changed = true;
- }
- }
-
- return changed;
+static int ed_editcurve_addvert(Curve *cu,
+ EditNurb *editnurb,
+ View3D *v3d,
+ const float location_init[3])
+{
+ Nurb *nu;
+
+ float center[3];
+ float temp[3];
+ uint verts_len;
+ bool changed = false;
+
+ zero_v3(center);
+ verts_len = 0;
+
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ int i;
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt;
+
+ for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ add_v3_v3(center, bezt->vec[1]);
+ verts_len += 1;
+ }
+ }
+ }
+ else {
+ BPoint *bp;
+
+ for (i = 0, bp = nu->bp; i < nu->pntsu; i++, bp++) {
+ if (bp->f1 & SELECT) {
+ add_v3_v3(center, bp->vec);
+ verts_len += 1;
+ }
+ }
+ }
+ }
+
+ if (verts_len && ed_editcurve_extrude(cu, editnurb, v3d)) {
+ float ofs[3];
+ int i;
+
+ mul_v3_fl(center, 1.0f / (float)verts_len);
+ sub_v3_v3v3(ofs, location_init, center);
+
+ if ((cu->flag & CU_3D) == 0) {
+ ofs[2] = 0.0f;
+ }
+
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt;
+ for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ add_v3_v3(bezt->vec[0], ofs);
+ add_v3_v3(bezt->vec[1], ofs);
+ add_v3_v3(bezt->vec[2], ofs);
+
+ if (((nu->flagu & CU_NURB_CYCLIC) == 0) && (i == 0 || i == nu->pntsu - 1)) {
+ BKE_nurb_handle_calc_simple_auto(nu, bezt);
+ }
+ }
+ }
+
+ BKE_nurb_handles_calc(nu);
+ }
+ else {
+ BPoint *bp;
+
+ for (i = 0, bp = nu->bp; i < nu->pntsu; i++, bp++) {
+ if (bp->f1 & SELECT) {
+ add_v3_v3(bp->vec, ofs);
+ }
+ }
+ }
+ }
+ changed = true;
+ }
+ else {
+ float location[3];
+
+ copy_v3_v3(location, location_init);
+
+ if ((cu->flag & CU_3D) == 0) {
+ location[2] = 0.0f;
+ }
+
+ /* nothing selected: create a new curve */
+ nu = BKE_curve_nurb_active_get(cu);
+
+ if (!nu || nu->type == CU_BEZIER) {
+ Nurb *nurb_new;
+ BezTriple *bezt_new;
+
+ if (nu) {
+ nurb_new = BKE_nurb_copy(nu, 1, 1);
+ }
+ else {
+ nurb_new = MEM_callocN(sizeof(Nurb), "BLI_editcurve_addvert new_bezt_nurb 2");
+ nurb_new->type = CU_BEZIER;
+ nurb_new->resolu = cu->resolu;
+ nurb_new->orderu = 4;
+ nurb_new->flag |= CU_SMOOTH;
+ BKE_nurb_bezierPoints_add(nurb_new, 1);
+
+ if ((cu->flag & CU_3D) == 0) {
+ nurb_new->flag |= CU_2D;
+ }
+ }
+ BLI_addtail(&editnurb->nurbs, nurb_new);
+
+ bezt_new = nurb_new->bezt;
+
+ BEZT_SEL_ALL(bezt_new);
+
+ bezt_new->h1 = HD_AUTO;
+ bezt_new->h2 = HD_AUTO;
+
+ temp[0] = 1.0f;
+ temp[1] = 0.0f;
+ temp[2] = 0.0f;
+
+ copy_v3_v3(bezt_new->vec[1], location);
+ sub_v3_v3v3(bezt_new->vec[0], bezt_new->vec[1], temp);
+ add_v3_v3v3(bezt_new->vec[2], bezt_new->vec[1], temp);
+
+ changed = true;
+ }
+ else {
+ Nurb *nurb_new;
+ BPoint *bp_new;
+
+ {
+ nurb_new = MEM_callocN(sizeof(Nurb), __func__);
+ nurb_new->type = CU_POLY;
+ nurb_new->resolu = cu->resolu;
+ nurb_new->flag |= CU_SMOOTH;
+ nurb_new->orderu = 4;
+ BKE_nurb_points_add(nurb_new, 1);
+
+ if ((cu->flag & CU_3D) == 0) {
+ nurb_new->flag |= CU_2D;
+ }
+ }
+ BLI_addtail(&editnurb->nurbs, nurb_new);
+
+ bp_new = nurb_new->bp;
+
+ bp_new->f1 |= SELECT;
+
+ copy_v3_v3(bp_new->vec, location);
+ bp_new->vec[3] = 1.0f;
+
+ BKE_nurb_knot_calc_u(nurb_new);
+
+ changed = true;
+ }
+ }
+
+ return changed;
}
static int add_vertex_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- Object *obedit = CTX_data_edit_object(C);
- View3D *v3d = CTX_wm_view3d(C);
- Curve *cu = obedit->data;
- EditNurb *editnurb = cu->editnurb;
- float location[3];
- float imat[4][4];
+ Main *bmain = CTX_data_main(C);
+ Object *obedit = CTX_data_edit_object(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ Curve *cu = obedit->data;
+ EditNurb *editnurb = cu->editnurb;
+ float location[3];
+ float imat[4][4];
- RNA_float_get_array(op->ptr, "location", location);
+ RNA_float_get_array(op->ptr, "location", location);
- invert_m4_m4(imat, obedit->obmat);
- mul_m4_v3(imat, location);
+ invert_m4_m4(imat, obedit->obmat);
+ mul_m4_v3(imat, location);
- if (ed_editcurve_addvert(cu, editnurb, v3d, location)) {
- if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
+ if (ed_editcurve_addvert(cu, editnurb, v3d, location)) {
+ if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewContext vc;
-
- ED_view3d_viewcontext_init(C, &vc);
-
- if (vc.rv3d && !RNA_struct_property_is_set(op->ptr, "location")) {
- Curve *cu;
- float location[3];
- const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) &&
- (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE));
-
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
-
- cu = vc.obedit->data;
-
- findselectedNurbvert(cu, vc.v3d, &nu, &bezt, &bp);
-
- if (bezt) {
- mul_v3_m4v3(location, vc.obedit->obmat, bezt->vec[1]);
- }
- else if (bp) {
- mul_v3_m4v3(location, vc.obedit->obmat, bp->vec);
- }
- else {
- copy_v3_v3(location, vc.scene->cursor.location);
- }
-
- ED_view3d_win_to_3d_int(vc.v3d, vc.ar, location, event->mval, location);
-
- if (use_proj) {
- const float mval[2] = {UNPACK2(event->mval)};
-
- struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- vc.bmain, vc.scene, vc.depsgraph, 0, vc.ar, vc.v3d);
-
- ED_transform_snap_object_project_view3d(
- snap_context,
- SCE_SNAP_MODE_FACE,
- &(const struct SnapObjectParams){
- .snap_select = (vc.obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL,
- .use_object_edit_cage = false,
- },
- mval, NULL,
- location, NULL);
-
-
- ED_transform_snap_object_context_destroy(snap_context);
- }
-
- if ((cu->flag & CU_3D) == 0) {
- const float eps = 1e-6f;
-
- /* get the view vector to 'location' */
- float view_dir[3];
- ED_view3d_global_to_vector(vc.rv3d, location, view_dir);
-
- /* get the plane */
- float plane[4];
- /* only normalize to avoid precision errors */
- normalize_v3_v3(plane, vc.obedit->obmat[2]);
- plane[3] = -dot_v3v3(plane, vc.obedit->obmat[3]);
-
- if (fabsf(dot_v3v3(view_dir, plane)) < eps) {
- /* can't project on an aligned plane. */
- }
- else {
- float lambda;
- if (isect_ray_plane_v3(location, view_dir, plane, &lambda, false)) {
- /* check if we're behind the viewport */
- float location_test[3];
- madd_v3_v3v3fl(location_test, location, view_dir, lambda);
- if ((vc.rv3d->is_persp == false) ||
- (mul_project_m4_v3_zfac(vc.rv3d->persmat, location_test) > 0.0f))
- {
- copy_v3_v3(location, location_test);
- }
- }
- }
- }
-
- RNA_float_set_array(op->ptr, "location", location);
- }
-
- return add_vertex_exec(C, op);
+ ViewContext vc;
+
+ ED_view3d_viewcontext_init(C, &vc);
+
+ if (vc.rv3d && !RNA_struct_property_is_set(op->ptr, "location")) {
+ Curve *cu;
+ float location[3];
+ const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) &&
+ (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE));
+
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+
+ cu = vc.obedit->data;
+
+ findselectedNurbvert(cu, vc.v3d, &nu, &bezt, &bp);
+
+ if (bezt) {
+ mul_v3_m4v3(location, vc.obedit->obmat, bezt->vec[1]);
+ }
+ else if (bp) {
+ mul_v3_m4v3(location, vc.obedit->obmat, bp->vec);
+ }
+ else {
+ copy_v3_v3(location, vc.scene->cursor.location);
+ }
+
+ ED_view3d_win_to_3d_int(vc.v3d, vc.ar, location, event->mval, location);
+
+ if (use_proj) {
+ const float mval[2] = {UNPACK2(event->mval)};
+
+ struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
+ vc.bmain, vc.scene, vc.depsgraph, 0, vc.ar, vc.v3d);
+
+ ED_transform_snap_object_project_view3d(
+ snap_context,
+ SCE_SNAP_MODE_FACE,
+ &(const struct SnapObjectParams){
+ .snap_select = (vc.obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL,
+ .use_object_edit_cage = false,
+ },
+ mval,
+ NULL,
+ location,
+ NULL);
+
+ ED_transform_snap_object_context_destroy(snap_context);
+ }
+
+ if ((cu->flag & CU_3D) == 0) {
+ const float eps = 1e-6f;
+
+ /* get the view vector to 'location' */
+ float view_dir[3];
+ ED_view3d_global_to_vector(vc.rv3d, location, view_dir);
+
+ /* get the plane */
+ float plane[4];
+ /* only normalize to avoid precision errors */
+ normalize_v3_v3(plane, vc.obedit->obmat[2]);
+ plane[3] = -dot_v3v3(plane, vc.obedit->obmat[3]);
+
+ if (fabsf(dot_v3v3(view_dir, plane)) < eps) {
+ /* can't project on an aligned plane. */
+ }
+ else {
+ float lambda;
+ if (isect_ray_plane_v3(location, view_dir, plane, &lambda, false)) {
+ /* check if we're behind the viewport */
+ float location_test[3];
+ madd_v3_v3v3fl(location_test, location, view_dir, lambda);
+ if ((vc.rv3d->is_persp == false) ||
+ (mul_project_m4_v3_zfac(vc.rv3d->persmat, location_test) > 0.0f)) {
+ copy_v3_v3(location, location_test);
+ }
+ }
+ }
+ }
+
+ RNA_float_set_array(op->ptr, "location", location);
+ }
+
+ return add_vertex_exec(C, op);
}
void CURVE_OT_vertex_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Vertex";
- ot->idname = "CURVE_OT_vertex_add";
- ot->description = "Add a new control point (linked to only selected end-curve one, if any)";
+ /* identifiers */
+ ot->name = "Add Vertex";
+ ot->idname = "CURVE_OT_vertex_add";
+ ot->description = "Add a new control point (linked to only selected end-curve one, if any)";
- /* api callbacks */
- ot->exec = add_vertex_exec;
- ot->invoke = add_vertex_invoke;
- ot->poll = ED_operator_editcurve;
+ /* api callbacks */
+ ot->exec = add_vertex_exec;
+ ot->invoke = add_vertex_invoke;
+ ot->poll = ED_operator_editcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -OBJECT_ADD_SIZE_MAXF, OBJECT_ADD_SIZE_MAXF,
- "Location", "Location to add new vertex at", -1.0e4f, 1.0e4f);
+ /* properties */
+ RNA_def_float_vector_xyz(ot->srna,
+ "location",
+ 3,
+ NULL,
+ -OBJECT_ADD_SIZE_MAXF,
+ OBJECT_ADD_SIZE_MAXF,
+ "Location",
+ "Location to add new vertex at",
+ -1.0e4f,
+ 1.0e4f);
}
/***************** extrude operator **********************/
static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
- EditNurb *editnurb = cu->editnurb;
- bool changed = false;
- bool as_curve = false;
-
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
-
- /* First test: curve? */
- if (obedit->type != OB_CURVE) {
- Nurb *nu;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- if ((nu->pntsv == 1) &&
- (ED_curve_nurb_select_count(v3d, nu) == 1))
- {
- as_curve = true;
- break;
- }
- }
- }
-
- if (obedit->type == OB_CURVE || as_curve) {
- changed = ed_editcurve_extrude(cu, editnurb, v3d);
- }
- else {
- changed = ed_editnurb_extrude_flag(editnurb, SELECT);
- }
-
- if (changed) {
- if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
-
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+ EditNurb *editnurb = cu->editnurb;
+ bool changed = false;
+ bool as_curve = false;
+
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
+
+ /* First test: curve? */
+ if (obedit->type != OB_CURVE) {
+ Nurb *nu;
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ if ((nu->pntsv == 1) && (ED_curve_nurb_select_count(v3d, nu) == 1)) {
+ as_curve = true;
+ break;
+ }
+ }
+ }
+
+ if (obedit->type == OB_CURVE || as_curve) {
+ changed = ed_editcurve_extrude(cu, editnurb, v3d);
+ }
+ else {
+ changed = ed_editnurb_extrude_flag(editnurb, SELECT);
+ }
+
+ if (changed) {
+ if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_extrude(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Extrude";
- ot->description = "Extrude selected control point(s)";
- ot->idname = "CURVE_OT_extrude";
+ /* identifiers */
+ ot->name = "Extrude";
+ ot->description = "Extrude selected control point(s)";
+ ot->idname = "CURVE_OT_extrude";
- /* api callbacks */
- ot->exec = curve_extrude_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = curve_extrude_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* to give to transform */
- RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
+ /* to give to transform */
+ RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
}
/***************** make cyclic operator **********************/
static bool curve_toggle_cyclic(View3D *v3d, ListBase *editnurb, int direction)
{
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
- bool changed = false;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->pntsu > 1 || nu->pntsv > 1) {
- if (nu->type == CU_POLY) {
- a = nu->pntsu;
- bp = nu->bp;
- while (a--) {
- if (bp->f1 & SELECT) {
- nu->flagu ^= CU_NURB_CYCLIC;
- changed = true;
- break;
- }
- bp++;
- }
- }
- else if (nu->type == CU_BEZIER) {
- a = nu->pntsu;
- bezt = nu->bezt;
- while (a--) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- nu->flagu ^= CU_NURB_CYCLIC;
- changed = true;
- break;
- }
- bezt++;
- }
- BKE_nurb_handles_calc(nu);
- }
- else if (nu->pntsv == 1 && nu->type == CU_NURBS) {
- if (nu->knotsu) { /* if check_valid_nurb_u fails the knotsu can be NULL */
- a = nu->pntsu;
- bp = nu->bp;
- while (a--) {
- if (bp->f1 & SELECT) {
- nu->flagu ^= CU_NURB_CYCLIC;
- /* 1==u type is ignored for cyclic curves */
- BKE_nurb_knot_calc_u(nu);
- changed = true;
- break;
- }
- bp++;
- }
- }
- }
- else if (nu->type == CU_NURBS) {
- a = nu->pntsu * nu->pntsv;
- bp = nu->bp;
- while (a--) {
-
- if (bp->f1 & SELECT) {
- if (direction == 0 && nu->pntsu > 1) {
- nu->flagu ^= CU_NURB_CYCLIC;
- /* 1==u type is ignored for cyclic curves */
- BKE_nurb_knot_calc_u(nu);
- changed = true;
- }
- if (direction == 1 && nu->pntsv > 1) {
- nu->flagv ^= CU_NURB_CYCLIC;
- /* 2==v type is ignored for cyclic curves */
- BKE_nurb_knot_calc_v(nu);
- changed = true;
- }
- break;
- }
- bp++;
- }
- }
- }
- }
- return changed;
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+ bool changed = false;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->pntsu > 1 || nu->pntsv > 1) {
+ if (nu->type == CU_POLY) {
+ a = nu->pntsu;
+ bp = nu->bp;
+ while (a--) {
+ if (bp->f1 & SELECT) {
+ nu->flagu ^= CU_NURB_CYCLIC;
+ changed = true;
+ break;
+ }
+ bp++;
+ }
+ }
+ else if (nu->type == CU_BEZIER) {
+ a = nu->pntsu;
+ bezt = nu->bezt;
+ while (a--) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ nu->flagu ^= CU_NURB_CYCLIC;
+ changed = true;
+ break;
+ }
+ bezt++;
+ }
+ BKE_nurb_handles_calc(nu);
+ }
+ else if (nu->pntsv == 1 && nu->type == CU_NURBS) {
+ if (nu->knotsu) { /* if check_valid_nurb_u fails the knotsu can be NULL */
+ a = nu->pntsu;
+ bp = nu->bp;
+ while (a--) {
+ if (bp->f1 & SELECT) {
+ nu->flagu ^= CU_NURB_CYCLIC;
+ /* 1==u type is ignored for cyclic curves */
+ BKE_nurb_knot_calc_u(nu);
+ changed = true;
+ break;
+ }
+ bp++;
+ }
+ }
+ }
+ else if (nu->type == CU_NURBS) {
+ a = nu->pntsu * nu->pntsv;
+ bp = nu->bp;
+ while (a--) {
+
+ if (bp->f1 & SELECT) {
+ if (direction == 0 && nu->pntsu > 1) {
+ nu->flagu ^= CU_NURB_CYCLIC;
+ /* 1==u type is ignored for cyclic curves */
+ BKE_nurb_knot_calc_u(nu);
+ changed = true;
+ }
+ if (direction == 1 && nu->pntsv > 1) {
+ nu->flagv ^= CU_NURB_CYCLIC;
+ /* 2==v type is ignored for cyclic curves */
+ BKE_nurb_knot_calc_v(nu);
+ changed = true;
+ }
+ break;
+ }
+ bp++;
+ }
+ }
+ }
+ }
+ return changed;
}
static int toggle_cyclic_exec(bContext *C, wmOperator *op)
{
- const int direction = RNA_enum_get(op->ptr, "direction");
- View3D *v3d = CTX_wm_view3d(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- bool changed_multi = false;
+ const int direction = RNA_enum_get(op->ptr, "direction");
+ View3D *v3d = CTX_wm_view3d(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ bool changed_multi = false;
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
- ListBase *editnurb = object_editcurve_get(obedit);
- if (curve_toggle_cyclic(v3d, editnurb, direction)) {
- changed_multi = true;
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- }
- MEM_freeN(objects);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ if (curve_toggle_cyclic(v3d, editnurb, direction)) {
+ changed_multi = true;
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ }
+ MEM_freeN(objects);
- return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
static int toggle_cyclic_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- uiPopupMenu *pup;
- uiLayout *layout;
- Nurb *nu;
-
- if (obedit->type == OB_SURF) {
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->pntsu > 1 || nu->pntsv > 1) {
- if (nu->type == CU_NURBS) {
- pup = UI_popup_menu_begin(C, IFACE_("Direction"), ICON_NONE);
- layout = UI_popup_menu_layout(pup);
- uiItemsEnumO(layout, op->type->idname, "direction");
- UI_popup_menu_end(C, pup);
- return OPERATOR_INTERFACE;
- }
- }
- }
- }
-
- return toggle_cyclic_exec(C, op);
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ uiPopupMenu *pup;
+ uiLayout *layout;
+ Nurb *nu;
+
+ if (obedit->type == OB_SURF) {
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->pntsu > 1 || nu->pntsv > 1) {
+ if (nu->type == CU_NURBS) {
+ pup = UI_popup_menu_begin(C, IFACE_("Direction"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ uiItemsEnumO(layout, op->type->idname, "direction");
+ UI_popup_menu_end(C, pup);
+ return OPERATOR_INTERFACE;
+ }
+ }
+ }
+ }
+
+ return toggle_cyclic_exec(C, op);
}
void CURVE_OT_cyclic_toggle(wmOperatorType *ot)
{
- static const EnumPropertyItem direction_items[] = {
- {0, "CYCLIC_U", 0, "Cyclic U", ""},
- {1, "CYCLIC_V", 0, "Cyclic V", ""},
- {0, NULL, 0, NULL, NULL},
- };
+ static const EnumPropertyItem direction_items[] = {
+ {0, "CYCLIC_U", 0, "Cyclic U", ""},
+ {1, "CYCLIC_V", 0, "Cyclic V", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
- /* identifiers */
- ot->name = "Toggle Cyclic";
- ot->description = "Make active spline closed/opened loop";
- ot->idname = "CURVE_OT_cyclic_toggle";
+ /* identifiers */
+ ot->name = "Toggle Cyclic";
+ ot->description = "Make active spline closed/opened loop";
+ ot->idname = "CURVE_OT_cyclic_toggle";
- /* api callbacks */
- ot->exec = toggle_cyclic_exec;
- ot->invoke = toggle_cyclic_invoke;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = toggle_cyclic_exec;
+ ot->invoke = toggle_cyclic_invoke;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to make surface cyclic in");
+ /* properties */
+ RNA_def_enum(ot->srna,
+ "direction",
+ direction_items,
+ 0,
+ "Direction",
+ "Direction to make surface cyclic in");
}
/********************** add duplicate operator *********************/
static int duplicate_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- int ok = -1;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ int ok = -1;
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
- ListBase newnurb = {NULL, NULL};
- adduplicateflagNurb(obedit, v3d, &newnurb, SELECT, false);
+ ListBase newnurb = {NULL, NULL};
+ adduplicateflagNurb(obedit, v3d, &newnurb, SELECT, false);
- if (BLI_listbase_is_empty(&newnurb)) {
- ok = MAX2(ok, 0);
- continue;
- }
+ if (BLI_listbase_is_empty(&newnurb)) {
+ ok = MAX2(ok, 0);
+ continue;
+ }
- ok = 1;
- BLI_movelisttolist(object_editcurve_get(obedit), &newnurb);
- DEG_id_tag_update(&cu->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, &cu->id);
- }
- MEM_freeN(objects);
+ ok = 1;
+ BLI_movelisttolist(object_editcurve_get(obedit), &newnurb);
+ DEG_id_tag_update(&cu->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, &cu->id);
+ }
+ MEM_freeN(objects);
- if (ok == 0) {
- BKE_report(op->reports, RPT_ERROR, "Cannot duplicate current selection");
- return OPERATOR_CANCELLED;
- }
- return OPERATOR_FINISHED;
+ if (ok == 0) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot duplicate current selection");
+ return OPERATOR_CANCELLED;
+ }
+ return OPERATOR_FINISHED;
}
void CURVE_OT_duplicate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Duplicate Curve";
- ot->description = "Duplicate selected control points";
- ot->idname = "CURVE_OT_duplicate";
+ /* identifiers */
+ ot->name = "Duplicate Curve";
+ ot->description = "Duplicate selected control points";
+ ot->idname = "CURVE_OT_duplicate";
- /* api callbacks */
- ot->exec = duplicate_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = duplicate_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/********************** delete operator *********************/
static bool curve_delete_vertices(Object *obedit, View3D *v3d)
{
- if (obedit->type == OB_SURF) {
- ed_surf_delete_selected(obedit);
- }
- else {
- ed_curve_delete_selected(obedit, v3d);
- }
+ if (obedit->type == OB_SURF) {
+ ed_surf_delete_selected(obedit);
+ }
+ else {
+ ed_curve_delete_selected(obedit, v3d);
+ }
- return true;
+ return true;
}
static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split)
{
- Curve *cu = obedit->data;
- EditNurb *editnurb = cu->editnurb;
- ListBase *nubase = &editnurb->nurbs, newnurb = {NULL, NULL};
- Nurb *nu, *nu1;
- BezTriple *bezt, *bezt1, *bezt2;
- BPoint *bp, *bp1, *bp2;
- int a, b, starta, enda, cut, cyclicut;
-
- for (nu = nubase->first; nu; nu = nu->next) {
- nu1 = NULL;
- starta = enda = cut = -1;
- cyclicut = 0;
-
- if (nu->type == CU_BEZIER) {
- for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
- if (!BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- enda = a;
- if (starta == -1) {
- starta = a;
- }
- if (a < nu->pntsu - 1) {
- continue;
- }
- }
- else if (a < nu->pntsu - 1 && !BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt + 1)) {
- /* if just single selected point then continue */
- continue;
- }
-
- if (starta >= 0) {
- /* got selected segment, now check where and copy */
- if (starta <= 1 && a == nu->pntsu - 1) {
- /* copying all points in spline */
- if (starta == 1 && enda != a) {
- nu->flagu &= ~CU_NURB_CYCLIC;
- }
-
- starta = 0;
- enda = a;
- cut = enda - starta + 1;
- nu1 = BKE_nurb_copy(nu, cut, 1);
- }
- else if (starta == 0) {
- /* if start of curve copy next end point */
- enda++;
- cut = enda - starta + 1;
- bezt1 = &nu->bezt[nu->pntsu - 1];
- bezt2 = &nu->bezt[nu->pntsu - 2];
-
- if ((nu->flagu & CU_NURB_CYCLIC) &&
- BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1) &&
- BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt2))
- {
- /* check if need to join start of spline to end */
- nu1 = BKE_nurb_copy(nu, cut + 1, 1);
- ED_curve_beztcpy(editnurb, &nu1->bezt[1], nu->bezt, cut);
- starta = nu->pntsu - 1;
- cut = 1;
- }
- else {
- if (nu->flagu & CU_NURB_CYCLIC) {
- cyclicut = cut;
- }
- else {
- nu1 = BKE_nurb_copy(nu, cut, 1);
- }
- }
- }
- else if (enda == nu->pntsu - 1) {
- /* if end of curve copy previous start point */
- starta--;
- cut = enda - starta + 1;
- bezt1 = nu->bezt;
- bezt2 = &nu->bezt[1];
-
- if ((nu->flagu & CU_NURB_CYCLIC) &&
- BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1) &&
- BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt2))
- {
- /* check if need to join start of spline to end */
- nu1 = BKE_nurb_copy(nu, cut + 1, 1);
- ED_curve_beztcpy(editnurb, &nu1->bezt[cut], nu->bezt, 1);
- }
- else if (cyclicut != 0) {
- /* if cyclicut exists it is a cyclic spline, start and end should be connected */
- nu1 = BKE_nurb_copy(nu, cut + cyclicut, 1);
- ED_curve_beztcpy(editnurb, &nu1->bezt[cut], nu->bezt, cyclicut);
- cyclicut = 0;
- }
- else {
- nu1 = BKE_nurb_copy(nu, cut, 1);
- }
- }
- else {
- /* mid spline selection, copy adjacent start and end */
- starta--;
- enda++;
- cut = enda - starta + 1;
- nu1 = BKE_nurb_copy(nu, cut, 1);
- }
-
- if (nu1 != NULL) {
- ED_curve_beztcpy(editnurb, nu1->bezt, &nu->bezt[starta], cut);
- BLI_addtail(&newnurb, nu1);
-
- if (starta != 0 || enda != nu->pntsu - 1) {
- nu1->flagu &= ~CU_NURB_CYCLIC;
- }
- nu1 = NULL;
- }
- starta = enda = -1;
- }
- }
-
- if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) {
- /* start and points copied if connecting segment was deleted and not cylic spline */
- bezt1 = nu->bezt;
- bezt2 = &nu->bezt[1];
-
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1) &&
- BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt2))
- {
- nu1 = BKE_nurb_copy(nu, 1, 1);
- ED_curve_beztcpy(editnurb, nu1->bezt, bezt1, 1);
- BLI_addtail(&newnurb, nu1);
- }
-
- bezt1 = &nu->bezt[nu->pntsu - 1];
- bezt2 = &nu->bezt[nu->pntsu - 2];
-
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1) &&
- BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt2))
- {
- nu1 = BKE_nurb_copy(nu, 1, 1);
- ED_curve_beztcpy(editnurb, nu1->bezt, bezt1, 1);
- BLI_addtail(&newnurb, nu1);
- }
- }
- }
- else if (nu->pntsv >= 1) {
- int u, v;
-
- if (isNurbselV(nu, &u, SELECT)) {
- for (a = 0, bp = nu->bp; a < nu->pntsu; a++, bp++) {
- if (!(bp->f1 & SELECT)) {
- enda = a;
- if (starta == -1) {
- starta = a;
- }
- if (a < nu->pntsu - 1) {
- continue;
- }
- }
- else if (a < nu->pntsu - 1 && !((bp + 1)->f1 & SELECT)) {
- /* if just single selected point then continue */
- continue;
- }
-
- if (starta >= 0) {
- /* got selected segment, now check where and copy */
- if (starta <= 1 && a == nu->pntsu - 1) {
- /* copying all points in spline */
- if (starta == 1 && enda != a) {
- nu->flagu &= ~CU_NURB_CYCLIC;
- }
-
- starta = 0;
- enda = a;
- cut = enda - starta + 1;
- nu1 = BKE_nurb_copy(nu, cut, nu->pntsv);
- }
- else if (starta == 0) {
- /* if start of curve copy next end point */
- enda++;
- cut = enda - starta + 1;
- bp1 = &nu->bp[nu->pntsu - 1];
- bp2 = &nu->bp[nu->pntsu - 2];
-
- if ((nu->flagu & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
- /* check if need to join start of spline to end */
- nu1 = BKE_nurb_copy(nu, cut + 1, nu->pntsv);
- for (b = 0; b < nu->pntsv; b++) {
- ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu + 1], &nu->bp[b * nu->pntsu], cut);
- }
- starta = nu->pntsu - 1;
- cut = 1;
- }
- else {
- if (nu->flagu & CU_NURB_CYCLIC) {
- cyclicut = cut;
- }
- else {
- nu1 = BKE_nurb_copy(nu, cut, nu->pntsv);
- }
- }
- }
- else if (enda == nu->pntsu - 1) {
- /* if end of curve copy previous start point */
- starta--;
- cut = enda - starta + 1;
- bp1 = nu->bp;
- bp2 = &nu->bp[1];
-
- if ((nu->flagu & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
- /* check if need to join start of spline to end */
- nu1 = BKE_nurb_copy(nu, cut + 1, nu->pntsv);
- for (b = 0; b < nu->pntsv; b++) {
- ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu + cut], &nu->bp[b * nu->pntsu], 1);
- }
- }
- else if (cyclicut != 0) {
- /* if cyclicut exists it is a cyclic spline, start and end should be connected */
- nu1 = BKE_nurb_copy(nu, cut + cyclicut, nu->pntsv);
- for (b = 0; b < nu->pntsv; b++) {
- ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu + cut], &nu->bp[b * nu->pntsu], cyclicut);
- }
- }
- else {
- nu1 = BKE_nurb_copy(nu, cut, nu->pntsv);
- }
- }
- else {
- /* mid spline selection, copy adjacent start and end */
- starta--;
- enda++;
- cut = enda - starta + 1;
- nu1 = BKE_nurb_copy(nu, cut, nu->pntsv);
- }
-
- if (nu1 != NULL) {
- for (b = 0; b < nu->pntsv; b++) {
- ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu], &nu->bp[b * nu->pntsu + starta], cut);
- }
- BLI_addtail(&newnurb, nu1);
-
- if (starta != 0 || enda != nu->pntsu - 1) {
- nu1->flagu &= ~CU_NURB_CYCLIC;
- }
- nu1 = NULL;
- }
- starta = enda = -1;
- }
- }
-
- if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) {
- /* start and points copied if connecting segment was deleted and not cylic spline */
- bp1 = nu->bp;
- bp2 = &nu->bp[1];
-
- if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
- nu1 = BKE_nurb_copy(nu, 1, nu->pntsv);
- for (b = 0; b < nu->pntsv; b++) {
- ED_curve_bpcpy(editnurb, &nu1->bp[b], &nu->bp[b * nu->pntsu], 1);
- }
- BLI_addtail(&newnurb, nu1);
- }
-
- bp1 = &nu->bp[nu->pntsu - 1];
- bp2 = &nu->bp[nu->pntsu - 2];
-
- if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
- nu1 = BKE_nurb_copy(nu, 1, nu->pntsv);
- for (b = 0; b < nu->pntsv; b++) {
- ED_curve_bpcpy(editnurb, &nu1->bp[b], &nu->bp[b * nu->pntsu + nu->pntsu - 1], 1);
- }
- BLI_addtail(&newnurb, nu1);
- }
- }
- }
- else if (isNurbselU(nu, &v, SELECT)) {
- for (a = 0, bp = nu->bp; a < nu->pntsv; a++, bp += nu->pntsu) {
- if (!(bp->f1 & SELECT)) {
- enda = a;
- if (starta == -1) {
- starta = a;
- }
- if (a < nu->pntsv - 1) {
- continue;
- }
- }
- else if (a < nu->pntsv - 1 && !((bp + nu->pntsu)->f1 & SELECT)) {
- /* if just single selected point then continue */
- continue;
- }
-
- if (starta >= 0) {
- /* got selected segment, now check where and copy */
- if (starta <= 1 && a == nu->pntsv - 1) {
- /* copying all points in spline */
- if (starta == 1 && enda != a) {
- nu->flagv &= ~CU_NURB_CYCLIC;
- }
-
- starta = 0;
- enda = a;
- cut = enda - starta + 1;
- nu1 = BKE_nurb_copy(nu, nu->pntsu, cut);
- }
- else if (starta == 0) {
- /* if start of curve copy next end point */
- enda++;
- cut = enda - starta + 1;
- bp1 = &nu->bp[nu->pntsv * nu->pntsu - nu->pntsu];
- bp2 = &nu->bp[nu->pntsv * nu->pntsu - (nu->pntsu * 2)];
-
- if ((nu->flagv & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
- /* check if need to join start of spline to end */
- nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + 1);
- ED_curve_bpcpy(editnurb, &nu1->bp[nu->pntsu], nu->bp, cut * nu->pntsu);
- starta = nu->pntsv - 1;
- cut = 1;
- }
- else {
- if (nu->flagv & CU_NURB_CYCLIC) {
- cyclicut = cut;
- }
- else {
- nu1 = BKE_nurb_copy(nu, nu->pntsu, cut);
- }
- }
- }
- else if (enda == nu->pntsv - 1) {
- /* if end of curve copy previous start point */
- starta--;
- cut = enda - starta + 1;
- bp1 = nu->bp;
- bp2 = &nu->bp[nu->pntsu];
-
- if ((nu->flagv & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
- /* check if need to join start of spline to end */
- nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + 1);
- ED_curve_bpcpy(editnurb, &nu1->bp[cut * nu->pntsu], nu->bp, nu->pntsu);
- }
- else if (cyclicut != 0) {
- /* if cyclicut exists it is a cyclic spline, start and end should be connected */
- nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + cyclicut);
- ED_curve_bpcpy(editnurb, &nu1->bp[cut * nu->pntsu], nu->bp, nu->pntsu * cyclicut);
- cyclicut = 0;
- }
- else {
- nu1 = BKE_nurb_copy(nu, nu->pntsu, cut);
- }
- }
- else {
- /* mid spline selection, copy adjacent start and end */
- starta--;
- enda++;
- cut = enda - starta + 1;
- nu1 = BKE_nurb_copy(nu, nu->pntsu, cut);
- }
-
- if (nu1 != NULL) {
- ED_curve_bpcpy(editnurb, nu1->bp, &nu->bp[starta * nu->pntsu], cut * nu->pntsu);
- BLI_addtail(&newnurb, nu1);
-
- if (starta != 0 || enda != nu->pntsv - 1) {
- nu1->flagv &= ~CU_NURB_CYCLIC;
- }
- nu1 = NULL;
- }
- starta = enda = -1;
- }
- }
-
- if (!split && cut != -1 && nu->pntsv > 2 && !(nu->flagv & CU_NURB_CYCLIC)) {
- /* start and points copied if connecting segment was deleted and not cylic spline */
- bp1 = nu->bp;
- bp2 = &nu->bp[nu->pntsu];
-
- if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
- nu1 = BKE_nurb_copy(nu, nu->pntsu, 1);
- ED_curve_bpcpy(editnurb, nu1->bp, nu->bp, nu->pntsu);
- BLI_addtail(&newnurb, nu1);
- }
-
- bp1 = &nu->bp[nu->pntsu * nu->pntsv - nu->pntsu];
- bp2 = &nu->bp[nu->pntsu * nu->pntsv - (nu->pntsu * 2)];
-
- if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
- nu1 = BKE_nurb_copy(nu, nu->pntsu, 1);
- ED_curve_bpcpy(editnurb, nu1->bp, &nu->bp[nu->pntsu * nu->pntsv - nu->pntsu], nu->pntsu);
- BLI_addtail(&newnurb, nu1);
- }
- }
- }
- else {
- /* selection not valid, just copy nurb to new list */
- nu1 = BKE_nurb_copy(nu, nu->pntsu, nu->pntsv);
- ED_curve_bpcpy(editnurb, nu1->bp, nu->bp, nu->pntsu * nu->pntsv);
- BLI_addtail(&newnurb, nu1);
- }
- }
- }
-
- for (nu = newnurb.first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- if (split) {
- /* deselect for split operator */
- for (b = 0, bezt1 = nu->bezt; b < nu->pntsu; b++, bezt1++) {
- select_beztriple(bezt1, DESELECT, SELECT, true);
- }
- }
-
- BKE_nurb_handles_calc(nu);
- }
- else {
- if (split) {
- /* deselect for split operator */
- for (b = 0, bp1 = nu->bp; b < nu->pntsu * nu->pntsv; b++, bp1++) {
- select_bpoint(bp1, DESELECT, SELECT, HIDDEN);
- }
- }
-
- BKE_nurb_order_clamp_u(nu);
- BKE_nurb_knot_calc_u(nu);
-
- if (nu->pntsv > 1) {
- BKE_nurb_order_clamp_v(nu);
- BKE_nurb_knot_calc_v(nu);
- }
- }
- }
-
- keyIndex_delNurbList(editnurb, nubase);
- BKE_nurbList_free(nubase);
- BLI_movelisttolist(nubase, &newnurb);
-
- return true;
+ Curve *cu = obedit->data;
+ EditNurb *editnurb = cu->editnurb;
+ ListBase *nubase = &editnurb->nurbs, newnurb = {NULL, NULL};
+ Nurb *nu, *nu1;
+ BezTriple *bezt, *bezt1, *bezt2;
+ BPoint *bp, *bp1, *bp2;
+ int a, b, starta, enda, cut, cyclicut;
+
+ for (nu = nubase->first; nu; nu = nu->next) {
+ nu1 = NULL;
+ starta = enda = cut = -1;
+ cyclicut = 0;
+
+ if (nu->type == CU_BEZIER) {
+ for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
+ if (!BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ enda = a;
+ if (starta == -1) {
+ starta = a;
+ }
+ if (a < nu->pntsu - 1) {
+ continue;
+ }
+ }
+ else if (a < nu->pntsu - 1 && !BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt + 1)) {
+ /* if just single selected point then continue */
+ continue;
+ }
+
+ if (starta >= 0) {
+ /* got selected segment, now check where and copy */
+ if (starta <= 1 && a == nu->pntsu - 1) {
+ /* copying all points in spline */
+ if (starta == 1 && enda != a) {
+ nu->flagu &= ~CU_NURB_CYCLIC;
+ }
+
+ starta = 0;
+ enda = a;
+ cut = enda - starta + 1;
+ nu1 = BKE_nurb_copy(nu, cut, 1);
+ }
+ else if (starta == 0) {
+ /* if start of curve copy next end point */
+ enda++;
+ cut = enda - starta + 1;
+ bezt1 = &nu->bezt[nu->pntsu - 1];
+ bezt2 = &nu->bezt[nu->pntsu - 2];
+
+ if ((nu->flagu & CU_NURB_CYCLIC) && BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1) &&
+ BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt2)) {
+ /* check if need to join start of spline to end */
+ nu1 = BKE_nurb_copy(nu, cut + 1, 1);
+ ED_curve_beztcpy(editnurb, &nu1->bezt[1], nu->bezt, cut);
+ starta = nu->pntsu - 1;
+ cut = 1;
+ }
+ else {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ cyclicut = cut;
+ }
+ else {
+ nu1 = BKE_nurb_copy(nu, cut, 1);
+ }
+ }
+ }
+ else if (enda == nu->pntsu - 1) {
+ /* if end of curve copy previous start point */
+ starta--;
+ cut = enda - starta + 1;
+ bezt1 = nu->bezt;
+ bezt2 = &nu->bezt[1];
+
+ if ((nu->flagu & CU_NURB_CYCLIC) && BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1) &&
+ BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt2)) {
+ /* check if need to join start of spline to end */
+ nu1 = BKE_nurb_copy(nu, cut + 1, 1);
+ ED_curve_beztcpy(editnurb, &nu1->bezt[cut], nu->bezt, 1);
+ }
+ else if (cyclicut != 0) {
+ /* if cyclicut exists it is a cyclic spline, start and end should be connected */
+ nu1 = BKE_nurb_copy(nu, cut + cyclicut, 1);
+ ED_curve_beztcpy(editnurb, &nu1->bezt[cut], nu->bezt, cyclicut);
+ cyclicut = 0;
+ }
+ else {
+ nu1 = BKE_nurb_copy(nu, cut, 1);
+ }
+ }
+ else {
+ /* mid spline selection, copy adjacent start and end */
+ starta--;
+ enda++;
+ cut = enda - starta + 1;
+ nu1 = BKE_nurb_copy(nu, cut, 1);
+ }
+
+ if (nu1 != NULL) {
+ ED_curve_beztcpy(editnurb, nu1->bezt, &nu->bezt[starta], cut);
+ BLI_addtail(&newnurb, nu1);
+
+ if (starta != 0 || enda != nu->pntsu - 1) {
+ nu1->flagu &= ~CU_NURB_CYCLIC;
+ }
+ nu1 = NULL;
+ }
+ starta = enda = -1;
+ }
+ }
+
+ if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) {
+ /* start and points copied if connecting segment was deleted and not cylic spline */
+ bezt1 = nu->bezt;
+ bezt2 = &nu->bezt[1];
+
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1) && BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt2)) {
+ nu1 = BKE_nurb_copy(nu, 1, 1);
+ ED_curve_beztcpy(editnurb, nu1->bezt, bezt1, 1);
+ BLI_addtail(&newnurb, nu1);
+ }
+
+ bezt1 = &nu->bezt[nu->pntsu - 1];
+ bezt2 = &nu->bezt[nu->pntsu - 2];
+
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1) && BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt2)) {
+ nu1 = BKE_nurb_copy(nu, 1, 1);
+ ED_curve_beztcpy(editnurb, nu1->bezt, bezt1, 1);
+ BLI_addtail(&newnurb, nu1);
+ }
+ }
+ }
+ else if (nu->pntsv >= 1) {
+ int u, v;
+
+ if (isNurbselV(nu, &u, SELECT)) {
+ for (a = 0, bp = nu->bp; a < nu->pntsu; a++, bp++) {
+ if (!(bp->f1 & SELECT)) {
+ enda = a;
+ if (starta == -1) {
+ starta = a;
+ }
+ if (a < nu->pntsu - 1) {
+ continue;
+ }
+ }
+ else if (a < nu->pntsu - 1 && !((bp + 1)->f1 & SELECT)) {
+ /* if just single selected point then continue */
+ continue;
+ }
+
+ if (starta >= 0) {
+ /* got selected segment, now check where and copy */
+ if (starta <= 1 && a == nu->pntsu - 1) {
+ /* copying all points in spline */
+ if (starta == 1 && enda != a) {
+ nu->flagu &= ~CU_NURB_CYCLIC;
+ }
+
+ starta = 0;
+ enda = a;
+ cut = enda - starta + 1;
+ nu1 = BKE_nurb_copy(nu, cut, nu->pntsv);
+ }
+ else if (starta == 0) {
+ /* if start of curve copy next end point */
+ enda++;
+ cut = enda - starta + 1;
+ bp1 = &nu->bp[nu->pntsu - 1];
+ bp2 = &nu->bp[nu->pntsu - 2];
+
+ if ((nu->flagu & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
+ /* check if need to join start of spline to end */
+ nu1 = BKE_nurb_copy(nu, cut + 1, nu->pntsv);
+ for (b = 0; b < nu->pntsv; b++) {
+ ED_curve_bpcpy(
+ editnurb, &nu1->bp[b * nu1->pntsu + 1], &nu->bp[b * nu->pntsu], cut);
+ }
+ starta = nu->pntsu - 1;
+ cut = 1;
+ }
+ else {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ cyclicut = cut;
+ }
+ else {
+ nu1 = BKE_nurb_copy(nu, cut, nu->pntsv);
+ }
+ }
+ }
+ else if (enda == nu->pntsu - 1) {
+ /* if end of curve copy previous start point */
+ starta--;
+ cut = enda - starta + 1;
+ bp1 = nu->bp;
+ bp2 = &nu->bp[1];
+
+ if ((nu->flagu & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
+ /* check if need to join start of spline to end */
+ nu1 = BKE_nurb_copy(nu, cut + 1, nu->pntsv);
+ for (b = 0; b < nu->pntsv; b++) {
+ ED_curve_bpcpy(
+ editnurb, &nu1->bp[b * nu1->pntsu + cut], &nu->bp[b * nu->pntsu], 1);
+ }
+ }
+ else if (cyclicut != 0) {
+ /* if cyclicut exists it is a cyclic spline, start and end should be connected */
+ nu1 = BKE_nurb_copy(nu, cut + cyclicut, nu->pntsv);
+ for (b = 0; b < nu->pntsv; b++) {
+ ED_curve_bpcpy(
+ editnurb, &nu1->bp[b * nu1->pntsu + cut], &nu->bp[b * nu->pntsu], cyclicut);
+ }
+ }
+ else {
+ nu1 = BKE_nurb_copy(nu, cut, nu->pntsv);
+ }
+ }
+ else {
+ /* mid spline selection, copy adjacent start and end */
+ starta--;
+ enda++;
+ cut = enda - starta + 1;
+ nu1 = BKE_nurb_copy(nu, cut, nu->pntsv);
+ }
+
+ if (nu1 != NULL) {
+ for (b = 0; b < nu->pntsv; b++) {
+ ED_curve_bpcpy(
+ editnurb, &nu1->bp[b * nu1->pntsu], &nu->bp[b * nu->pntsu + starta], cut);
+ }
+ BLI_addtail(&newnurb, nu1);
+
+ if (starta != 0 || enda != nu->pntsu - 1) {
+ nu1->flagu &= ~CU_NURB_CYCLIC;
+ }
+ nu1 = NULL;
+ }
+ starta = enda = -1;
+ }
+ }
+
+ if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) {
+ /* start and points copied if connecting segment was deleted and not cylic spline */
+ bp1 = nu->bp;
+ bp2 = &nu->bp[1];
+
+ if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
+ nu1 = BKE_nurb_copy(nu, 1, nu->pntsv);
+ for (b = 0; b < nu->pntsv; b++) {
+ ED_curve_bpcpy(editnurb, &nu1->bp[b], &nu->bp[b * nu->pntsu], 1);
+ }
+ BLI_addtail(&newnurb, nu1);
+ }
+
+ bp1 = &nu->bp[nu->pntsu - 1];
+ bp2 = &nu->bp[nu->pntsu - 2];
+
+ if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
+ nu1 = BKE_nurb_copy(nu, 1, nu->pntsv);
+ for (b = 0; b < nu->pntsv; b++) {
+ ED_curve_bpcpy(editnurb, &nu1->bp[b], &nu->bp[b * nu->pntsu + nu->pntsu - 1], 1);
+ }
+ BLI_addtail(&newnurb, nu1);
+ }
+ }
+ }
+ else if (isNurbselU(nu, &v, SELECT)) {
+ for (a = 0, bp = nu->bp; a < nu->pntsv; a++, bp += nu->pntsu) {
+ if (!(bp->f1 & SELECT)) {
+ enda = a;
+ if (starta == -1) {
+ starta = a;
+ }
+ if (a < nu->pntsv - 1) {
+ continue;
+ }
+ }
+ else if (a < nu->pntsv - 1 && !((bp + nu->pntsu)->f1 & SELECT)) {
+ /* if just single selected point then continue */
+ continue;
+ }
+
+ if (starta >= 0) {
+ /* got selected segment, now check where and copy */
+ if (starta <= 1 && a == nu->pntsv - 1) {
+ /* copying all points in spline */
+ if (starta == 1 && enda != a) {
+ nu->flagv &= ~CU_NURB_CYCLIC;
+ }
+
+ starta = 0;
+ enda = a;
+ cut = enda - starta + 1;
+ nu1 = BKE_nurb_copy(nu, nu->pntsu, cut);
+ }
+ else if (starta == 0) {
+ /* if start of curve copy next end point */
+ enda++;
+ cut = enda - starta + 1;
+ bp1 = &nu->bp[nu->pntsv * nu->pntsu - nu->pntsu];
+ bp2 = &nu->bp[nu->pntsv * nu->pntsu - (nu->pntsu * 2)];
+
+ if ((nu->flagv & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
+ /* check if need to join start of spline to end */
+ nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + 1);
+ ED_curve_bpcpy(editnurb, &nu1->bp[nu->pntsu], nu->bp, cut * nu->pntsu);
+ starta = nu->pntsv - 1;
+ cut = 1;
+ }
+ else {
+ if (nu->flagv & CU_NURB_CYCLIC) {
+ cyclicut = cut;
+ }
+ else {
+ nu1 = BKE_nurb_copy(nu, nu->pntsu, cut);
+ }
+ }
+ }
+ else if (enda == nu->pntsv - 1) {
+ /* if end of curve copy previous start point */
+ starta--;
+ cut = enda - starta + 1;
+ bp1 = nu->bp;
+ bp2 = &nu->bp[nu->pntsu];
+
+ if ((nu->flagv & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
+ /* check if need to join start of spline to end */
+ nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + 1);
+ ED_curve_bpcpy(editnurb, &nu1->bp[cut * nu->pntsu], nu->bp, nu->pntsu);
+ }
+ else if (cyclicut != 0) {
+ /* if cyclicut exists it is a cyclic spline, start and end should be connected */
+ nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + cyclicut);
+ ED_curve_bpcpy(editnurb, &nu1->bp[cut * nu->pntsu], nu->bp, nu->pntsu * cyclicut);
+ cyclicut = 0;
+ }
+ else {
+ nu1 = BKE_nurb_copy(nu, nu->pntsu, cut);
+ }
+ }
+ else {
+ /* mid spline selection, copy adjacent start and end */
+ starta--;
+ enda++;
+ cut = enda - starta + 1;
+ nu1 = BKE_nurb_copy(nu, nu->pntsu, cut);
+ }
+
+ if (nu1 != NULL) {
+ ED_curve_bpcpy(editnurb, nu1->bp, &nu->bp[starta * nu->pntsu], cut * nu->pntsu);
+ BLI_addtail(&newnurb, nu1);
+
+ if (starta != 0 || enda != nu->pntsv - 1) {
+ nu1->flagv &= ~CU_NURB_CYCLIC;
+ }
+ nu1 = NULL;
+ }
+ starta = enda = -1;
+ }
+ }
+
+ if (!split && cut != -1 && nu->pntsv > 2 && !(nu->flagv & CU_NURB_CYCLIC)) {
+ /* start and points copied if connecting segment was deleted and not cylic spline */
+ bp1 = nu->bp;
+ bp2 = &nu->bp[nu->pntsu];
+
+ if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
+ nu1 = BKE_nurb_copy(nu, nu->pntsu, 1);
+ ED_curve_bpcpy(editnurb, nu1->bp, nu->bp, nu->pntsu);
+ BLI_addtail(&newnurb, nu1);
+ }
+
+ bp1 = &nu->bp[nu->pntsu * nu->pntsv - nu->pntsu];
+ bp2 = &nu->bp[nu->pntsu * nu->pntsv - (nu->pntsu * 2)];
+
+ if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) {
+ nu1 = BKE_nurb_copy(nu, nu->pntsu, 1);
+ ED_curve_bpcpy(
+ editnurb, nu1->bp, &nu->bp[nu->pntsu * nu->pntsv - nu->pntsu], nu->pntsu);
+ BLI_addtail(&newnurb, nu1);
+ }
+ }
+ }
+ else {
+ /* selection not valid, just copy nurb to new list */
+ nu1 = BKE_nurb_copy(nu, nu->pntsu, nu->pntsv);
+ ED_curve_bpcpy(editnurb, nu1->bp, nu->bp, nu->pntsu * nu->pntsv);
+ BLI_addtail(&newnurb, nu1);
+ }
+ }
+ }
+
+ for (nu = newnurb.first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ if (split) {
+ /* deselect for split operator */
+ for (b = 0, bezt1 = nu->bezt; b < nu->pntsu; b++, bezt1++) {
+ select_beztriple(bezt1, DESELECT, SELECT, true);
+ }
+ }
+
+ BKE_nurb_handles_calc(nu);
+ }
+ else {
+ if (split) {
+ /* deselect for split operator */
+ for (b = 0, bp1 = nu->bp; b < nu->pntsu * nu->pntsv; b++, bp1++) {
+ select_bpoint(bp1, DESELECT, SELECT, HIDDEN);
+ }
+ }
+
+ BKE_nurb_order_clamp_u(nu);
+ BKE_nurb_knot_calc_u(nu);
+
+ if (nu->pntsv > 1) {
+ BKE_nurb_order_clamp_v(nu);
+ BKE_nurb_knot_calc_v(nu);
+ }
+ }
+ }
+
+ keyIndex_delNurbList(editnurb, nubase);
+ BKE_nurbList_free(nubase);
+ BLI_movelisttolist(nubase, &newnurb);
+
+ return true;
}
static int curve_delete_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- View3D *v3d = CTX_wm_view3d(C);
- eCurveElem_Types type = RNA_enum_get(op->ptr, "type");
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- bool changed_multi = false;
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = (Curve *)obedit->data;
- bool changed = false;
-
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
-
- if (type == CURVE_VERTEX) {
- changed = curve_delete_vertices(obedit, v3d);
- }
- else if (type == CURVE_SEGMENT) {
- changed = curve_delete_segments(obedit, v3d, false);
- }
- else {
- BLI_assert(0);
- }
-
- if (changed) {
- changed_multi = true;
- cu->actnu = cu->actvert = CU_ACT_NONE;
-
- if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
-
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- }
- MEM_freeN(objects);
-
- if (changed_multi) {
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ Main *bmain = CTX_data_main(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ eCurveElem_Types type = RNA_enum_get(op->ptr, "type");
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ bool changed_multi = false;
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = (Curve *)obedit->data;
+ bool changed = false;
+
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
+
+ if (type == CURVE_VERTEX) {
+ changed = curve_delete_vertices(obedit, v3d);
+ }
+ else if (type == CURVE_SEGMENT) {
+ changed = curve_delete_segments(obedit, v3d, false);
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ if (changed) {
+ changed_multi = true;
+ cu->actnu = cu->actvert = CU_ACT_NONE;
+
+ if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ }
+ MEM_freeN(objects);
+
+ if (changed_multi) {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static const EnumPropertyItem curve_delete_type_items[] = {
- {CURVE_VERTEX, "VERT", 0, "Vertices", ""},
- {CURVE_SEGMENT, "SEGMENT", 0, "Segments", ""},
- {0, NULL, 0, NULL, NULL},
+ {CURVE_VERTEX, "VERT", 0, "Vertices", ""},
+ {CURVE_SEGMENT, "SEGMENT", 0, "Segments", ""},
+ {0, NULL, 0, NULL, NULL},
};
-static const EnumPropertyItem *rna_curve_delete_type_itemf(
- bContext *C, PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop), bool *r_free)
+static const EnumPropertyItem *rna_curve_delete_type_itemf(bContext *C,
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
{
- EnumPropertyItem *item = NULL;
- int totitem = 0;
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
- if (!C) { /* needed for docs and i18n tools */
- return curve_delete_type_items;
- }
+ if (!C) { /* needed for docs and i18n tools */
+ return curve_delete_type_items;
+ }
- RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_VERTEX);
- RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_SEGMENT);
- RNA_enum_item_end(&item, &totitem);
- *r_free = true;
+ RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_VERTEX);
+ RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_SEGMENT);
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
- return item;
+ return item;
}
void CURVE_OT_delete(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Delete";
- ot->description = "Delete selected control points or segments";
- ot->idname = "CURVE_OT_delete";
+ /* identifiers */
+ ot->name = "Delete";
+ ot->description = "Delete selected control points or segments";
+ ot->idname = "CURVE_OT_delete";
- /* api callbacks */
- ot->exec = curve_delete_exec;
- ot->invoke = WM_menu_invoke;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = curve_delete_exec;
+ ot->invoke = WM_menu_invoke;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- prop = RNA_def_enum(ot->srna, "type", curve_delete_type_items, 0, "Type", "Which elements to delete");
- RNA_def_enum_funcs(prop, rna_curve_delete_type_itemf);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- ot->prop = prop;
+ /* properties */
+ prop = RNA_def_enum(
+ ot->srna, "type", curve_delete_type_items, 0, "Type", "Which elements to delete");
+ RNA_def_enum_funcs(prop, rna_curve_delete_type_itemf);
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ ot->prop = prop;
}
static bool test_bezt_is_sel_any(const void *bezt_v, void *user_data)
{
- View3D *v3d = user_data;
- const BezTriple *bezt = bezt_v;
- return BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt);
+ View3D *v3d = user_data;
+ const BezTriple *bezt = bezt_v;
+ return BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt);
}
static int curve_dissolve_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = (Curve *)obedit->data;
-
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
-
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if ((nu->type == CU_BEZIER) && (nu->pntsu > 2)) {
- unsigned int span_step[2] = {nu->pntsu, nu->pntsu};
- unsigned int span_len;
-
- while (BLI_array_iter_span(
- nu->bezt, nu->pntsu,
- (nu->flagu & CU_NURB_CYCLIC) != 0, false,
- test_bezt_is_sel_any, v3d,
- span_step, &span_len))
- {
- BezTriple *bezt_prev = &nu->bezt[mod_i(span_step[0] - 1, nu->pntsu)];
- BezTriple *bezt_next = &nu->bezt[mod_i(span_step[1] + 1, nu->pntsu)];
-
- int i_span_edge_len = span_len + 1;
- const unsigned int dims = 3;
-
- const unsigned int points_len = ((cu->resolu - 1) * i_span_edge_len) + 1;
- float *points = MEM_mallocN(points_len * dims * sizeof(float), __func__);
- float *points_stride = points;
- const int points_stride_len = (cu->resolu - 1);
-
- for (int segment = 0; segment < i_span_edge_len; segment++) {
- BezTriple *bezt_a = &nu->bezt[mod_i((span_step[0] + segment) - 1, nu->pntsu)];
- BezTriple *bezt_b = &nu->bezt[mod_i((span_step[0] + segment), nu->pntsu)];
-
- for (int axis = 0; axis < dims; axis++) {
- BKE_curve_forward_diff_bezier(
- bezt_a->vec[1][axis], bezt_a->vec[2][axis],
- bezt_b->vec[0][axis], bezt_b->vec[1][axis],
- points_stride + axis, points_stride_len, dims * sizeof(float));
- }
-
- points_stride += dims * points_stride_len;
- }
-
- BLI_assert(points_stride + dims == points + (points_len * dims));
-
- float tan_l[3], tan_r[3], error_sq_dummy;
- unsigned int error_index_dummy;
-
- sub_v3_v3v3(tan_l, bezt_prev->vec[1], bezt_prev->vec[2]);
- normalize_v3(tan_l);
- sub_v3_v3v3(tan_r, bezt_next->vec[0], bezt_next->vec[1]);
- normalize_v3(tan_r);
-
- curve_fit_cubic_to_points_single_fl(
- points, points_len, NULL, dims, FLT_EPSILON,
- tan_l, tan_r,
- bezt_prev->vec[2], bezt_next->vec[0],
- &error_sq_dummy, &error_index_dummy);
-
- if (!ELEM(bezt_prev->h2, HD_FREE, HD_ALIGN)) {
- bezt_prev->h2 = (bezt_prev->h2 == HD_VECT) ? HD_FREE : HD_ALIGN;
- }
- if (!ELEM(bezt_next->h1, HD_FREE, HD_ALIGN)) {
- bezt_next->h1 = (bezt_next->h1 == HD_VECT) ? HD_FREE : HD_ALIGN;
- }
-
- MEM_freeN(points);
- }
- }
- }
-
- ed_curve_delete_selected(obedit, v3d);
-
- cu->actnu = cu->actvert = CU_ACT_NONE;
-
- if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
-
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = (Curve *)obedit->data;
+
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
+
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if ((nu->type == CU_BEZIER) && (nu->pntsu > 2)) {
+ unsigned int span_step[2] = {nu->pntsu, nu->pntsu};
+ unsigned int span_len;
+
+ while (BLI_array_iter_span(nu->bezt,
+ nu->pntsu,
+ (nu->flagu & CU_NURB_CYCLIC) != 0,
+ false,
+ test_bezt_is_sel_any,
+ v3d,
+ span_step,
+ &span_len)) {
+ BezTriple *bezt_prev = &nu->bezt[mod_i(span_step[0] - 1, nu->pntsu)];
+ BezTriple *bezt_next = &nu->bezt[mod_i(span_step[1] + 1, nu->pntsu)];
+
+ int i_span_edge_len = span_len + 1;
+ const unsigned int dims = 3;
+
+ const unsigned int points_len = ((cu->resolu - 1) * i_span_edge_len) + 1;
+ float *points = MEM_mallocN(points_len * dims * sizeof(float), __func__);
+ float *points_stride = points;
+ const int points_stride_len = (cu->resolu - 1);
+
+ for (int segment = 0; segment < i_span_edge_len; segment++) {
+ BezTriple *bezt_a = &nu->bezt[mod_i((span_step[0] + segment) - 1, nu->pntsu)];
+ BezTriple *bezt_b = &nu->bezt[mod_i((span_step[0] + segment), nu->pntsu)];
+
+ for (int axis = 0; axis < dims; axis++) {
+ BKE_curve_forward_diff_bezier(bezt_a->vec[1][axis],
+ bezt_a->vec[2][axis],
+ bezt_b->vec[0][axis],
+ bezt_b->vec[1][axis],
+ points_stride + axis,
+ points_stride_len,
+ dims * sizeof(float));
+ }
+
+ points_stride += dims * points_stride_len;
+ }
+
+ BLI_assert(points_stride + dims == points + (points_len * dims));
+
+ float tan_l[3], tan_r[3], error_sq_dummy;
+ unsigned int error_index_dummy;
+
+ sub_v3_v3v3(tan_l, bezt_prev->vec[1], bezt_prev->vec[2]);
+ normalize_v3(tan_l);
+ sub_v3_v3v3(tan_r, bezt_next->vec[0], bezt_next->vec[1]);
+ normalize_v3(tan_r);
+
+ curve_fit_cubic_to_points_single_fl(points,
+ points_len,
+ NULL,
+ dims,
+ FLT_EPSILON,
+ tan_l,
+ tan_r,
+ bezt_prev->vec[2],
+ bezt_next->vec[0],
+ &error_sq_dummy,
+ &error_index_dummy);
+
+ if (!ELEM(bezt_prev->h2, HD_FREE, HD_ALIGN)) {
+ bezt_prev->h2 = (bezt_prev->h2 == HD_VECT) ? HD_FREE : HD_ALIGN;
+ }
+ if (!ELEM(bezt_next->h1, HD_FREE, HD_ALIGN)) {
+ bezt_next->h1 = (bezt_next->h1 == HD_VECT) ? HD_FREE : HD_ALIGN;
+ }
+
+ MEM_freeN(points);
+ }
+ }
+ }
+
+ ed_curve_delete_selected(obedit, v3d);
+
+ cu->actnu = cu->actvert = CU_ACT_NONE;
+
+ if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_dissolve_verts(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Dissolve Vertices";
- ot->description = "Delete selected control points, correcting surrounding handles";
- ot->idname = "CURVE_OT_dissolve_verts";
+ /* identifiers */
+ ot->name = "Dissolve Vertices";
+ ot->description = "Delete selected control points, correcting surrounding handles";
+ ot->idname = "CURVE_OT_dissolve_verts";
- /* api callbacks */
- ot->exec = curve_dissolve_exec;
- ot->poll = ED_operator_editcurve;
+ /* api callbacks */
+ ot->exec = curve_dissolve_exec;
+ ot->poll = ED_operator_editcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static bool nurb_bezt_flag_any(const Nurb *nu, const char flag_test)
{
- BezTriple *bezt = nu->bezt;
- int i;
+ BezTriple *bezt = nu->bezt;
+ int i;
- for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
- if (bezt->f2 & flag_test) {
- return true;
- }
- }
+ for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
+ if (bezt->f2 & flag_test) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
static int curve_decimate_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- const float error_sq_max = FLT_MAX;
- float ratio = RNA_float_get(op->ptr, "ratio");
- bool all_supported_multi = true;
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = (Curve *)obedit->data;
- bool all_supported = true;
- bool changed = false;
-
- {
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- if ((nu->pntsu > 2) && nurb_bezt_flag_any(nu, SELECT)) {
- const int error_target_len = max_ii(2, nu->pntsu * ratio);
- if (error_target_len != nu->pntsu) {
- BKE_curve_decimate_nurb(nu, cu->resolu, error_sq_max, error_target_len);
- changed = true;
- }
- }
- }
- else {
- all_supported = false;
- }
- }
- }
-
- if (all_supported == false) {
- all_supported_multi = false;
- }
-
- if (changed) {
- cu->actnu = cu->actvert = CU_ACT_NONE;
- if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
-
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- }
-
- if (all_supported_multi == false) {
- BKE_report(op->reports, RPT_WARNING, "Only bezier curves are supported");
- }
-
- MEM_freeN(objects);
-
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ const float error_sq_max = FLT_MAX;
+ float ratio = RNA_float_get(op->ptr, "ratio");
+ bool all_supported_multi = true;
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = (Curve *)obedit->data;
+ bool all_supported = true;
+ bool changed = false;
+
+ {
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ if ((nu->pntsu > 2) && nurb_bezt_flag_any(nu, SELECT)) {
+ const int error_target_len = max_ii(2, nu->pntsu * ratio);
+ if (error_target_len != nu->pntsu) {
+ BKE_curve_decimate_nurb(nu, cu->resolu, error_sq_max, error_target_len);
+ changed = true;
+ }
+ }
+ }
+ else {
+ all_supported = false;
+ }
+ }
+ }
+
+ if (all_supported == false) {
+ all_supported_multi = false;
+ }
+
+ if (changed) {
+ cu->actnu = cu->actvert = CU_ACT_NONE;
+ if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ }
+
+ if (all_supported_multi == false) {
+ BKE_report(op->reports, RPT_WARNING, "Only bezier curves are supported");
+ }
+
+ MEM_freeN(objects);
+
+ return OPERATOR_FINISHED;
}
void CURVE_OT_decimate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Decimate Curve";
- ot->description = "Simplify selected curves";
- ot->idname = "CURVE_OT_decimate";
+ /* identifiers */
+ ot->name = "Decimate Curve";
+ ot->description = "Simplify selected curves";
+ ot->idname = "CURVE_OT_decimate";
- /* api callbacks */
- ot->exec = curve_decimate_exec;
- ot->poll = ED_operator_editcurve;
+ /* api callbacks */
+ ot->exec = curve_decimate_exec;
+ ot->poll = ED_operator_editcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_float_factor(ot->srna, "ratio", 1.0f, 0.0f, 1.0f, "Ratio", "", 0.0f, 1.0f);
+ /* properties */
+ RNA_def_float_factor(ot->srna, "ratio", 1.0f, 0.0f, 1.0f, "Ratio", "", 0.0f, 1.0f);
}
-
/********************** shade smooth/flat operator *********************/
static int shade_smooth_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- View3D *v3d = CTX_wm_view3d(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- int clear = (STREQ(op->idname, "CURVE_OT_shade_flat"));
+ Object *obedit = CTX_data_edit_object(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ int clear = (STREQ(op->idname, "CURVE_OT_shade_flat"));
- if (obedit->type != OB_CURVE) {
- return OPERATOR_CANCELLED;
- }
+ if (obedit->type != OB_CURVE) {
+ return OPERATOR_CANCELLED;
+ }
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (ED_curve_nurb_select_check(v3d, nu)) {
- if (!clear) {
- nu->flag |= CU_SMOOTH;
- }
- else {
- nu->flag &= ~CU_SMOOTH;
- }
- }
- }
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+ if (!clear) {
+ nu->flag |= CU_SMOOTH;
+ }
+ else {
+ nu->flag &= ~CU_SMOOTH;
+ }
+ }
+ }
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void CURVE_OT_shade_smooth(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Shade Smooth";
- ot->idname = "CURVE_OT_shade_smooth";
- ot->description = "Set shading to smooth";
+ /* identifiers */
+ ot->name = "Shade Smooth";
+ ot->idname = "CURVE_OT_shade_smooth";
+ ot->description = "Set shading to smooth";
- /* api callbacks */
- ot->exec = shade_smooth_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = shade_smooth_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void CURVE_OT_shade_flat(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Shade Flat";
- ot->idname = "CURVE_OT_shade_flat";
- ot->description = "Set shading to flat";
+ /* identifiers */
+ ot->name = "Shade Flat";
+ ot->idname = "CURVE_OT_shade_flat";
+ ot->description = "Set shading to flat";
- /* api callbacks */
- ot->exec = shade_smooth_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = shade_smooth_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/************** join operator, to be used externally? ****************/
/* TODO: shape keys - as with meshes */
int join_curve_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- Object *ob_active = CTX_data_active_object(C);
- Curve *cu;
- Nurb *nu, *newnu;
- BezTriple *bezt;
- BPoint *bp;
- ListBase tempbase;
- float imat[4][4], cmat[4][4];
- int a;
- bool ok = false;
-
- CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
- {
- if (ob_iter == ob_active) {
- ok = true;
- break;
- }
- }
- CTX_DATA_END;
-
- /* that way the active object is always selected */
- if (ok == false) {
- BKE_report(op->reports, RPT_WARNING, "Active object is not a selected curve");
- return OPERATOR_CANCELLED;
- }
-
- BLI_listbase_clear(&tempbase);
-
- /* trasnform all selected curves inverse in obact */
- invert_m4_m4(imat, ob_active->obmat);
-
- CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
- {
- if (ob_iter->type == ob_active->type) {
- if (ob_iter != ob_active) {
-
- cu = ob_iter->data;
-
- if (cu->nurb.first) {
- /* watch it: switch order here really goes wrong */
- mul_m4_m4m4(cmat, imat, ob_iter->obmat);
-
- nu = cu->nurb.first;
- while (nu) {
- newnu = BKE_nurb_duplicate(nu);
- if (ob_active->totcol) { /* TODO, merge material lists */
- CLAMP(newnu->mat_nr, 0, ob_active->totcol - 1);
- }
- else {
- newnu->mat_nr = 0;
- }
- BLI_addtail(&tempbase, newnu);
-
- if ((bezt = newnu->bezt)) {
- a = newnu->pntsu;
- while (a--) {
- mul_m4_v3(cmat, bezt->vec[0]);
- mul_m4_v3(cmat, bezt->vec[1]);
- mul_m4_v3(cmat, bezt->vec[2]);
- bezt++;
- }
- BKE_nurb_handles_calc(newnu);
- }
- if ((bp = newnu->bp)) {
- a = newnu->pntsu * nu->pntsv;
- while (a--) {
- mul_m4_v3(cmat, bp->vec);
- bp++;
- }
- }
- nu = nu->next;
- }
- }
-
- ED_object_base_free_and_unlink(bmain, scene, ob_iter);
- }
- }
- }
- CTX_DATA_END;
-
- cu = ob_active->data;
- BLI_movelisttolist(&cu->nurb, &tempbase);
-
- if (ob_active->type == OB_CURVE) {
- /* Account for mixed 2D/3D curves when joining */
- BKE_curve_curve_dimension_update(cu);
- }
-
- DEG_relations_tag_update(bmain); // because we removed object(s), call before editmode!
-
- DEG_id_tag_update(&ob_active->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
-
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
-
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob_active = CTX_data_active_object(C);
+ Curve *cu;
+ Nurb *nu, *newnu;
+ BezTriple *bezt;
+ BPoint *bp;
+ ListBase tempbase;
+ float imat[4][4], cmat[4][4];
+ int a;
+ bool ok = false;
+
+ CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
+ if (ob_iter == ob_active) {
+ ok = true;
+ break;
+ }
+ }
+ CTX_DATA_END;
+
+ /* that way the active object is always selected */
+ if (ok == false) {
+ BKE_report(op->reports, RPT_WARNING, "Active object is not a selected curve");
+ return OPERATOR_CANCELLED;
+ }
+
+ BLI_listbase_clear(&tempbase);
+
+ /* trasnform all selected curves inverse in obact */
+ invert_m4_m4(imat, ob_active->obmat);
+
+ CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
+ if (ob_iter->type == ob_active->type) {
+ if (ob_iter != ob_active) {
+
+ cu = ob_iter->data;
+
+ if (cu->nurb.first) {
+ /* watch it: switch order here really goes wrong */
+ mul_m4_m4m4(cmat, imat, ob_iter->obmat);
+
+ nu = cu->nurb.first;
+ while (nu) {
+ newnu = BKE_nurb_duplicate(nu);
+ if (ob_active->totcol) { /* TODO, merge material lists */
+ CLAMP(newnu->mat_nr, 0, ob_active->totcol - 1);
+ }
+ else {
+ newnu->mat_nr = 0;
+ }
+ BLI_addtail(&tempbase, newnu);
+
+ if ((bezt = newnu->bezt)) {
+ a = newnu->pntsu;
+ while (a--) {
+ mul_m4_v3(cmat, bezt->vec[0]);
+ mul_m4_v3(cmat, bezt->vec[1]);
+ mul_m4_v3(cmat, bezt->vec[2]);
+ bezt++;
+ }
+ BKE_nurb_handles_calc(newnu);
+ }
+ if ((bp = newnu->bp)) {
+ a = newnu->pntsu * nu->pntsv;
+ while (a--) {
+ mul_m4_v3(cmat, bp->vec);
+ bp++;
+ }
+ }
+ nu = nu->next;
+ }
+ }
+
+ ED_object_base_free_and_unlink(bmain, scene, ob_iter);
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ cu = ob_active->data;
+ BLI_movelisttolist(&cu->nurb, &tempbase);
+
+ if (ob_active->type == OB_CURVE) {
+ /* Account for mixed 2D/3D curves when joining */
+ BKE_curve_curve_dimension_update(cu);
+ }
+
+ DEG_relations_tag_update(bmain); // because we removed object(s), call before editmode!
+
+ DEG_id_tag_update(&ob_active->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+
+ return OPERATOR_FINISHED;
}
-
/***************** clear tilt operator ********************/
static int clear_tilt_exec(bContext *C, wmOperator *UNUSED(op))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- uint objects_len;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
-
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
-
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- bezt->tilt = 0.0;
- }
- bezt++;
- }
- }
- else if (nu->bp) {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- if (bp->f1 & SELECT) {
- bp->tilt = 0.0f;
- }
- bp++;
- }
- }
- }
-
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
+
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ while (a--) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ bezt->tilt = 0.0;
+ }
+ bezt++;
+ }
+ }
+ else if (nu->bp) {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ if (bp->f1 & SELECT) {
+ bp->tilt = 0.0f;
+ }
+ bp++;
+ }
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_tilt_clear(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clear Tilt";
- ot->idname = "CURVE_OT_tilt_clear";
- ot->description = "Clear the tilt of selected control points";
+ /* identifiers */
+ ot->name = "Clear Tilt";
+ ot->idname = "CURVE_OT_tilt_clear";
+ ot->description = "Clear the tilt of selected control points";
- /* api callbacks */
- ot->exec = clear_tilt_exec;
- ot->poll = ED_operator_editcurve;
+ /* api callbacks */
+ ot->exec = clear_tilt_exec;
+ ot->poll = ED_operator_editcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void ED_curve_beztcpy(EditNurb *editnurb, BezTriple *dst, BezTriple *src, int count)
{
- memcpy(dst, src, count * sizeof(BezTriple));
- keyIndex_updateBezt(editnurb, src, dst, count);
+ memcpy(dst, src, count * sizeof(BezTriple));
+ keyIndex_updateBezt(editnurb, src, dst, count);
}
void ED_curve_bpcpy(EditNurb *editnurb, BPoint *dst, BPoint *src, int count)
{
- memcpy(dst, src, count * sizeof(BPoint));
- keyIndex_updateBP(editnurb, src, dst, count);
+ memcpy(dst, src, count * sizeof(BPoint));
+ keyIndex_updateBP(editnurb, src, dst, count);
}
bool ED_curve_active_center(Curve *cu, float center[3])
{
- Nurb *nu = NULL;
- void *vert = NULL;
+ Nurb *nu = NULL;
+ void *vert = NULL;
- if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) {
- return false;
- }
+ if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) {
+ return false;
+ }
- if (nu->type == CU_BEZIER) {
- BezTriple *bezt = (BezTriple *)vert;
- copy_v3_v3(center, bezt->vec[1]);
- }
- else {
- BPoint *bp = (BPoint *)vert;
- copy_v3_v3(center, bp->vec);
- }
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt = (BezTriple *)vert;
+ copy_v3_v3(center, bezt->vec[1]);
+ }
+ else {
+ BPoint *bp = (BPoint *)vert;
+ copy_v3_v3(center, bp->vec);
+ }
- return true;
+ return true;
}
/******************** Match texture space operator ***********************/
static bool match_texture_space_poll(bContext *C)
{
- Object *object = CTX_data_active_object(C);
+ Object *object = CTX_data_active_object(C);
- return object && ELEM(object->type, OB_CURVE, OB_SURF, OB_FONT);
+ return object && ELEM(object->type, OB_CURVE, OB_SURF, OB_FONT);
}
static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op))
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
- Object *object = CTX_data_active_object(C);
- Curve *curve = (Curve *) object->data;
- float min[3], max[3], size[3], loc[3];
- int a;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *object = CTX_data_active_object(C);
+ Curve *curve = (Curve *)object->data;
+ float min[3], max[3], size[3], loc[3];
+ int a;
- if (object->runtime.curve_cache == NULL) {
- BKE_displist_make_curveTypes(depsgraph, scene, object, false, false, NULL);
- }
+ if (object->runtime.curve_cache == NULL) {
+ BKE_displist_make_curveTypes(depsgraph, scene, object, false, false, NULL);
+ }
- INIT_MINMAX(min, max);
- BKE_displist_minmax(&object->runtime.curve_cache->disp, min, max);
+ INIT_MINMAX(min, max);
+ BKE_displist_minmax(&object->runtime.curve_cache->disp, min, max);
- mid_v3_v3v3(loc, min, max);
+ mid_v3_v3v3(loc, min, max);
- size[0] = (max[0] - min[0]) / 2.0f;
- size[1] = (max[1] - min[1]) / 2.0f;
- size[2] = (max[2] - min[2]) / 2.0f;
+ size[0] = (max[0] - min[0]) / 2.0f;
+ size[1] = (max[1] - min[1]) / 2.0f;
+ size[2] = (max[2] - min[2]) / 2.0f;
- for (a = 0; a < 3; a++) {
- if (size[a] == 0.0f) {
- size[a] = 1.0f;
- }
- else if (size[a] > 0.0f && size[a] < 0.00001f) {
- size[a] = 0.00001f;
- }
- else if (size[a] < 0.0f && size[a] > -0.00001f) {
- size[a] = -0.00001f;
- }
- }
+ for (a = 0; a < 3; a++) {
+ if (size[a] == 0.0f) {
+ size[a] = 1.0f;
+ }
+ else if (size[a] > 0.0f && size[a] < 0.00001f) {
+ size[a] = 0.00001f;
+ }
+ else if (size[a] < 0.0f && size[a] > -0.00001f) {
+ size[a] = -0.00001f;
+ }
+ }
- copy_v3_v3(curve->loc, loc);
- copy_v3_v3(curve->size, size);
- zero_v3(curve->rot);
+ copy_v3_v3(curve->loc, loc);
+ copy_v3_v3(curve->size, size);
+ zero_v3(curve->rot);
- curve->texflag &= ~CU_AUTOSPACE;
+ curve->texflag &= ~CU_AUTOSPACE;
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, curve);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, curve);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void CURVE_OT_match_texture_space(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Match Texture Space";
- ot->idname = "CURVE_OT_match_texture_space";
- ot->description = "Match texture space to object's bounding box";
+ /* identifiers */
+ ot->name = "Match Texture Space";
+ ot->idname = "CURVE_OT_match_texture_space";
+ ot->description = "Match texture space to object's bounding box";
- /* api callbacks */
- ot->exec = match_texture_space_exec;
- ot->poll = match_texture_space_poll;
+ /* api callbacks */
+ ot->exec = match_texture_space_exec;
+ ot->poll = match_texture_space_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c
index 0b6d4f6585a..4912ae5451d 100644
--- a/source/blender/editors/curve/editcurve_add.c
+++ b/source/blender/editors/curve/editcurve_add.c
@@ -51,775 +51,791 @@
#include "curve_intern.h"
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},
+ {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, "BezierCurve");
- case CU_PRIM_CIRCLE: return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "BezierCircle");
- case CU_PRIM_PATH: return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "CurvePath");
- default:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "Curve");
- }
- }
- else {
- switch (stype) {
- case CU_PRIM_CURVE: return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "NurbsCurve");
- case CU_PRIM_CIRCLE: return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "NurbsCircle");
- case CU_PRIM_PATH: return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "NurbsPath");
- default:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "Curve");
- }
- }
+ int stype = type & CU_PRIMITIVE;
+
+ if ((type & CU_TYPE) == CU_BEZIER) {
+ switch (stype) {
+ case CU_PRIM_CURVE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "BezierCurve");
+ case CU_PRIM_CIRCLE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "BezierCircle");
+ case CU_PRIM_PATH:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "CurvePath");
+ default:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "Curve");
+ }
+ }
+ else {
+ switch (stype) {
+ case CU_PRIM_CURVE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "NurbsCurve");
+ case CU_PRIM_CIRCLE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "NurbsCircle");
+ case CU_PRIM_PATH:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "NurbsPath");
+ default:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "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, "SurfCurve");
- case CU_PRIM_CIRCLE: return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfCircle");
- case CU_PRIM_PATCH: return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfPatch");
- case CU_PRIM_SPHERE: return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfSphere");
- case CU_PRIM_DONUT: return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfTorus");
- default:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "Surface");
- }
+ int stype = type & CU_PRIMITIVE;
+
+ switch (stype) {
+ case CU_PRIM_CURVE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfCurve");
+ case CU_PRIM_CIRCLE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfCircle");
+ case CU_PRIM_PATCH:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfPatch");
+ case CU_PRIM_SPHERE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfSphere");
+ case CU_PRIM_DONUT:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfTorus");
+ default:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "Surface");
+ }
}
-
-Nurb *ED_curve_add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type, int newob)
+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... */
- ListBase *editnurb = object_editcurve_get(obedit);
- RegionView3D *rv3d = ED_view3d_context_rv3d(C);
- Nurb *nu = NULL;
- BezTriple *bezt;
- BPoint *bp;
- Curve *cu = (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 int cutype = (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, 0);
-
- /* these types call this function to return a Nurb */
- if (stype != CU_PRIM_TUBE && stype != CU_PRIM_DONUT) {
- nu = (Nurb *)MEM_callocN(sizeof(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 = (BezTriple *)MEM_callocN(2 * sizeof(BezTriple), "addNurbprim1");
- bezt = nu->bezt;
- bezt->h1 = bezt->h2 = HD_ALIGN;
- bezt->f1 = bezt->f2 = bezt->f3 = 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 = 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 = (BPoint *)MEM_callocN(sizeof(BPoint) * 4, "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 = NULL; /* 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 = (BPoint *)MEM_callocN(sizeof(BPoint) * 5, "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 = NULL; /* 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 = (BezTriple *)MEM_callocN(sizeof(BezTriple) * 4, "addNurbprim1");
- nu->flagu = CU_NURB_CYCLIC;
- bezt = nu->bezt;
-
- bezt->h1 = bezt->h2 = HD_AUTO;
- bezt->f1 = bezt->f2 = bezt->f3 = 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 = 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 = 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 = 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 = 4;
- nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * 8, "addNurbprim6");
- nu->flagu = CU_NURB_CYCLIC;
- 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.25 * 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 = (BPoint *)MEM_callocN(sizeof(BPoint) * (4 * 4), "addNurbprim6");
- nu->flagu = 0;
- nu->flagv = 0;
- 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 ((a == 1 || a == 2) && (b == 1 || b == 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, SELECT, vec);
- ed_editnurb_extrude_flag(cu->editnurb, SELECT);
- mul_v3_fl(vec, -2.0f);
- ed_editnurb_translate_flag(editnurb, SELECT, vec);
-
- 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) {
- float tmp_cent[3] = {0.f, 0.f, 0.f};
- float tmp_vec[3] = {0.f, 0.f, 1.f};
-
- nu->pntsu = 5;
- nu->pntsv = 1;
- nu->orderu = 3;
- nu->resolu = cu->resolu;
- nu->resolv = cu->resolv;
- nu->flag = CU_SMOOTH;
- nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * 5, "addNurbprim6");
- nu->flagu = 0;
- 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;
- 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, NULL, obedit, tmp_vec, tmp_cent);
- }
- else if ((U.flag & USER_ADD_VIEWALIGNED)) {
- ed_editnurb_spin(viewmat, NULL, obedit, zvec, mat[3]);
- }
- else {
- ed_editnurb_spin(umat, NULL, 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) {
- float tmp_cent[3] = {0.f, 0.f, 0.f};
- float tmp_vec[3] = {0.f, 0.f, 1.f};
-
- 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, NULL, obedit, tmp_vec, tmp_cent);
- }
- else if ((U.flag & USER_ADD_VIEWALIGNED)) {
- ed_editnurb_spin(viewmat, NULL, obedit, zvec, mat[3]);
- }
- else {
- ed_editnurb_spin(umat, NULL, 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(!"invalid nurbs type");
- return NULL;
- }
-
- BLI_assert(nu != NULL);
-
- if (nu) { /* should always be set */
- if ((obedit->type != OB_SURF) && ((cu->flag & CU_3D) == 0)) {
- nu->flag |= CU_2D;
- }
-
- nu->flag |= CU_SMOOTH;
- cu->actnu = BLI_listbase_count(editnurb);
- cu->actvert = CU_ACT_NONE;
-
- BKE_nurb_test_2d(nu);
- }
-
- return nu;
+ static int xzproj = 0; /* this function calls itself... */
+ ListBase *editnurb = object_editcurve_get(obedit);
+ RegionView3D *rv3d = ED_view3d_context_rv3d(C);
+ Nurb *nu = NULL;
+ BezTriple *bezt;
+ BPoint *bp;
+ Curve *cu = (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 int cutype = (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, 0);
+
+ /* these types call this function to return a Nurb */
+ if (stype != CU_PRIM_TUBE && stype != CU_PRIM_DONUT) {
+ nu = (Nurb *)MEM_callocN(sizeof(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 = (BezTriple *)MEM_callocN(2 * sizeof(BezTriple), "addNurbprim1");
+ bezt = nu->bezt;
+ bezt->h1 = bezt->h2 = HD_ALIGN;
+ bezt->f1 = bezt->f2 = bezt->f3 = 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 = 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 = (BPoint *)MEM_callocN(sizeof(BPoint) * 4, "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 = NULL; /* 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 = (BPoint *)MEM_callocN(sizeof(BPoint) * 5, "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 = NULL; /* 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 = (BezTriple *)MEM_callocN(sizeof(BezTriple) * 4, "addNurbprim1");
+ nu->flagu = CU_NURB_CYCLIC;
+ bezt = nu->bezt;
+
+ bezt->h1 = bezt->h2 = HD_AUTO;
+ bezt->f1 = bezt->f2 = bezt->f3 = 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 = 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 = 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 = 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 = 4;
+ nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * 8, "addNurbprim6");
+ nu->flagu = CU_NURB_CYCLIC;
+ 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.25 * 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 = (BPoint *)MEM_callocN(sizeof(BPoint) * (4 * 4), "addNurbprim6");
+ nu->flagu = 0;
+ nu->flagv = 0;
+ 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 ((a == 1 || a == 2) && (b == 1 || b == 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, SELECT, vec);
+ ed_editnurb_extrude_flag(cu->editnurb, SELECT);
+ mul_v3_fl(vec, -2.0f);
+ ed_editnurb_translate_flag(editnurb, SELECT, vec);
+
+ 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) {
+ float tmp_cent[3] = {0.f, 0.f, 0.f};
+ float tmp_vec[3] = {0.f, 0.f, 1.f};
+
+ nu->pntsu = 5;
+ nu->pntsv = 1;
+ nu->orderu = 3;
+ nu->resolu = cu->resolu;
+ nu->resolv = cu->resolv;
+ nu->flag = CU_SMOOTH;
+ nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * 5, "addNurbprim6");
+ nu->flagu = 0;
+ 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;
+ 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, NULL, obedit, tmp_vec, tmp_cent);
+ }
+ else if ((U.flag & USER_ADD_VIEWALIGNED)) {
+ ed_editnurb_spin(viewmat, NULL, obedit, zvec, mat[3]);
+ }
+ else {
+ ed_editnurb_spin(umat, NULL, 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) {
+ float tmp_cent[3] = {0.f, 0.f, 0.f};
+ float tmp_vec[3] = {0.f, 0.f, 1.f};
+
+ 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, NULL, obedit, tmp_vec, tmp_cent);
+ }
+ else if ((U.flag & USER_ADD_VIEWALIGNED)) {
+ ed_editnurb_spin(viewmat, NULL, obedit, zvec, mat[3]);
+ }
+ else {
+ ed_editnurb_spin(umat, NULL, 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(!"invalid nurbs type");
+ return NULL;
+ }
+
+ BLI_assert(nu != NULL);
+
+ if (nu) { /* should always be set */
+ if ((obedit->type != OB_SURF) && ((cu->flag & CU_3D) == 0)) {
+ nu->flag |= CU_2D;
+ }
+
+ nu->flag |= CU_SMOOTH;
+ cu->actnu = BLI_listbase_count(editnurb);
+ cu->actvert = CU_ACT_NONE;
+
+ BKE_nurb_test_2d(nu);
+ }
+
+ return nu;
}
static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb;
- Nurb *nu;
- bool newob = false;
- bool enter_editmode;
- ushort local_view_bits;
- float dia;
- float loc[3], rot[3];
- float mat[4][4];
-
- WM_operator_view3d_unit_defaults(C, op);
-
- if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL)) {
- return OPERATOR_CANCELLED;
- }
-
- if (!isSurf) { /* adding curve */
- if (obedit == NULL || obedit->type != OB_CURVE) {
- const char *name = get_curve_defname(type);
- Curve *cu;
-
- obedit = ED_object_add_type(C, OB_CURVE, name, loc, rot, true, local_view_bits);
- newob = true;
-
- cu = (Curve *)obedit->data;
- cu->flag |= CU_DEFORM_FILL;
-
- 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 == NULL || 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);
- }
- }
-
- ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
- dia = RNA_float_get(op->ptr, "radius");
- mul_mat3_m4_fl(mat, dia);
-
- 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(C, EM_FREEDATA);
- }
-
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
-
- return OPERATOR_FINISHED;
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb;
+ Nurb *nu;
+ bool newob = false;
+ bool enter_editmode;
+ ushort local_view_bits;
+ float dia;
+ float loc[3], rot[3];
+ float mat[4][4];
+
+ WM_operator_view3d_unit_defaults(C, op);
+
+ if (!ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, &enter_editmode, &local_view_bits, NULL)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!isSurf) { /* adding curve */
+ if (obedit == NULL || obedit->type != OB_CURVE) {
+ const char *name = get_curve_defname(type);
+ Curve *cu;
+
+ obedit = ED_object_add_type(C, OB_CURVE, name, loc, rot, true, local_view_bits);
+ newob = true;
+
+ cu = (Curve *)obedit->data;
+ cu->flag |= CU_DEFORM_FILL;
+
+ 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 == NULL || 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);
+ }
+ }
+
+ ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
+ dia = RNA_float_get(op->ptr, "radius");
+ mul_mat3_m4_fl(mat, dia);
+
+ 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(C, EM_FREEDATA);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
+
+ return OPERATOR_FINISHED;
}
static int curve_prim_add(bContext *C, wmOperator *op, int type)
{
- return curvesurf_prim_add(C, op, type, 0);
+ return curvesurf_prim_add(C, op, type, 0);
}
static int surf_prim_add(bContext *C, wmOperator *op, int type)
{
- return curvesurf_prim_add(C, op, type, 1);
+ return curvesurf_prim_add(C, op, type, 1);
}
/* ******************** Curves ******************* */
static int add_primitive_bezier_exec(bContext *C, wmOperator *op)
{
- return curve_prim_add(C, op, CU_BEZIER | CU_PRIM_CURVE);
+ return curve_prim_add(C, op, CU_BEZIER | CU_PRIM_CURVE);
}
void CURVE_OT_primitive_bezier_curve_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Bezier";
- ot->description = "Construct a Bezier Curve";
- ot->idname = "CURVE_OT_primitive_bezier_curve_add";
+ /* identifiers */
+ ot->name = "Add Bezier";
+ ot->description = "Construct a Bezier Curve";
+ ot->idname = "CURVE_OT_primitive_bezier_curve_add";
- /* api callbacks */
- ot->exec = add_primitive_bezier_exec;
- ot->poll = ED_operator_scene_editable;
+ /* api callbacks */
+ ot->exec = add_primitive_bezier_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
static int add_primitive_bezier_circle_exec(bContext *C, wmOperator *op)
{
- return curve_prim_add(C, op, CU_BEZIER | CU_PRIM_CIRCLE);
+ return curve_prim_add(C, op, CU_BEZIER | CU_PRIM_CIRCLE);
}
void CURVE_OT_primitive_bezier_circle_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Bezier Circle";
- ot->description = "Construct a Bezier Circle";
- ot->idname = "CURVE_OT_primitive_bezier_circle_add";
+ /* identifiers */
+ ot->name = "Add Bezier Circle";
+ ot->description = "Construct a Bezier Circle";
+ ot->idname = "CURVE_OT_primitive_bezier_circle_add";
- /* api callbacks */
- ot->exec = add_primitive_bezier_circle_exec;
- ot->poll = ED_operator_scene_editable;
+ /* api callbacks */
+ ot->exec = add_primitive_bezier_circle_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
static int add_primitive_nurbs_curve_exec(bContext *C, wmOperator *op)
{
- return curve_prim_add(C, op, CU_NURBS | CU_PRIM_CURVE);
+ 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";
+ /* 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;
+ /* api callbacks */
+ ot->exec = add_primitive_nurbs_curve_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
static int add_primitive_nurbs_circle_exec(bContext *C, wmOperator *op)
{
- return curve_prim_add(C, op, CU_NURBS | CU_PRIM_CIRCLE);
+ 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";
+ /* 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;
+ /* api callbacks */
+ ot->exec = add_primitive_nurbs_circle_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
static int add_primitive_curve_path_exec(bContext *C, wmOperator *op)
{
- return curve_prim_add(C, op, CU_NURBS | CU_PRIM_PATH);
+ 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";
+ /* 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;
+ /* api callbacks */
+ ot->exec = add_primitive_curve_path_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
/* **************** NURBS surfaces ********************** */
static int add_primitive_nurbs_surface_curve_exec(bContext *C, wmOperator *op)
{
- return surf_prim_add(C, op, CU_PRIM_CURVE | CU_NURBS);
+ 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";
+ /* 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;
+ /* api callbacks */
+ ot->exec = add_primitive_nurbs_surface_curve_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
static int add_primitive_nurbs_surface_circle_exec(bContext *C, wmOperator *op)
{
- return surf_prim_add(C, op, CU_PRIM_CIRCLE | CU_NURBS);
+ 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";
+ /* 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;
+ /* api callbacks */
+ ot->exec = add_primitive_nurbs_surface_circle_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
static int add_primitive_nurbs_surface_surface_exec(bContext *C, wmOperator *op)
{
- return surf_prim_add(C, op, CU_PRIM_PATCH | CU_NURBS);
+ 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";
+ /* 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;
+ /* api callbacks */
+ ot->exec = add_primitive_nurbs_surface_surface_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
static int add_primitive_nurbs_surface_cylinder_exec(bContext *C, wmOperator *op)
{
- return surf_prim_add(C, op, CU_PRIM_TUBE | CU_NURBS);
+ 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";
+ /* 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;
+ /* api callbacks */
+ ot->exec = add_primitive_nurbs_surface_cylinder_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
static int add_primitive_nurbs_surface_sphere_exec(bContext *C, wmOperator *op)
{
- return surf_prim_add(C, op, CU_PRIM_SPHERE | CU_NURBS);
+ 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";
+ /* 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;
+ /* api callbacks */
+ ot->exec = add_primitive_nurbs_surface_sphere_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
static int add_primitive_nurbs_surface_torus_exec(bContext *C, wmOperator *op)
{
- return surf_prim_add(C, op, CU_PRIM_DONUT | CU_NURBS);
+ 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";
+ /* 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;
+ /* api callbacks */
+ ot->exec = add_primitive_nurbs_surface_torus_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_unit_props_radius(ot);
- ED_object_add_generic_props(ot, true);
+ ED_object_add_unit_props_radius(ot);
+ ED_object_add_generic_props(ot, true);
}
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index d930174c25b..6811e32cc2a 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -43,7 +43,6 @@
#include "ED_view3d.h"
#include "ED_curve.h"
-
#include "GPU_batch.h"
#include "GPU_batch_presets.h"
#include "GPU_immediate.h"
@@ -63,7 +62,7 @@
#define USE_SPLINE_FIT
#ifdef USE_SPLINE_FIT
-#include "curve_fit_nd.h"
+# include "curve_fit_nd.h"
#endif
/* Distance between input samples */
@@ -71,573 +70,567 @@
#define STROKE_SAMPLE_DIST_MAX_PX 3
/* Distance between start/end points to consider cyclic */
-#define STROKE_CYCLIC_DIST_PX 8
+#define STROKE_CYCLIC_DIST_PX 8
/* -------------------------------------------------------------------- */
/** \name StrokeElem / #RNA_OperatorStrokeElement Conversion Functions
* \{ */
struct StrokeElem {
- float mval[2];
- float location_world[3];
- float location_local[3];
+ float mval[2];
+ float location_world[3];
+ float location_local[3];
- /* surface normal, may be zero'd */
- float normal_world[3];
- float normal_local[3];
+ /* surface normal, may be zero'd */
+ float normal_world[3];
+ float normal_local[3];
- float pressure;
+ float pressure;
};
struct CurveDrawData {
- Depsgraph *depsgraph;
+ Depsgraph *depsgraph;
- short init_event_type;
- short curve_type;
+ short init_event_type;
+ short curve_type;
- /* projecting 2D into 3D space */
- struct {
- /* use a plane or project to the surface */
- bool use_plane;
- float plane[4];
+ /* projecting 2D into 3D space */
+ struct {
+ /* use a plane or project to the surface */
+ bool use_plane;
+ float plane[4];
- /* use 'rv3d->depths', note that this will become 'damaged' while drawing, but that's OK. */
- bool use_depth;
+ /* use 'rv3d->depths', note that this will become 'damaged' while drawing, but that's OK. */
+ bool use_depth;
- /* offset projection by this value */
- bool use_offset;
- float offset[3]; /* worldspace */
- float surface_offset;
- bool use_surface_offset_absolute;
- } project;
+ /* offset projection by this value */
+ bool use_offset;
+ float offset[3]; /* worldspace */
+ float surface_offset;
+ bool use_surface_offset_absolute;
+ } project;
- /* cursor sampling */
- struct {
- /* use substeps, needed for nicely interpolating depth */
- bool use_substeps;
- } sample;
+ /* cursor sampling */
+ struct {
+ /* use substeps, needed for nicely interpolating depth */
+ bool use_substeps;
+ } sample;
- struct {
- float min, max, range;
- } radius;
+ struct {
+ float min, max, range;
+ } radius;
- struct {
- float mouse[2];
- /* used incase we can't calculate the depth */
- float location_world[3];
+ struct {
+ float mouse[2];
+ /* used incase we can't calculate the depth */
+ float location_world[3];
- float location_world_valid[3];
+ float location_world_valid[3];
- const struct StrokeElem *selem;
- } prev;
+ const struct StrokeElem *selem;
+ } prev;
- ViewContext vc;
- enum {
- CURVE_DRAW_IDLE = 0,
- CURVE_DRAW_PAINTING = 1,
- } state;
+ ViewContext vc;
+ enum {
+ CURVE_DRAW_IDLE = 0,
+ CURVE_DRAW_PAINTING = 1,
+ } state;
- /* StrokeElem */
- BLI_mempool *stroke_elem_pool;
+ /* StrokeElem */
+ BLI_mempool *stroke_elem_pool;
- void *draw_handle_view;
+ void *draw_handle_view;
};
-static float stroke_elem_radius_from_pressure(const struct CurveDrawData *cdd, const float pressure)
+static float stroke_elem_radius_from_pressure(const struct CurveDrawData *cdd,
+ const float pressure)
{
- const Curve *cu = cdd->vc.obedit->data;
- return ((pressure * cdd->radius.range) + cdd->radius.min) * cu->ext2;
+ const Curve *cu = cdd->vc.obedit->data;
+ return ((pressure * cdd->radius.range) + cdd->radius.min) * cu->ext2;
}
static float stroke_elem_radius(const struct CurveDrawData *cdd, const struct StrokeElem *selem)
{
- return stroke_elem_radius_from_pressure(cdd, selem->pressure);
+ return stroke_elem_radius_from_pressure(cdd, selem->pressure);
}
-static void stroke_elem_pressure_set(const struct CurveDrawData *cdd, struct StrokeElem *selem, float pressure)
+static void stroke_elem_pressure_set(const struct CurveDrawData *cdd,
+ struct StrokeElem *selem,
+ float pressure)
{
- if ((cdd->project.surface_offset != 0.0f) &&
- !cdd->project.use_surface_offset_absolute &&
- !is_zero_v3(selem->normal_local))
- {
- const float adjust = stroke_elem_radius_from_pressure(cdd, pressure) -
- stroke_elem_radius_from_pressure(cdd, selem->pressure);
- madd_v3_v3fl(selem->location_local, selem->normal_local, adjust);
- mul_v3_m4v3(selem->location_world, cdd->vc.obedit->obmat, selem->location_local);
- }
- selem->pressure = pressure;
+ if ((cdd->project.surface_offset != 0.0f) && !cdd->project.use_surface_offset_absolute &&
+ !is_zero_v3(selem->normal_local)) {
+ const float adjust = stroke_elem_radius_from_pressure(cdd, pressure) -
+ stroke_elem_radius_from_pressure(cdd, selem->pressure);
+ madd_v3_v3fl(selem->location_local, selem->normal_local, adjust);
+ mul_v3_m4v3(selem->location_world, cdd->vc.obedit->obmat, selem->location_local);
+ }
+ selem->pressure = pressure;
}
-static void stroke_elem_interp(
- struct StrokeElem *selem_out,
- const struct StrokeElem *selem_a, const struct StrokeElem *selem_b, float t)
+static void stroke_elem_interp(struct StrokeElem *selem_out,
+ const struct StrokeElem *selem_a,
+ const struct StrokeElem *selem_b,
+ float t)
{
- interp_v2_v2v2(selem_out->mval, selem_a->mval, selem_b->mval, t);
- interp_v3_v3v3(selem_out->location_world, selem_a->location_world, selem_b->location_world, t);
- interp_v3_v3v3(selem_out->location_local, selem_a->location_local, selem_b->location_local, t);
- selem_out->pressure = interpf(selem_a->pressure, selem_b->pressure, t);
+ interp_v2_v2v2(selem_out->mval, selem_a->mval, selem_b->mval, t);
+ interp_v3_v3v3(selem_out->location_world, selem_a->location_world, selem_b->location_world, t);
+ interp_v3_v3v3(selem_out->location_local, selem_a->location_local, selem_b->location_local, t);
+ selem_out->pressure = interpf(selem_a->pressure, selem_b->pressure, t);
}
-
/**
* Sets the depth from #StrokeElem.mval
*/
-static bool stroke_elem_project(
- const struct CurveDrawData *cdd,
- const int mval_i[2], const float mval_fl[2],
- float surface_offset, const float radius,
- float r_location_world[3], float r_normal_world[3])
+static bool stroke_elem_project(const struct CurveDrawData *cdd,
+ const int mval_i[2],
+ const float mval_fl[2],
+ float surface_offset,
+ const float radius,
+ float r_location_world[3],
+ float r_normal_world[3])
{
- ARegion *ar = cdd->vc.ar;
- RegionView3D *rv3d = cdd->vc.rv3d;
-
- bool is_location_world_set = false;
-
- /* project to 'location_world' */
- if (cdd->project.use_plane) {
- /* get the view vector to 'location' */
- if (ED_view3d_win_to_3d_on_plane(ar, cdd->project.plane, mval_fl, true, r_location_world)) {
- if (r_normal_world) {
- zero_v3(r_normal_world);
- }
- is_location_world_set = true;
- }
- }
- else {
- const ViewDepths *depths = rv3d->depths;
- if (depths &&
- ((unsigned int)mval_i[0] < depths->w) &&
- ((unsigned int)mval_i[1] < depths->h))
- {
- const double depth = (double)ED_view3d_depth_read_cached(&cdd->vc, mval_i);
- if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
- if (ED_view3d_depth_unproject(ar, mval_i, depth, r_location_world)) {
- is_location_world_set = true;
- if (r_normal_world) {
- zero_v3(r_normal_world);
- }
-
- if (surface_offset != 0.0f) {
- const float offset = cdd->project.use_surface_offset_absolute ? 1.0f : radius;
- float normal[3];
- if (ED_view3d_depth_read_cached_normal(&cdd->vc, mval_i, normal)) {
- madd_v3_v3fl(r_location_world, normal, offset * surface_offset);
- if (r_normal_world) {
- copy_v3_v3(r_normal_world, normal);
- }
- }
- }
- }
- }
- }
- }
-
- if (is_location_world_set) {
- if (cdd->project.use_offset) {
- add_v3_v3(r_location_world, cdd->project.offset);
- }
- }
-
- return is_location_world_set;
+ ARegion *ar = cdd->vc.ar;
+ RegionView3D *rv3d = cdd->vc.rv3d;
+
+ bool is_location_world_set = false;
+
+ /* project to 'location_world' */
+ if (cdd->project.use_plane) {
+ /* get the view vector to 'location' */
+ if (ED_view3d_win_to_3d_on_plane(ar, cdd->project.plane, mval_fl, true, r_location_world)) {
+ if (r_normal_world) {
+ zero_v3(r_normal_world);
+ }
+ is_location_world_set = true;
+ }
+ }
+ else {
+ const ViewDepths *depths = rv3d->depths;
+ if (depths && ((unsigned int)mval_i[0] < depths->w) && ((unsigned int)mval_i[1] < depths->h)) {
+ const double depth = (double)ED_view3d_depth_read_cached(&cdd->vc, mval_i);
+ if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
+ if (ED_view3d_depth_unproject(ar, mval_i, depth, r_location_world)) {
+ is_location_world_set = true;
+ if (r_normal_world) {
+ zero_v3(r_normal_world);
+ }
+
+ if (surface_offset != 0.0f) {
+ const float offset = cdd->project.use_surface_offset_absolute ? 1.0f : radius;
+ float normal[3];
+ if (ED_view3d_depth_read_cached_normal(&cdd->vc, mval_i, normal)) {
+ madd_v3_v3fl(r_location_world, normal, offset * surface_offset);
+ if (r_normal_world) {
+ copy_v3_v3(r_normal_world, normal);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (is_location_world_set) {
+ if (cdd->project.use_offset) {
+ add_v3_v3(r_location_world, cdd->project.offset);
+ }
+ }
+
+ return is_location_world_set;
}
-static bool stroke_elem_project_fallback(
- const struct CurveDrawData *cdd,
- const int mval_i[2], const float mval_fl[2],
- const float surface_offset, const float radius,
- const float location_fallback_depth[3],
- float r_location_world[3], float r_location_local[3],
- float r_normal_world[3], float r_normal_local[3])
+static bool stroke_elem_project_fallback(const struct CurveDrawData *cdd,
+ const int mval_i[2],
+ const float mval_fl[2],
+ const float surface_offset,
+ const float radius,
+ const float location_fallback_depth[3],
+ float r_location_world[3],
+ float r_location_local[3],
+ float r_normal_world[3],
+ float r_normal_local[3])
{
- bool is_depth_found = stroke_elem_project(
- cdd, mval_i, mval_fl,
- surface_offset, radius,
- r_location_world, r_normal_world);
- if (is_depth_found == false) {
- ED_view3d_win_to_3d(cdd->vc.v3d, cdd->vc.ar, location_fallback_depth, mval_fl, r_location_world);
- zero_v3(r_normal_local);
- }
- mul_v3_m4v3(r_location_local, cdd->vc.obedit->imat, r_location_world);
-
- if (!is_zero_v3(r_normal_world)) {
- copy_v3_v3(r_normal_local, r_normal_world);
- mul_transposed_mat3_m4_v3(cdd->vc.obedit->obmat, r_normal_local);
- normalize_v3(r_normal_local);
- }
- else {
- zero_v3(r_normal_local);
- }
-
- return is_depth_found;
+ bool is_depth_found = stroke_elem_project(
+ cdd, mval_i, mval_fl, surface_offset, radius, r_location_world, r_normal_world);
+ if (is_depth_found == false) {
+ ED_view3d_win_to_3d(
+ cdd->vc.v3d, cdd->vc.ar, location_fallback_depth, mval_fl, r_location_world);
+ zero_v3(r_normal_local);
+ }
+ mul_v3_m4v3(r_location_local, cdd->vc.obedit->imat, r_location_world);
+
+ if (!is_zero_v3(r_normal_world)) {
+ copy_v3_v3(r_normal_local, r_normal_world);
+ mul_transposed_mat3_m4_v3(cdd->vc.obedit->obmat, r_normal_local);
+ normalize_v3(r_normal_local);
+ }
+ else {
+ zero_v3(r_normal_local);
+ }
+
+ return is_depth_found;
}
/**
* \note #StrokeElem.mval & #StrokeElem.pressure must be set first.
*/
-static bool stroke_elem_project_fallback_elem(
- const struct CurveDrawData *cdd,
- const float location_fallback_depth[3],
- struct StrokeElem *selem)
+static bool stroke_elem_project_fallback_elem(const struct CurveDrawData *cdd,
+ const float location_fallback_depth[3],
+ struct StrokeElem *selem)
{
- const int mval_i[2] = {UNPACK2(selem->mval)};
- const float radius = stroke_elem_radius(cdd, selem);
- return stroke_elem_project_fallback(
- cdd, mval_i, selem->mval,
- cdd->project.surface_offset, radius,
- location_fallback_depth,
- selem->location_world, selem->location_local,
- selem->normal_world, selem->normal_local);
+ const int mval_i[2] = {UNPACK2(selem->mval)};
+ const float radius = stroke_elem_radius(cdd, selem);
+ return stroke_elem_project_fallback(cdd,
+ mval_i,
+ selem->mval,
+ cdd->project.surface_offset,
+ radius,
+ location_fallback_depth,
+ selem->location_world,
+ selem->location_local,
+ selem->normal_world,
+ selem->normal_local);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Operator/Stroke Conversion
* \{ */
-static void curve_draw_stroke_to_operator_elem(
- wmOperator *op, const struct StrokeElem *selem)
+static void curve_draw_stroke_to_operator_elem(wmOperator *op, const struct StrokeElem *selem)
{
- PointerRNA itemptr;
- RNA_collection_add(op->ptr, "stroke", &itemptr);
+ PointerRNA itemptr;
+ RNA_collection_add(op->ptr, "stroke", &itemptr);
- RNA_float_set_array(&itemptr, "mouse", selem->mval);
- RNA_float_set_array(&itemptr, "location", selem->location_world);
- RNA_float_set(&itemptr, "pressure", selem->pressure);
+ RNA_float_set_array(&itemptr, "mouse", selem->mval);
+ RNA_float_set_array(&itemptr, "location", selem->location_world);
+ RNA_float_set(&itemptr, "pressure", selem->pressure);
}
-static void curve_draw_stroke_from_operator_elem(
- wmOperator *op, PointerRNA *itemptr)
+static void curve_draw_stroke_from_operator_elem(wmOperator *op, PointerRNA *itemptr)
{
- struct CurveDrawData *cdd = op->customdata;
+ struct CurveDrawData *cdd = op->customdata;
- struct StrokeElem *selem = BLI_mempool_calloc(cdd->stroke_elem_pool);
+ struct StrokeElem *selem = BLI_mempool_calloc(cdd->stroke_elem_pool);
- RNA_float_get_array(itemptr, "mouse", selem->mval);
- RNA_float_get_array(itemptr, "location", selem->location_world);
- mul_v3_m4v3(selem->location_local, cdd->vc.obedit->imat, selem->location_world);
- selem->pressure = RNA_float_get(itemptr, "pressure");
+ RNA_float_get_array(itemptr, "mouse", selem->mval);
+ RNA_float_get_array(itemptr, "location", selem->location_world);
+ mul_v3_m4v3(selem->location_local, cdd->vc.obedit->imat, selem->location_world);
+ selem->pressure = RNA_float_get(itemptr, "pressure");
}
static void curve_draw_stroke_to_operator(wmOperator *op)
{
- struct CurveDrawData *cdd = op->customdata;
+ struct CurveDrawData *cdd = op->customdata;
- BLI_mempool_iter iter;
- const struct StrokeElem *selem;
+ BLI_mempool_iter iter;
+ const struct StrokeElem *selem;
- BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
- for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
- curve_draw_stroke_to_operator_elem(op, selem);
- }
+ BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
+ for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
+ curve_draw_stroke_to_operator_elem(op, selem);
+ }
}
static void curve_draw_stroke_from_operator(wmOperator *op)
{
- RNA_BEGIN (op->ptr, itemptr, "stroke")
- {
- curve_draw_stroke_from_operator_elem(op, &itemptr);
- }
- RNA_END;
+ RNA_BEGIN (op->ptr, itemptr, "stroke") {
+ curve_draw_stroke_from_operator_elem(op, &itemptr);
+ }
+ RNA_END;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Operator Callbacks & Helpers
* \{ */
static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
{
- wmOperator *op = arg;
- struct CurveDrawData *cdd = op->customdata;
-
- const int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
-
- if (stroke_len == 0) {
- return;
- }
-
- Object *obedit = cdd->vc.obedit;
- Curve *cu = obedit->data;
-
- if (cu->ext2 > 0.0f) {
- BLI_mempool_iter iter;
- const struct StrokeElem *selem;
-
- const float location_zero[3] = {0};
- const float *location_prev = location_zero;
-
- float color[3];
- UI_GetThemeColor3fv(TH_WIRE, color);
-
- GPUBatch *sphere = GPU_batch_preset_sphere(0);
- GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
- GPU_batch_uniform_3fv(sphere, "color", color);
-
- /* scale to edit-mode space */
- GPU_matrix_push();
- GPU_matrix_mul(obedit->obmat);
-
- BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
- for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
- GPU_matrix_translate_3f(
- selem->location_local[0] - location_prev[0],
- selem->location_local[1] - location_prev[1],
- selem->location_local[2] - location_prev[2]);
- location_prev = selem->location_local;
-
- const float radius = stroke_elem_radius(cdd, selem);
-
- GPU_matrix_push();
- GPU_matrix_scale_1f(radius);
- GPU_batch_draw(sphere);
- GPU_matrix_pop();
-
- location_prev = selem->location_local;
- }
-
- GPU_matrix_pop();
- }
-
- if (stroke_len > 1) {
- float (*coord_array)[3] = MEM_mallocN(sizeof(*coord_array) * stroke_len, __func__);
-
- {
- BLI_mempool_iter iter;
- const struct StrokeElem *selem;
- int i;
- BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
- for (selem = BLI_mempool_iterstep(&iter), i = 0; selem; selem = BLI_mempool_iterstep(&iter), i++) {
- copy_v3_v3(coord_array[i], selem->location_world);
- }
- }
-
- {
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
- GPU_depth_test(false);
- GPU_blend(true);
- GPU_line_smooth(true);
- GPU_line_width(3.0f);
-
- imm_cpack(0x0);
- immBegin(GPU_PRIM_LINE_STRIP, stroke_len);
- for (int i = 0; i < stroke_len; i++) {
- immVertex3fv(pos, coord_array[i]);
- }
- immEnd();
-
- GPU_line_width(1.0f);
-
- imm_cpack(0xffffffff);
- immBegin(GPU_PRIM_LINE_STRIP, stroke_len);
- for (int i = 0; i < stroke_len; i++) {
- immVertex3fv(pos, coord_array[i]);
- }
- immEnd();
-
- /* Reset defaults */
- GPU_depth_test(true);
- GPU_blend(false);
- GPU_line_smooth(false);
-
- immUnbindProgram();
- }
-
- MEM_freeN(coord_array);
- }
+ wmOperator *op = arg;
+ struct CurveDrawData *cdd = op->customdata;
+
+ const int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
+
+ if (stroke_len == 0) {
+ return;
+ }
+
+ Object *obedit = cdd->vc.obedit;
+ Curve *cu = obedit->data;
+
+ if (cu->ext2 > 0.0f) {
+ BLI_mempool_iter iter;
+ const struct StrokeElem *selem;
+
+ const float location_zero[3] = {0};
+ const float *location_prev = location_zero;
+
+ float color[3];
+ UI_GetThemeColor3fv(TH_WIRE, color);
+
+ GPUBatch *sphere = GPU_batch_preset_sphere(0);
+ GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
+ GPU_batch_uniform_3fv(sphere, "color", color);
+
+ /* scale to edit-mode space */
+ GPU_matrix_push();
+ GPU_matrix_mul(obedit->obmat);
+
+ BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
+ for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
+ GPU_matrix_translate_3f(selem->location_local[0] - location_prev[0],
+ selem->location_local[1] - location_prev[1],
+ selem->location_local[2] - location_prev[2]);
+ location_prev = selem->location_local;
+
+ const float radius = stroke_elem_radius(cdd, selem);
+
+ GPU_matrix_push();
+ GPU_matrix_scale_1f(radius);
+ GPU_batch_draw(sphere);
+ GPU_matrix_pop();
+
+ location_prev = selem->location_local;
+ }
+
+ GPU_matrix_pop();
+ }
+
+ if (stroke_len > 1) {
+ float(*coord_array)[3] = MEM_mallocN(sizeof(*coord_array) * stroke_len, __func__);
+
+ {
+ BLI_mempool_iter iter;
+ const struct StrokeElem *selem;
+ int i;
+ BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
+ for (selem = BLI_mempool_iterstep(&iter), i = 0; selem;
+ selem = BLI_mempool_iterstep(&iter), i++) {
+ copy_v3_v3(coord_array[i], selem->location_world);
+ }
+ }
+
+ {
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ GPU_depth_test(false);
+ GPU_blend(true);
+ GPU_line_smooth(true);
+ GPU_line_width(3.0f);
+
+ imm_cpack(0x0);
+ immBegin(GPU_PRIM_LINE_STRIP, stroke_len);
+ for (int i = 0; i < stroke_len; i++) {
+ immVertex3fv(pos, coord_array[i]);
+ }
+ immEnd();
+
+ GPU_line_width(1.0f);
+
+ imm_cpack(0xffffffff);
+ immBegin(GPU_PRIM_LINE_STRIP, stroke_len);
+ for (int i = 0; i < stroke_len; i++) {
+ immVertex3fv(pos, coord_array[i]);
+ }
+ immEnd();
+
+ /* Reset defaults */
+ GPU_depth_test(true);
+ GPU_blend(false);
+ GPU_line_smooth(false);
+
+ immUnbindProgram();
+ }
+
+ MEM_freeN(coord_array);
+ }
}
static void curve_draw_event_add(wmOperator *op, const wmEvent *event)
{
- struct CurveDrawData *cdd = op->customdata;
- Object *obedit = cdd->vc.obedit;
-
- invert_m4_m4(obedit->imat, obedit->obmat);
-
- struct StrokeElem *selem = BLI_mempool_calloc(cdd->stroke_elem_pool);
-
- ARRAY_SET_ITEMS(selem->mval, event->mval[0], event->mval[1]);
-
- /* handle pressure sensitivity (which is supplied by tablets) */
- if (event->tablet_data) {
- const wmTabletData *wmtab = event->tablet_data;
- selem->pressure = wmtab->Pressure;
- }
- else {
- selem->pressure = 1.0f;
- }
-
- bool is_depth_found = stroke_elem_project_fallback_elem(
- cdd, cdd->prev.location_world_valid, selem);
-
- if (is_depth_found) {
- /* use the depth if a fallback wasn't used */
- copy_v3_v3(cdd->prev.location_world_valid, selem->location_world);
- }
- copy_v3_v3(cdd->prev.location_world, selem->location_world);
-
- float len_sq = len_squared_v2v2(cdd->prev.mouse, selem->mval);
- copy_v2_v2(cdd->prev.mouse, selem->mval);
-
- if (cdd->sample.use_substeps && cdd->prev.selem) {
- const struct StrokeElem selem_target = *selem;
- struct StrokeElem *selem_new_last = selem;
- if (len_sq >= SQUARE(STROKE_SAMPLE_DIST_MAX_PX)) {
- int n = (int)ceil(sqrt((double)len_sq)) / STROKE_SAMPLE_DIST_MAX_PX ;
-
- for (int i = 1; i < n; i++) {
- struct StrokeElem *selem_new = selem_new_last;
- stroke_elem_interp(selem_new, cdd->prev.selem, &selem_target, (float)i / n);
-
- const bool is_depth_found_substep = stroke_elem_project_fallback_elem(
- cdd, cdd->prev.location_world_valid, selem_new);
- if (is_depth_found == false) {
- if (is_depth_found_substep) {
- copy_v3_v3(cdd->prev.location_world_valid, selem_new->location_world);
- }
- }
-
- selem_new_last = BLI_mempool_calloc(cdd->stroke_elem_pool);
- }
- }
- selem = selem_new_last;
- *selem_new_last = selem_target;
- }
-
- cdd->prev.selem = selem;
-
- ED_region_tag_redraw(cdd->vc.ar);
+ struct CurveDrawData *cdd = op->customdata;
+ Object *obedit = cdd->vc.obedit;
+
+ invert_m4_m4(obedit->imat, obedit->obmat);
+
+ struct StrokeElem *selem = BLI_mempool_calloc(cdd->stroke_elem_pool);
+
+ ARRAY_SET_ITEMS(selem->mval, event->mval[0], event->mval[1]);
+
+ /* handle pressure sensitivity (which is supplied by tablets) */
+ if (event->tablet_data) {
+ const wmTabletData *wmtab = event->tablet_data;
+ selem->pressure = wmtab->Pressure;
+ }
+ else {
+ selem->pressure = 1.0f;
+ }
+
+ bool is_depth_found = stroke_elem_project_fallback_elem(
+ cdd, cdd->prev.location_world_valid, selem);
+
+ if (is_depth_found) {
+ /* use the depth if a fallback wasn't used */
+ copy_v3_v3(cdd->prev.location_world_valid, selem->location_world);
+ }
+ copy_v3_v3(cdd->prev.location_world, selem->location_world);
+
+ float len_sq = len_squared_v2v2(cdd->prev.mouse, selem->mval);
+ copy_v2_v2(cdd->prev.mouse, selem->mval);
+
+ if (cdd->sample.use_substeps && cdd->prev.selem) {
+ const struct StrokeElem selem_target = *selem;
+ struct StrokeElem *selem_new_last = selem;
+ if (len_sq >= SQUARE(STROKE_SAMPLE_DIST_MAX_PX)) {
+ int n = (int)ceil(sqrt((double)len_sq)) / STROKE_SAMPLE_DIST_MAX_PX;
+
+ for (int i = 1; i < n; i++) {
+ struct StrokeElem *selem_new = selem_new_last;
+ stroke_elem_interp(selem_new, cdd->prev.selem, &selem_target, (float)i / n);
+
+ const bool is_depth_found_substep = stroke_elem_project_fallback_elem(
+ cdd, cdd->prev.location_world_valid, selem_new);
+ if (is_depth_found == false) {
+ if (is_depth_found_substep) {
+ copy_v3_v3(cdd->prev.location_world_valid, selem_new->location_world);
+ }
+ }
+
+ selem_new_last = BLI_mempool_calloc(cdd->stroke_elem_pool);
+ }
+ }
+ selem = selem_new_last;
+ *selem_new_last = selem_target;
+ }
+
+ cdd->prev.selem = selem;
+
+ ED_region_tag_redraw(cdd->vc.ar);
}
static void curve_draw_event_add_first(wmOperator *op, const wmEvent *event)
{
- struct CurveDrawData *cdd = op->customdata;
- const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
-
- /* add first point */
- curve_draw_event_add(op, event);
-
- if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) && cdd->project.use_depth &&
- (cps->flag & CURVE_PAINT_FLAG_DEPTH_STROKE_ENDPOINTS))
- {
- RegionView3D *rv3d = cdd->vc.rv3d;
-
- cdd->project.use_depth = false;
- cdd->project.use_plane = true;
-
- float normal[3] = {0.0f};
- if (ELEM(cps->surface_plane,
- CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW,
- CURVE_PAINT_SURFACE_PLANE_NORMAL_SURFACE))
- {
- if (ED_view3d_depth_read_cached_normal(&cdd->vc, event->mval, normal)) {
- if (cps->surface_plane == CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW) {
- float cross_a[3], cross_b[3];
- cross_v3_v3v3(cross_a, rv3d->viewinv[2], normal);
- cross_v3_v3v3(cross_b, normal, cross_a);
- copy_v3_v3(normal, cross_b);
- }
- }
- }
-
- /* CURVE_PAINT_SURFACE_PLANE_VIEW or fallback */
- if (is_zero_v3(normal)) {
- copy_v3_v3(normal, rv3d->viewinv[2]);
- }
-
- normalize_v3_v3(cdd->project.plane, normal);
- cdd->project.plane[3] = -dot_v3v3(cdd->project.plane, cdd->prev.location_world_valid);
-
- /* Special case for when we only have offset applied on the first-hit,
- * the remaining stroke must be offset too. */
- if (cdd->project.surface_offset != 0.0f) {
- const float mval_fl[2] = {UNPACK2(event->mval)};
-
- float location_no_offset[3];
-
- if (stroke_elem_project(
- cdd, event->mval, mval_fl, 0.0f, 0.0f,
- location_no_offset, NULL))
- {
- sub_v3_v3v3(cdd->project.offset, cdd->prev.location_world_valid, location_no_offset);
- if (!is_zero_v3(cdd->project.offset)) {
- cdd->project.use_offset = true;
- }
- }
- }
- /* end special case */
-
- }
-
- cdd->init_event_type = event->type;
- cdd->state = CURVE_DRAW_PAINTING;
+ struct CurveDrawData *cdd = op->customdata;
+ const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
+
+ /* add first point */
+ curve_draw_event_add(op, event);
+
+ if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) && cdd->project.use_depth &&
+ (cps->flag & CURVE_PAINT_FLAG_DEPTH_STROKE_ENDPOINTS)) {
+ RegionView3D *rv3d = cdd->vc.rv3d;
+
+ cdd->project.use_depth = false;
+ cdd->project.use_plane = true;
+
+ float normal[3] = {0.0f};
+ if (ELEM(cps->surface_plane,
+ CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW,
+ CURVE_PAINT_SURFACE_PLANE_NORMAL_SURFACE)) {
+ if (ED_view3d_depth_read_cached_normal(&cdd->vc, event->mval, normal)) {
+ if (cps->surface_plane == CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW) {
+ float cross_a[3], cross_b[3];
+ cross_v3_v3v3(cross_a, rv3d->viewinv[2], normal);
+ cross_v3_v3v3(cross_b, normal, cross_a);
+ copy_v3_v3(normal, cross_b);
+ }
+ }
+ }
+
+ /* CURVE_PAINT_SURFACE_PLANE_VIEW or fallback */
+ if (is_zero_v3(normal)) {
+ copy_v3_v3(normal, rv3d->viewinv[2]);
+ }
+
+ normalize_v3_v3(cdd->project.plane, normal);
+ cdd->project.plane[3] = -dot_v3v3(cdd->project.plane, cdd->prev.location_world_valid);
+
+ /* Special case for when we only have offset applied on the first-hit,
+ * the remaining stroke must be offset too. */
+ if (cdd->project.surface_offset != 0.0f) {
+ const float mval_fl[2] = {UNPACK2(event->mval)};
+
+ float location_no_offset[3];
+
+ if (stroke_elem_project(cdd, event->mval, mval_fl, 0.0f, 0.0f, location_no_offset, NULL)) {
+ sub_v3_v3v3(cdd->project.offset, cdd->prev.location_world_valid, location_no_offset);
+ if (!is_zero_v3(cdd->project.offset)) {
+ cdd->project.use_offset = true;
+ }
+ }
+ }
+ /* end special case */
+ }
+
+ cdd->init_event_type = event->type;
+ cdd->state = CURVE_DRAW_PAINTING;
}
static bool curve_draw_init(bContext *C, wmOperator *op, bool is_invoke)
{
- BLI_assert(op->customdata == NULL);
+ BLI_assert(op->customdata == NULL);
- struct CurveDrawData *cdd = MEM_callocN(sizeof(*cdd), __func__);
+ struct CurveDrawData *cdd = MEM_callocN(sizeof(*cdd), __func__);
- cdd->depsgraph = CTX_data_depsgraph(C);
+ cdd->depsgraph = CTX_data_depsgraph(C);
- if (is_invoke) {
- ED_view3d_viewcontext_init(C, &cdd->vc);
- if (ELEM(NULL, cdd->vc.ar, cdd->vc.rv3d, cdd->vc.v3d, cdd->vc.win, cdd->vc.scene)) {
- MEM_freeN(cdd);
- BKE_report(op->reports, RPT_ERROR, "Unable to access 3D viewport");
- return false;
- }
- }
- else {
- cdd->vc.bmain = CTX_data_main(C);
- cdd->vc.depsgraph = CTX_data_depsgraph(C);
- cdd->vc.scene = CTX_data_scene(C);
- cdd->vc.view_layer = CTX_data_view_layer(C);
- cdd->vc.obedit = CTX_data_edit_object(C);
- }
+ if (is_invoke) {
+ ED_view3d_viewcontext_init(C, &cdd->vc);
+ if (ELEM(NULL, cdd->vc.ar, cdd->vc.rv3d, cdd->vc.v3d, cdd->vc.win, cdd->vc.scene)) {
+ MEM_freeN(cdd);
+ BKE_report(op->reports, RPT_ERROR, "Unable to access 3D viewport");
+ return false;
+ }
+ }
+ else {
+ cdd->vc.bmain = CTX_data_main(C);
+ cdd->vc.depsgraph = CTX_data_depsgraph(C);
+ cdd->vc.scene = CTX_data_scene(C);
+ cdd->vc.view_layer = CTX_data_view_layer(C);
+ cdd->vc.obedit = CTX_data_edit_object(C);
+ }
- op->customdata = cdd;
+ op->customdata = cdd;
- const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
+ const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
- cdd->curve_type = cps->curve_type;
+ cdd->curve_type = cps->curve_type;
- cdd->radius.min = cps->radius_min;
- cdd->radius.max = cps->radius_max;
- cdd->radius.range = cps->radius_max - cps->radius_min;
- cdd->project.surface_offset = cps->surface_offset;
- cdd->project.use_surface_offset_absolute = (cps->flag & CURVE_PAINT_FLAG_DEPTH_STROKE_OFFSET_ABS) != 0;
+ cdd->radius.min = cps->radius_min;
+ cdd->radius.max = cps->radius_max;
+ cdd->radius.range = cps->radius_max - cps->radius_min;
+ cdd->project.surface_offset = cps->surface_offset;
+ cdd->project.use_surface_offset_absolute = (cps->flag &
+ CURVE_PAINT_FLAG_DEPTH_STROKE_OFFSET_ABS) != 0;
- cdd->stroke_elem_pool = BLI_mempool_create(
- sizeof(struct StrokeElem), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
+ cdd->stroke_elem_pool = BLI_mempool_create(
+ sizeof(struct StrokeElem), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
- return true;
+ return true;
}
-
static void curve_draw_exit(wmOperator *op)
{
- struct CurveDrawData *cdd = op->customdata;
- if (cdd) {
- if (cdd->draw_handle_view) {
- ED_region_draw_cb_exit(cdd->vc.ar->type, cdd->draw_handle_view);
- WM_cursor_modal_restore(cdd->vc.win);
- }
-
- if (cdd->stroke_elem_pool) {
- BLI_mempool_destroy(cdd->stroke_elem_pool);
- }
-
- MEM_freeN(cdd);
- op->customdata = NULL;
- }
+ struct CurveDrawData *cdd = op->customdata;
+ if (cdd) {
+ if (cdd->draw_handle_view) {
+ ED_region_draw_cb_exit(cdd->vc.ar->type, cdd->draw_handle_view);
+ WM_cursor_modal_restore(cdd->vc.win);
+ }
+
+ if (cdd->stroke_elem_pool) {
+ BLI_mempool_destroy(cdd->stroke_elem_pool);
+ }
+
+ MEM_freeN(cdd);
+ op->customdata = NULL;
+ }
}
/**
@@ -645,583 +638,601 @@ static void curve_draw_exit(wmOperator *op)
*/
static void curve_draw_exec_precalc(wmOperator *op)
{
- struct CurveDrawData *cdd = op->customdata;
- const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
- PropertyRNA *prop;
-
- prop = RNA_struct_find_property(op->ptr, "fit_method");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_enum_set(op->ptr, prop, cps->fit_method);
- }
-
- prop = RNA_struct_find_property(op->ptr, "corner_angle");
- if (!RNA_property_is_set(op->ptr, prop)) {
- const float corner_angle = (cps->flag & CURVE_PAINT_FLAG_CORNERS_DETECT) ? cps->corner_angle : (float)M_PI;
- RNA_property_float_set(op->ptr, prop, corner_angle);
- }
-
- prop = RNA_struct_find_property(op->ptr, "error_threshold");
- if (!RNA_property_is_set(op->ptr, prop)) {
-
- /* error isnt set so we'll have to calculate it from the pixel values */
- BLI_mempool_iter iter;
- const struct StrokeElem *selem, *selem_prev;
-
- float len_3d = 0.0f, len_2d = 0.0f;
- float scale_px; /* pixel to local space scale */
-
- int i = 0;
- BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
- selem_prev = BLI_mempool_iterstep(&iter);
- for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter), i++) {
- len_3d += len_v3v3(selem->location_local, selem_prev->location_local);
- len_2d += len_v2v2(selem->mval, selem_prev->mval);
- selem_prev = selem;
- }
- scale_px = ((len_3d > 0.0f) && (len_2d > 0.0f)) ? (len_3d / len_2d) : 0.0f;
- float error_threshold = (cps->error_threshold * U.pixelsize) * scale_px;
- RNA_property_float_set(op->ptr, prop, error_threshold);
- }
-
- prop = RNA_struct_find_property(op->ptr, "use_cyclic");
- if (!RNA_property_is_set(op->ptr, prop)) {
- bool use_cyclic = false;
-
- if (BLI_mempool_len(cdd->stroke_elem_pool) > 2) {
- BLI_mempool_iter iter;
- const struct StrokeElem *selem, *selem_first, *selem_last;
-
- BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
- selem_first = selem_last = BLI_mempool_iterstep(&iter);
- for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
- selem_last = selem;
- }
-
- if (len_squared_v2v2(
- selem_first->mval,
- selem_last->mval) <= SQUARE(STROKE_CYCLIC_DIST_PX * U.pixelsize))
- {
- use_cyclic = true;
- }
- }
-
- RNA_property_boolean_set(op->ptr, prop, use_cyclic);
- }
-
-
- if ((cps->radius_taper_start != 0.0f) ||
- (cps->radius_taper_end != 0.0f))
- {
- /* note, we could try to de-duplicate the length calculations above */
- const int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
-
- BLI_mempool_iter iter;
- struct StrokeElem *selem, *selem_prev;
-
- float *lengths = MEM_mallocN(sizeof(float) * stroke_len, __func__);
- struct StrokeElem **selem_array = MEM_mallocN(sizeof(*selem_array) * stroke_len, __func__);
- lengths[0] = 0.0f;
-
- float len_3d = 0.0f;
-
- int i = 1;
- BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
- selem_prev = BLI_mempool_iterstep(&iter);
- selem_array[0] = selem_prev;
- for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter), i++) {
- const float len_3d_segment = len_v3v3(selem->location_local, selem_prev->location_local);
- len_3d += len_3d_segment;
- lengths[i] = len_3d;
- selem_array[i] = selem;
- selem_prev = selem;
- }
-
- if (cps->radius_taper_start != 0.0f) {
- const float len_taper_max = cps->radius_taper_start * len_3d;
- for (i = 0; i < stroke_len && lengths[i] < len_taper_max; i++) {
- const float pressure_new = selem_array[i]->pressure * (lengths[i] / len_taper_max);
- stroke_elem_pressure_set(cdd, selem_array[i], pressure_new);
- }
- }
-
- if (cps->radius_taper_end != 0.0f) {
- const float len_taper_max = cps->radius_taper_end * len_3d;
- const float len_taper_min = len_3d - len_taper_max;
- for (i = stroke_len - 1; i > 0 && lengths[i] > len_taper_min; i--) {
- const float pressure_new = selem_array[i]->pressure * ((len_3d - lengths[i]) / len_taper_max);
- stroke_elem_pressure_set(cdd, selem_array[i], pressure_new);
- }
- }
-
- MEM_freeN(lengths);
- MEM_freeN(selem_array);
- }
+ struct CurveDrawData *cdd = op->customdata;
+ const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
+ PropertyRNA *prop;
+
+ prop = RNA_struct_find_property(op->ptr, "fit_method");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, cps->fit_method);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "corner_angle");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ const float corner_angle = (cps->flag & CURVE_PAINT_FLAG_CORNERS_DETECT) ? cps->corner_angle :
+ (float)M_PI;
+ RNA_property_float_set(op->ptr, prop, corner_angle);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "error_threshold");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+
+ /* error isnt set so we'll have to calculate it from the pixel values */
+ BLI_mempool_iter iter;
+ const struct StrokeElem *selem, *selem_prev;
+
+ float len_3d = 0.0f, len_2d = 0.0f;
+ float scale_px; /* pixel to local space scale */
+
+ int i = 0;
+ BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
+ selem_prev = BLI_mempool_iterstep(&iter);
+ for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter), i++) {
+ len_3d += len_v3v3(selem->location_local, selem_prev->location_local);
+ len_2d += len_v2v2(selem->mval, selem_prev->mval);
+ selem_prev = selem;
+ }
+ scale_px = ((len_3d > 0.0f) && (len_2d > 0.0f)) ? (len_3d / len_2d) : 0.0f;
+ float error_threshold = (cps->error_threshold * U.pixelsize) * scale_px;
+ RNA_property_float_set(op->ptr, prop, error_threshold);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "use_cyclic");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ bool use_cyclic = false;
+
+ if (BLI_mempool_len(cdd->stroke_elem_pool) > 2) {
+ BLI_mempool_iter iter;
+ const struct StrokeElem *selem, *selem_first, *selem_last;
+
+ BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
+ selem_first = selem_last = BLI_mempool_iterstep(&iter);
+ for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
+ selem_last = selem;
+ }
+
+ if (len_squared_v2v2(selem_first->mval, selem_last->mval) <=
+ SQUARE(STROKE_CYCLIC_DIST_PX * U.pixelsize)) {
+ use_cyclic = true;
+ }
+ }
+
+ RNA_property_boolean_set(op->ptr, prop, use_cyclic);
+ }
+
+ if ((cps->radius_taper_start != 0.0f) || (cps->radius_taper_end != 0.0f)) {
+ /* note, we could try to de-duplicate the length calculations above */
+ const int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
+
+ BLI_mempool_iter iter;
+ struct StrokeElem *selem, *selem_prev;
+
+ float *lengths = MEM_mallocN(sizeof(float) * stroke_len, __func__);
+ struct StrokeElem **selem_array = MEM_mallocN(sizeof(*selem_array) * stroke_len, __func__);
+ lengths[0] = 0.0f;
+
+ float len_3d = 0.0f;
+
+ int i = 1;
+ BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
+ selem_prev = BLI_mempool_iterstep(&iter);
+ selem_array[0] = selem_prev;
+ for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter), i++) {
+ const float len_3d_segment = len_v3v3(selem->location_local, selem_prev->location_local);
+ len_3d += len_3d_segment;
+ lengths[i] = len_3d;
+ selem_array[i] = selem;
+ selem_prev = selem;
+ }
+
+ if (cps->radius_taper_start != 0.0f) {
+ const float len_taper_max = cps->radius_taper_start * len_3d;
+ for (i = 0; i < stroke_len && lengths[i] < len_taper_max; i++) {
+ const float pressure_new = selem_array[i]->pressure * (lengths[i] / len_taper_max);
+ stroke_elem_pressure_set(cdd, selem_array[i], pressure_new);
+ }
+ }
+
+ if (cps->radius_taper_end != 0.0f) {
+ const float len_taper_max = cps->radius_taper_end * len_3d;
+ const float len_taper_min = len_3d - len_taper_max;
+ for (i = stroke_len - 1; i > 0 && lengths[i] > len_taper_min; i--) {
+ const float pressure_new = selem_array[i]->pressure *
+ ((len_3d - lengths[i]) / len_taper_max);
+ stroke_elem_pressure_set(cdd, selem_array[i], pressure_new);
+ }
+ }
+
+ MEM_freeN(lengths);
+ MEM_freeN(selem_array);
+ }
}
static int curve_draw_exec(bContext *C, wmOperator *op)
{
- if (op->customdata == NULL) {
- if (!curve_draw_init(C, op, false)) {
- return OPERATOR_CANCELLED;
- }
- }
+ if (op->customdata == NULL) {
+ if (!curve_draw_init(C, op, false)) {
+ return OPERATOR_CANCELLED;
+ }
+ }
- struct CurveDrawData *cdd = op->customdata;
+ struct CurveDrawData *cdd = op->customdata;
- const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
- Object *obedit = cdd->vc.obedit;
- Curve *cu = obedit->data;
- ListBase *nurblist = object_editcurve_get(obedit);
+ const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
+ Object *obedit = cdd->vc.obedit;
+ Curve *cu = obedit->data;
+ ListBase *nurblist = object_editcurve_get(obedit);
- int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
+ int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
- const bool is_3d = (cu->flag & CU_3D) != 0;
- invert_m4_m4(obedit->imat, obedit->obmat);
+ const bool is_3d = (cu->flag & CU_3D) != 0;
+ invert_m4_m4(obedit->imat, obedit->obmat);
- if (BLI_mempool_len(cdd->stroke_elem_pool) == 0) {
- curve_draw_stroke_from_operator(op);
- stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
- }
+ if (BLI_mempool_len(cdd->stroke_elem_pool) == 0) {
+ curve_draw_stroke_from_operator(op);
+ stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
+ }
- /* Deselect all existing curves. */
- ED_curve_deselect_all_multi(C);
+ /* Deselect all existing curves. */
+ ED_curve_deselect_all_multi(C);
- const float radius_min = cps->radius_min;
- const float radius_max = cps->radius_max;
- const float radius_range = cps->radius_max - cps->radius_min;
+ const float radius_min = cps->radius_min;
+ const float radius_max = cps->radius_max;
+ const float radius_range = cps->radius_max - cps->radius_min;
- Nurb *nu = MEM_callocN(sizeof(Nurb), __func__);
- nu->pntsv = 0;
- nu->resolu = cu->resolu;
- nu->resolv = cu->resolv;
- nu->flag |= CU_SMOOTH;
+ Nurb *nu = MEM_callocN(sizeof(Nurb), __func__);
+ nu->pntsv = 0;
+ nu->resolu = cu->resolu;
+ nu->resolv = cu->resolv;
+ nu->flag |= CU_SMOOTH;
- const bool use_pressure_radius =
- (cps->flag & CURVE_PAINT_FLAG_PRESSURE_RADIUS) ||
- ((cps->radius_taper_start != 0.0f) ||
- (cps->radius_taper_end != 0.0f));
+ const bool use_pressure_radius = (cps->flag & CURVE_PAINT_FLAG_PRESSURE_RADIUS) ||
+ ((cps->radius_taper_start != 0.0f) ||
+ (cps->radius_taper_end != 0.0f));
- if (cdd->curve_type == CU_BEZIER) {
- nu->type = CU_BEZIER;
+ if (cdd->curve_type == CU_BEZIER) {
+ nu->type = CU_BEZIER;
#ifdef USE_SPLINE_FIT
- /* Allow to interpolate multiple channels */
- int dims = 3;
- struct {
- int radius;
- } coords_indices;
- coords_indices.radius = use_pressure_radius ? dims++ : -1;
-
- float *coords = MEM_mallocN(sizeof(*coords) * stroke_len * dims, __func__);
-
- float *cubic_spline = NULL;
- unsigned int cubic_spline_len = 0;
-
- /* error in object local space */
- const int fit_method = RNA_enum_get(op->ptr, "fit_method");
- const float error_threshold = RNA_float_get(op->ptr, "error_threshold");
- const float corner_angle = RNA_float_get(op->ptr, "corner_angle");
- const bool use_cyclic = RNA_boolean_get(op->ptr, "use_cyclic");
-
- {
- BLI_mempool_iter iter;
- const struct StrokeElem *selem;
- float *co = coords;
-
- BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
- for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter), co += dims) {
- copy_v3_v3(co, selem->location_local);
- if (coords_indices.radius != -1) {
- co[coords_indices.radius] = selem->pressure;
- }
-
- /* remove doubles */
- if ((co != coords) && UNLIKELY(memcmp(co, co - dims, sizeof(float) * dims) == 0)) {
- co -= dims;
- stroke_len--;
- }
- }
- }
-
- unsigned int *corners = NULL;
- unsigned int corners_len = 0;
-
- if ((fit_method == CURVE_PAINT_FIT_METHOD_SPLIT) && (corner_angle < (float)M_PI)) {
- /* this could be configurable... */
- const float corner_radius_min = error_threshold / 8;
- const float corner_radius_max = error_threshold * 2;
- const unsigned int samples_max = 16;
-
- curve_fit_corners_detect_fl(
- coords, stroke_len, dims,
- corner_radius_min, corner_radius_max,
- samples_max, corner_angle,
- &corners, &corners_len);
- }
-
- unsigned int *corners_index = NULL;
- unsigned int corners_index_len = 0;
- unsigned int calc_flag = CURVE_FIT_CALC_HIGH_QUALIY;
-
- if ((stroke_len > 2) && use_cyclic) {
- calc_flag |= CURVE_FIT_CALC_CYCLIC;
- }
-
- int result;
- if (fit_method == CURVE_PAINT_FIT_METHOD_REFIT) {
- result = curve_fit_cubic_to_points_refit_fl(
- coords, stroke_len, dims, error_threshold, calc_flag,
- NULL, 0, corner_angle,
- &cubic_spline, &cubic_spline_len,
- NULL,
- &corners_index, &corners_index_len);
- }
- else {
- result = curve_fit_cubic_to_points_fl(
- coords, stroke_len, dims, error_threshold, calc_flag,
- corners, corners_len,
- &cubic_spline, &cubic_spline_len,
- NULL,
- &corners_index, &corners_index_len);
- }
-
- MEM_freeN(coords);
- if (corners) {
- free(corners);
- }
-
- if (result == 0) {
- nu->pntsu = cubic_spline_len;
- nu->bezt = MEM_callocN(sizeof(BezTriple) * nu->pntsu, __func__);
-
- float *co = cubic_spline;
- BezTriple *bezt = nu->bezt;
- for (int j = 0; j < cubic_spline_len; j++, bezt++, co += (dims * 3)) {
- const float *handle_l = co + (dims * 0);
- const float *pt = co + (dims * 1);
- const float *handle_r = co + (dims * 2);
-
- copy_v3_v3(bezt->vec[0], handle_l);
- copy_v3_v3(bezt->vec[1], pt);
- copy_v3_v3(bezt->vec[2], handle_r);
-
- if (coords_indices.radius != -1) {
- bezt->radius = (pt[coords_indices.radius] * cdd->radius.range) + cdd->radius.min;
- }
- else {
- bezt->radius = radius_max;
- }
-
- bezt->h1 = bezt->h2 = HD_ALIGN; /* will set to free in second pass */
- bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
- }
-
- if (corners_index) {
- /* ignore the first and last */
- unsigned int i_start = 0, i_end = corners_index_len;
-
- if ((corners_index_len >= 2) &&
- (calc_flag & CURVE_FIT_CALC_CYCLIC) == 0)
- {
- i_start += 1;
- i_end -= 1;
- }
-
- for (unsigned int i = i_start; i < i_end; i++) {
- bezt = &nu->bezt[corners_index[i]];
- bezt->h1 = bezt->h2 = HD_FREE;
- }
- }
-
- if (calc_flag & CURVE_FIT_CALC_CYCLIC) {
- nu->flagu |= CU_NURB_CYCLIC;
- }
- }
-
- if (corners_index) {
- free(corners_index);
- }
-
- if (cubic_spline) {
- free(cubic_spline);
- }
+ /* Allow to interpolate multiple channels */
+ int dims = 3;
+ struct {
+ int radius;
+ } coords_indices;
+ coords_indices.radius = use_pressure_radius ? dims++ : -1;
+
+ float *coords = MEM_mallocN(sizeof(*coords) * stroke_len * dims, __func__);
+
+ float *cubic_spline = NULL;
+ unsigned int cubic_spline_len = 0;
+
+ /* error in object local space */
+ const int fit_method = RNA_enum_get(op->ptr, "fit_method");
+ const float error_threshold = RNA_float_get(op->ptr, "error_threshold");
+ const float corner_angle = RNA_float_get(op->ptr, "corner_angle");
+ const bool use_cyclic = RNA_boolean_get(op->ptr, "use_cyclic");
+
+ {
+ BLI_mempool_iter iter;
+ const struct StrokeElem *selem;
+ float *co = coords;
+
+ BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
+ for (selem = BLI_mempool_iterstep(&iter); selem;
+ selem = BLI_mempool_iterstep(&iter), co += dims) {
+ copy_v3_v3(co, selem->location_local);
+ if (coords_indices.radius != -1) {
+ co[coords_indices.radius] = selem->pressure;
+ }
+
+ /* remove doubles */
+ if ((co != coords) && UNLIKELY(memcmp(co, co - dims, sizeof(float) * dims) == 0)) {
+ co -= dims;
+ stroke_len--;
+ }
+ }
+ }
+
+ unsigned int *corners = NULL;
+ unsigned int corners_len = 0;
+
+ if ((fit_method == CURVE_PAINT_FIT_METHOD_SPLIT) && (corner_angle < (float)M_PI)) {
+ /* this could be configurable... */
+ const float corner_radius_min = error_threshold / 8;
+ const float corner_radius_max = error_threshold * 2;
+ const unsigned int samples_max = 16;
+
+ curve_fit_corners_detect_fl(coords,
+ stroke_len,
+ dims,
+ corner_radius_min,
+ corner_radius_max,
+ samples_max,
+ corner_angle,
+ &corners,
+ &corners_len);
+ }
+
+ unsigned int *corners_index = NULL;
+ unsigned int corners_index_len = 0;
+ unsigned int calc_flag = CURVE_FIT_CALC_HIGH_QUALIY;
+
+ if ((stroke_len > 2) && use_cyclic) {
+ calc_flag |= CURVE_FIT_CALC_CYCLIC;
+ }
+
+ int result;
+ if (fit_method == CURVE_PAINT_FIT_METHOD_REFIT) {
+ result = curve_fit_cubic_to_points_refit_fl(coords,
+ stroke_len,
+ dims,
+ error_threshold,
+ calc_flag,
+ NULL,
+ 0,
+ corner_angle,
+ &cubic_spline,
+ &cubic_spline_len,
+ NULL,
+ &corners_index,
+ &corners_index_len);
+ }
+ else {
+ result = curve_fit_cubic_to_points_fl(coords,
+ stroke_len,
+ dims,
+ error_threshold,
+ calc_flag,
+ corners,
+ corners_len,
+ &cubic_spline,
+ &cubic_spline_len,
+ NULL,
+ &corners_index,
+ &corners_index_len);
+ }
+
+ MEM_freeN(coords);
+ if (corners) {
+ free(corners);
+ }
+
+ if (result == 0) {
+ nu->pntsu = cubic_spline_len;
+ nu->bezt = MEM_callocN(sizeof(BezTriple) * nu->pntsu, __func__);
+
+ float *co = cubic_spline;
+ BezTriple *bezt = nu->bezt;
+ for (int j = 0; j < cubic_spline_len; j++, bezt++, co += (dims * 3)) {
+ const float *handle_l = co + (dims * 0);
+ const float *pt = co + (dims * 1);
+ const float *handle_r = co + (dims * 2);
+
+ copy_v3_v3(bezt->vec[0], handle_l);
+ copy_v3_v3(bezt->vec[1], pt);
+ copy_v3_v3(bezt->vec[2], handle_r);
+
+ if (coords_indices.radius != -1) {
+ bezt->radius = (pt[coords_indices.radius] * cdd->radius.range) + cdd->radius.min;
+ }
+ else {
+ bezt->radius = radius_max;
+ }
+
+ bezt->h1 = bezt->h2 = HD_ALIGN; /* will set to free in second pass */
+ bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
+ }
+
+ if (corners_index) {
+ /* ignore the first and last */
+ unsigned int i_start = 0, i_end = corners_index_len;
+
+ if ((corners_index_len >= 2) && (calc_flag & CURVE_FIT_CALC_CYCLIC) == 0) {
+ i_start += 1;
+ i_end -= 1;
+ }
+
+ for (unsigned int i = i_start; i < i_end; i++) {
+ bezt = &nu->bezt[corners_index[i]];
+ bezt->h1 = bezt->h2 = HD_FREE;
+ }
+ }
+
+ if (calc_flag & CURVE_FIT_CALC_CYCLIC) {
+ nu->flagu |= CU_NURB_CYCLIC;
+ }
+ }
+
+ if (corners_index) {
+ free(corners_index);
+ }
+
+ if (cubic_spline) {
+ free(cubic_spline);
+ }
#else
- nu->pntsu = stroke_len;
- nu->bezt = MEM_callocN(nu->pntsu * sizeof(BezTriple), __func__);
-
- BezTriple *bezt = nu->bezt;
-
- {
- BLI_mempool_iter iter;
- const struct StrokeElem *selem;
-
- BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
- for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
- copy_v3_v3(bezt->vec[1], selem->location_local);
- if (!is_3d) {
- bezt->vec[1][2] = 0.0f;
- }
-
- if (use_pressure_radius) {
- bezt->radius = selem->pressure;
- }
- else {
- bezt->radius = radius_max;
- }
-
- bezt->h1 = bezt->h2 = HD_AUTO;
-
- bezt->f1 |= SELECT;
- bezt->f2 |= SELECT;
- bezt->f3 |= SELECT;
-
- bezt++;
- }
- }
+ nu->pntsu = stroke_len;
+ nu->bezt = MEM_callocN(nu->pntsu * sizeof(BezTriple), __func__);
+
+ BezTriple *bezt = nu->bezt;
+
+ {
+ BLI_mempool_iter iter;
+ const struct StrokeElem *selem;
+
+ BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
+ for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
+ copy_v3_v3(bezt->vec[1], selem->location_local);
+ if (!is_3d) {
+ bezt->vec[1][2] = 0.0f;
+ }
+
+ if (use_pressure_radius) {
+ bezt->radius = selem->pressure;
+ }
+ else {
+ bezt->radius = radius_max;
+ }
+
+ bezt->h1 = bezt->h2 = HD_AUTO;
+
+ bezt->f1 |= SELECT;
+ bezt->f2 |= SELECT;
+ bezt->f3 |= SELECT;
+
+ bezt++;
+ }
+ }
#endif
- BKE_nurb_handles_calc(nu);
- }
- else { /* CU_POLY */
- BLI_mempool_iter iter;
- const struct StrokeElem *selem;
+ BKE_nurb_handles_calc(nu);
+ }
+ else { /* CU_POLY */
+ BLI_mempool_iter iter;
+ const struct StrokeElem *selem;
- nu->pntsu = stroke_len;
- nu->pntsv = 1;
- nu->type = CU_POLY;
- nu->bp = MEM_callocN(nu->pntsu * sizeof(BPoint), __func__);
+ nu->pntsu = stroke_len;
+ nu->pntsv = 1;
+ nu->type = CU_POLY;
+ nu->bp = MEM_callocN(nu->pntsu * sizeof(BPoint), __func__);
- /* Misc settings. */
- nu->resolu = cu->resolu;
- nu->resolv = 1;
- nu->orderu = 4;
- nu->orderv = 1;
+ /* Misc settings. */
+ nu->resolu = cu->resolu;
+ nu->resolv = 1;
+ nu->orderu = 4;
+ nu->orderv = 1;
- BPoint *bp = nu->bp;
+ BPoint *bp = nu->bp;
- BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
- for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
- copy_v3_v3(bp->vec, selem->location_local);
- if (!is_3d) {
- bp->vec[2] = 0.0f;
- }
+ BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
+ for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) {
+ copy_v3_v3(bp->vec, selem->location_local);
+ if (!is_3d) {
+ bp->vec[2] = 0.0f;
+ }
- if (use_pressure_radius) {
- bp->radius = (selem->pressure * radius_range) + radius_min;
- }
- else {
- bp->radius = cps->radius_max;
- }
- bp->f1 = SELECT;
- bp->vec[3] = 1.0f;
+ if (use_pressure_radius) {
+ bp->radius = (selem->pressure * radius_range) + radius_min;
+ }
+ else {
+ bp->radius = cps->radius_max;
+ }
+ bp->f1 = SELECT;
+ bp->vec[3] = 1.0f;
- bp++;
- }
+ bp++;
+ }
- BKE_nurb_knot_calc_u(nu);
- }
+ BKE_nurb_knot_calc_u(nu);
+ }
- BLI_addtail(nurblist, nu);
+ BLI_addtail(nurblist, nu);
- BKE_curve_nurb_active_set(cu, nu);
- cu->actvert = nu->pntsu - 1;
+ BKE_curve_nurb_active_set(cu, nu);
+ cu->actvert = nu->pntsu - 1;
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
- curve_draw_exit(op);
+ curve_draw_exit(op);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (RNA_struct_property_is_set(op->ptr, "stroke")) {
- return curve_draw_exec(C, op);
- }
-
- if (!curve_draw_init(C, op, true)) {
- return OPERATOR_CANCELLED;
- }
-
- struct CurveDrawData *cdd = op->customdata;
-
- const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
-
- const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
-
- /* fallback (incase we can't find the depth on first test) */
- {
- const float mval_fl[2] = {UNPACK2(event->mval)};
- float center[3];
- negate_v3_v3(center, cdd->vc.rv3d->ofs);
- ED_view3d_win_to_3d(cdd->vc.v3d, cdd->vc.ar, center, mval_fl, cdd->prev.location_world);
- copy_v3_v3(cdd->prev.location_world_valid, cdd->prev.location_world);
- }
-
- cdd->draw_handle_view = ED_region_draw_cb_activate(
- cdd->vc.ar->type, curve_draw_stroke_3d, op, REGION_DRAW_POST_VIEW);
- WM_cursor_modal_set(cdd->vc.win, BC_PAINTBRUSHCURSOR);
-
- {
- View3D *v3d = cdd->vc.v3d;
- RegionView3D *rv3d = cdd->vc.rv3d;
- Object *obedit = cdd->vc.obedit;
- Curve *cu = obedit->data;
-
- const float *plane_no = NULL;
- const float *plane_co = NULL;
-
- if ((cu->flag & CU_3D) == 0) {
- /* 2D overrides other options */
- plane_co = obedit->obmat[3];
- plane_no = obedit->obmat[2];
- cdd->project.use_plane = true;
- }
- else {
- if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) &&
- (v3d->shading.type > OB_WIRE))
- {
- /* needed or else the draw matrix can be incorrect */
- view3d_operator_needs_opengl(C);
-
- ED_view3d_autodist_init(cdd->vc.depsgraph, cdd->vc.ar, cdd->vc.v3d, 0);
-
- if (cdd->vc.rv3d->depths) {
- cdd->vc.rv3d->depths->damaged = true;
- }
-
- ED_view3d_depth_update(cdd->vc.ar);
-
- if (cdd->vc.rv3d->depths != NULL) {
- cdd->project.use_depth = true;
- }
- else {
- BKE_report(op->reports, RPT_WARNING, "Unable to access depth buffer, using view plane");
- cdd->project.use_depth = false;
- }
- }
-
- /* use view plane (when set or as fallback when surface can't be found) */
- if (cdd->project.use_depth == false) {
- plane_co = cdd->vc.scene->cursor.location;
- plane_no = rv3d->viewinv[2];
- cdd->project.use_plane = true;
- }
-
- if (cdd->project.use_depth && (cdd->curve_type != CU_POLY)) {
- cdd->sample.use_substeps = true;
- }
- }
-
- if (cdd->project.use_plane) {
- normalize_v3_v3(cdd->project.plane, plane_no);
- cdd->project.plane[3] = -dot_v3v3(cdd->project.plane, plane_co);
- }
- }
-
- if (is_modal == false) {
- curve_draw_event_add_first(op, event);
- }
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
+ if (RNA_struct_property_is_set(op->ptr, "stroke")) {
+ return curve_draw_exec(C, op);
+ }
+
+ if (!curve_draw_init(C, op, true)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ struct CurveDrawData *cdd = op->customdata;
+
+ const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
+
+ const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
+
+ /* fallback (incase we can't find the depth on first test) */
+ {
+ const float mval_fl[2] = {UNPACK2(event->mval)};
+ float center[3];
+ negate_v3_v3(center, cdd->vc.rv3d->ofs);
+ ED_view3d_win_to_3d(cdd->vc.v3d, cdd->vc.ar, center, mval_fl, cdd->prev.location_world);
+ copy_v3_v3(cdd->prev.location_world_valid, cdd->prev.location_world);
+ }
+
+ cdd->draw_handle_view = ED_region_draw_cb_activate(
+ cdd->vc.ar->type, curve_draw_stroke_3d, op, REGION_DRAW_POST_VIEW);
+ WM_cursor_modal_set(cdd->vc.win, BC_PAINTBRUSHCURSOR);
+
+ {
+ View3D *v3d = cdd->vc.v3d;
+ RegionView3D *rv3d = cdd->vc.rv3d;
+ Object *obedit = cdd->vc.obedit;
+ Curve *cu = obedit->data;
+
+ const float *plane_no = NULL;
+ const float *plane_co = NULL;
+
+ if ((cu->flag & CU_3D) == 0) {
+ /* 2D overrides other options */
+ plane_co = obedit->obmat[3];
+ plane_no = obedit->obmat[2];
+ cdd->project.use_plane = true;
+ }
+ else {
+ if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) && (v3d->shading.type > OB_WIRE)) {
+ /* needed or else the draw matrix can be incorrect */
+ view3d_operator_needs_opengl(C);
+
+ ED_view3d_autodist_init(cdd->vc.depsgraph, cdd->vc.ar, cdd->vc.v3d, 0);
+
+ if (cdd->vc.rv3d->depths) {
+ cdd->vc.rv3d->depths->damaged = true;
+ }
+
+ ED_view3d_depth_update(cdd->vc.ar);
+
+ if (cdd->vc.rv3d->depths != NULL) {
+ cdd->project.use_depth = true;
+ }
+ else {
+ BKE_report(op->reports, RPT_WARNING, "Unable to access depth buffer, using view plane");
+ cdd->project.use_depth = false;
+ }
+ }
+
+ /* use view plane (when set or as fallback when surface can't be found) */
+ if (cdd->project.use_depth == false) {
+ plane_co = cdd->vc.scene->cursor.location;
+ plane_no = rv3d->viewinv[2];
+ cdd->project.use_plane = true;
+ }
+
+ if (cdd->project.use_depth && (cdd->curve_type != CU_POLY)) {
+ cdd->sample.use_substeps = true;
+ }
+ }
+
+ if (cdd->project.use_plane) {
+ normalize_v3_v3(cdd->project.plane, plane_no);
+ cdd->project.plane[3] = -dot_v3v3(cdd->project.plane, plane_co);
+ }
+ }
+
+ if (is_modal == false) {
+ curve_draw_event_add_first(op, event);
+ }
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
}
static void curve_draw_cancel(bContext *UNUSED(C), wmOperator *op)
{
- curve_draw_exit(op);
+ curve_draw_exit(op);
}
-
/* Modal event handling of frame changing */
static int curve_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- int ret = OPERATOR_RUNNING_MODAL;
- struct CurveDrawData *cdd = op->customdata;
-
- UNUSED_VARS(C, op);
-
- if (event->type == cdd->init_event_type) {
- if (event->val == KM_RELEASE) {
- ED_region_tag_redraw(cdd->vc.ar);
-
- curve_draw_exec_precalc(op);
-
- curve_draw_stroke_to_operator(op);
-
- curve_draw_exec(C, op);
-
- return OPERATOR_FINISHED;
- }
- }
- else if (ELEM(event->type, ESCKEY, RIGHTMOUSE)) {
- ED_region_tag_redraw(cdd->vc.ar);
- curve_draw_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
- else if (ELEM(event->type, LEFTMOUSE)) {
- if (event->val == KM_PRESS) {
- curve_draw_event_add_first(op, event);
- }
- }
- else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
- if (cdd->state == CURVE_DRAW_PAINTING) {
- const float mval_fl[2] = {UNPACK2(event->mval)};
- if (len_squared_v2v2(mval_fl, cdd->prev.mouse) > SQUARE(STROKE_SAMPLE_DIST_MIN_PX)) {
- curve_draw_event_add(op, event);
- }
- }
- }
-
- return ret;
+ int ret = OPERATOR_RUNNING_MODAL;
+ struct CurveDrawData *cdd = op->customdata;
+
+ UNUSED_VARS(C, op);
+
+ if (event->type == cdd->init_event_type) {
+ if (event->val == KM_RELEASE) {
+ ED_region_tag_redraw(cdd->vc.ar);
+
+ curve_draw_exec_precalc(op);
+
+ curve_draw_stroke_to_operator(op);
+
+ curve_draw_exec(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+ }
+ else if (ELEM(event->type, ESCKEY, RIGHTMOUSE)) {
+ ED_region_tag_redraw(cdd->vc.ar);
+ curve_draw_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ else if (ELEM(event->type, LEFTMOUSE)) {
+ if (event->val == KM_PRESS) {
+ curve_draw_event_add_first(op, event);
+ }
+ }
+ else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ if (cdd->state == CURVE_DRAW_PAINTING) {
+ const float mval_fl[2] = {UNPACK2(event->mval)};
+ if (len_squared_v2v2(mval_fl, cdd->prev.mouse) > SQUARE(STROKE_SAMPLE_DIST_MIN_PX)) {
+ curve_draw_event_add(op, event);
+ }
+ }
+ }
+
+ return ret;
}
void CURVE_OT_draw(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Draw Curve";
- ot->idname = "CURVE_OT_draw";
- ot->description = "Draw a freehand spline";
-
- /* api callbacks */
- ot->exec = curve_draw_exec;
- ot->invoke = curve_draw_invoke;
- ot->cancel = curve_draw_cancel;
- ot->modal = curve_draw_modal;
- ot->poll = ED_operator_editcurve;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- PropertyRNA *prop;
-
- prop = RNA_def_float_distance(
- ot->srna, "error_threshold", 0.0f, 0.0f, 10.0f, "Error",
- "Error distance threshold (in object units)",
- 0.0001f, 10.0f);
- RNA_def_property_ui_range(prop, 0.0, 10, 1, 4);
-
- RNA_def_enum(ot->srna, "fit_method", rna_enum_curve_fit_method_items, CURVE_PAINT_FIT_METHOD_REFIT,
- "Fit Method", "");
-
- prop = RNA_def_float_distance(
- ot->srna, "corner_angle", DEG2RADF(70.0f), 0.0f, M_PI, "Corner Angle", "", 0.0f, M_PI);
- RNA_def_property_subtype(prop, PROP_ANGLE);
-
- prop = RNA_def_boolean(ot->srna, "use_cyclic", true, "Cyclic", "");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ /* identifiers */
+ ot->name = "Draw Curve";
+ ot->idname = "CURVE_OT_draw";
+ ot->description = "Draw a freehand spline";
+
+ /* api callbacks */
+ ot->exec = curve_draw_exec;
+ ot->invoke = curve_draw_invoke;
+ ot->cancel = curve_draw_cancel;
+ ot->modal = curve_draw_modal;
+ ot->poll = ED_operator_editcurve;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ PropertyRNA *prop;
+
+ prop = RNA_def_float_distance(ot->srna,
+ "error_threshold",
+ 0.0f,
+ 0.0f,
+ 10.0f,
+ "Error",
+ "Error distance threshold (in object units)",
+ 0.0001f,
+ 10.0f);
+ RNA_def_property_ui_range(prop, 0.0, 10, 1, 4);
+
+ RNA_def_enum(ot->srna,
+ "fit_method",
+ rna_enum_curve_fit_method_items,
+ CURVE_PAINT_FIT_METHOD_REFIT,
+ "Fit Method",
+ "");
+
+ prop = RNA_def_float_distance(
+ ot->srna, "corner_angle", DEG2RADF(70.0f), 0.0f, M_PI, "Corner Angle", "", 0.0f, M_PI);
+ RNA_def_property_subtype(prop, PROP_ANGLE);
+
+ prop = RNA_def_boolean(ot->srna, "use_cyclic", true, "Cyclic", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
/** \} */
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index d9392090166..d3f0ebfda3c 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -59,271 +59,272 @@
/* returns 1 in case (de)selection was successful */
bool select_beztriple(BezTriple *bezt, bool selstatus, short flag, eVisible_Types hidden)
{
- if ((bezt->hide == 0) || (hidden == HIDDEN)) {
- if (selstatus == SELECT) { /* selects */
- bezt->f1 |= flag;
- bezt->f2 |= flag;
- bezt->f3 |= flag;
- return true;
- }
- else { /* deselects */
- bezt->f1 &= ~flag;
- bezt->f2 &= ~flag;
- bezt->f3 &= ~flag;
- return true;
- }
- }
-
- return false;
+ if ((bezt->hide == 0) || (hidden == HIDDEN)) {
+ if (selstatus == SELECT) { /* selects */
+ bezt->f1 |= flag;
+ bezt->f2 |= flag;
+ bezt->f3 |= flag;
+ return true;
+ }
+ else { /* deselects */
+ bezt->f1 &= ~flag;
+ bezt->f2 &= ~flag;
+ bezt->f3 &= ~flag;
+ return true;
+ }
+ }
+
+ return false;
}
/* returns 1 in case (de)selection was successful */
bool select_bpoint(BPoint *bp, bool selstatus, short flag, bool hidden)
{
- if ((bp->hide == 0) || (hidden == 1)) {
- if (selstatus == SELECT) {
- bp->f1 |= flag;
- return true;
- }
- else {
- bp->f1 &= ~flag;
- return true;
- }
- }
-
- return false;
+ if ((bp->hide == 0) || (hidden == 1)) {
+ if (selstatus == SELECT) {
+ bp->f1 |= flag;
+ return true;
+ }
+ else {
+ bp->f1 &= ~flag;
+ return true;
+ }
+ }
+
+ return false;
}
static bool swap_selection_beztriple(BezTriple *bezt)
{
- if (bezt->f2 & SELECT) {
- return select_beztriple(bezt, DESELECT, SELECT, VISIBLE);
- }
- else {
- return select_beztriple(bezt, SELECT, SELECT, VISIBLE);
- }
+ if (bezt->f2 & SELECT) {
+ return select_beztriple(bezt, DESELECT, SELECT, VISIBLE);
+ }
+ else {
+ return select_beztriple(bezt, SELECT, SELECT, VISIBLE);
+ }
}
static bool swap_selection_bpoint(BPoint *bp)
{
- if (bp->f1 & SELECT) {
- return select_bpoint(bp, DESELECT, SELECT, VISIBLE);
- }
- else {
- return select_bpoint(bp, SELECT, SELECT, VISIBLE);
- }
+ if (bp->f1 & SELECT) {
+ return select_bpoint(bp, DESELECT, SELECT, VISIBLE);
+ }
+ else {
+ return select_bpoint(bp, SELECT, SELECT, VISIBLE);
+ }
}
bool ED_curve_nurb_select_check(View3D *v3d, Nurb *nu)
{
- if (nu->type == CU_BEZIER) {
- BezTriple *bezt;
- int i;
-
- for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- return true;
- }
- }
- }
- else {
- BPoint *bp;
- int i;
-
- for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
- if (bp->f1 & SELECT) {
- return true;
- }
- }
- }
- return false;
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt;
+ int i;
+
+ for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ return true;
+ }
+ }
+ }
+ else {
+ BPoint *bp;
+ int i;
+
+ for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
+ if (bp->f1 & SELECT) {
+ return true;
+ }
+ }
+ }
+ return false;
}
int ED_curve_nurb_select_count(View3D *v3d, Nurb *nu)
{
- int sel = 0;
-
- if (nu->type == CU_BEZIER) {
- BezTriple *bezt;
- int i;
-
- for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
- if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
- sel++;
- }
- }
- }
- else {
- BPoint *bp;
- int i;
-
- for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
- if (bp->f1 & SELECT) {
- sel++;
- }
- }
- }
-
- return sel;
+ int sel = 0;
+
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt;
+ int i;
+
+ for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
+ if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) {
+ sel++;
+ }
+ }
+ }
+ else {
+ BPoint *bp;
+ int i;
+
+ for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
+ if (bp->f1 & SELECT) {
+ sel++;
+ }
+ }
+ }
+
+ return sel;
}
bool ED_curve_nurb_select_all(const Nurb *nu)
{
- bool changed = false;
- int i;
- if (nu->bezt) {
- BezTriple *bezt;
- for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
- if (bezt->hide == 0) {
- if (BEZT_ISSEL_ALL(bezt) == false) {
- BEZT_SEL_ALL(bezt);
- changed = true;
- }
- }
- }
- }
- else if (nu->bp) {
- BPoint *bp;
- for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
- if (bp->hide == 0) {
- if ((bp->f1 & SELECT) == 0) {
- bp->f1 |= SELECT;
- changed = true;
- }
- }
- }
- }
- return changed;
+ bool changed = false;
+ int i;
+ if (nu->bezt) {
+ BezTriple *bezt;
+ for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
+ if (bezt->hide == 0) {
+ if (BEZT_ISSEL_ALL(bezt) == false) {
+ BEZT_SEL_ALL(bezt);
+ changed = true;
+ }
+ }
+ }
+ }
+ else if (nu->bp) {
+ BPoint *bp;
+ for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
+ if (bp->hide == 0) {
+ if ((bp->f1 & SELECT) == 0) {
+ bp->f1 |= SELECT;
+ changed = true;
+ }
+ }
+ }
+ }
+ return changed;
}
bool ED_curve_select_all(EditNurb *editnurb)
{
- bool changed = false;
- for (Nurb *nu = editnurb->nurbs.first; nu; nu = nu->next) {
- changed |= ED_curve_nurb_select_all(nu);
- }
- return changed;
+ bool changed = false;
+ for (Nurb *nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ changed |= ED_curve_nurb_select_all(nu);
+ }
+ return changed;
}
bool ED_curve_nurb_deselect_all(const Nurb *nu)
{
- bool changed = false;
- int i;
- if (nu->bezt) {
- BezTriple *bezt;
- for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
- if (BEZT_ISSEL_ANY(bezt)) {
- BEZT_DESEL_ALL(bezt);
- changed = true;
- }
- }
- }
- else if (nu->bp) {
- BPoint *bp;
- for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
- if (bp->f1 & SELECT) {
- bp->f1 &= ~SELECT;
- changed = true;
- }
- }
- }
- return changed;
+ bool changed = false;
+ int i;
+ if (nu->bezt) {
+ BezTriple *bezt;
+ for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
+ if (BEZT_ISSEL_ANY(bezt)) {
+ BEZT_DESEL_ALL(bezt);
+ changed = true;
+ }
+ }
+ }
+ else if (nu->bp) {
+ BPoint *bp;
+ for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
+ if (bp->f1 & SELECT) {
+ bp->f1 &= ~SELECT;
+ changed = true;
+ }
+ }
+ }
+ return changed;
}
int ED_curve_select_count(View3D *v3d, struct EditNurb *editnurb)
{
- int sel = 0;
- Nurb *nu;
+ int sel = 0;
+ Nurb *nu;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- sel += ED_curve_nurb_select_count(v3d, nu);
- }
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ sel += ED_curve_nurb_select_count(v3d, nu);
+ }
- return sel;
+ return sel;
}
bool ED_curve_select_check(View3D *v3d, struct EditNurb *editnurb)
{
- Nurb *nu;
+ Nurb *nu;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- if (ED_curve_nurb_select_check(v3d, nu)) {
- return true;
- }
- }
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
bool ED_curve_deselect_all(EditNurb *editnurb)
{
- bool changed = false;
- for (Nurb *nu = editnurb->nurbs.first; nu; nu = nu->next) {
- changed |= ED_curve_nurb_deselect_all(nu);
- }
- return changed;
+ bool changed = false;
+ for (Nurb *nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ changed |= ED_curve_nurb_deselect_all(nu);
+ }
+ return changed;
}
bool ED_curve_deselect_all_multi_ex(Base **bases, int bases_len)
{
- bool changed_multi = false;
- for (uint base_index = 0; base_index < bases_len; base_index++) {
- Object *obedit = bases[base_index]->object;
- Curve *cu = obedit->data;
- changed_multi |= ED_curve_deselect_all(cu->editnurb);
- DEG_id_tag_update(&cu->id, ID_RECALC_SELECT);
- }
- return changed_multi;
+ bool changed_multi = false;
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Object *obedit = bases[base_index]->object;
+ Curve *cu = obedit->data;
+ changed_multi |= ED_curve_deselect_all(cu->editnurb);
+ DEG_id_tag_update(&cu->id, ID_RECALC_SELECT);
+ }
+ return changed_multi;
}
bool ED_curve_deselect_all_multi(struct bContext *C)
{
- ViewContext vc;
- ED_view3d_viewcontext_init(C, &vc);
- uint bases_len = 0;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(vc.view_layer, vc.v3d, &bases_len);
- bool changed_multi = ED_curve_deselect_all_multi_ex(bases, bases_len);
- MEM_freeN(bases);
- return changed_multi;
+ ViewContext vc;
+ ED_view3d_viewcontext_init(C, &vc);
+ uint bases_len = 0;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
+ vc.view_layer, vc.v3d, &bases_len);
+ bool changed_multi = ED_curve_deselect_all_multi_ex(bases, bases_len);
+ MEM_freeN(bases);
+ return changed_multi;
}
bool ED_curve_select_swap(EditNurb *editnurb, bool hide_handles)
{
- Nurb *nu;
- BPoint *bp;
- BezTriple *bezt;
- int a;
- bool changed = false;
-
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- if (bezt->hide == 0) {
- bezt->f2 ^= SELECT; /* always do the center point */
- if (!hide_handles) {
- bezt->f1 ^= SELECT;
- bezt->f3 ^= SELECT;
- }
- changed = true;
- }
- bezt++;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- if (bp->hide == 0) {
- swap_selection_bpoint(bp);
- changed = true;
- }
- bp++;
- }
- }
- }
- return changed;
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ int a;
+ bool changed = false;
+
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ while (a--) {
+ if (bezt->hide == 0) {
+ bezt->f2 ^= SELECT; /* always do the center point */
+ if (!hide_handles) {
+ bezt->f1 ^= SELECT;
+ bezt->f3 ^= SELECT;
+ }
+ changed = true;
+ }
+ bezt++;
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ if (bp->hide == 0) {
+ swap_selection_bpoint(bp);
+ changed = true;
+ }
+ bp++;
+ }
+ }
+ }
+ return changed;
}
/**
@@ -331,77 +332,80 @@ bool ED_curve_select_swap(EditNurb *editnurb, bool hide_handles)
* \param cont: when true select continuously
* \param selstatus: inverts behavior
*/
-static void select_adjacent_cp(
- ListBase *editnurb, short next,
- const bool cont, const bool selstatus)
+static void select_adjacent_cp(ListBase *editnurb,
+ short next,
+ const bool cont,
+ const bool selstatus)
{
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
- bool lastsel = false;
-
- if (next == 0) {
- return;
- }
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- lastsel = false;
- if (nu->type == CU_BEZIER) {
- a = nu->pntsu;
- bezt = nu->bezt;
- if (next < 0) {
- bezt = &nu->bezt[a - 1];
- }
- while (a--) {
- if (a - abs(next) < 0) {
- break;
- }
- if ((lastsel == false) && (bezt->hide == 0) && ((bezt->f2 & SELECT) || (selstatus == DESELECT))) {
- bezt += next;
- if (!(bezt->f2 & SELECT) || (selstatus == DESELECT)) {
- bool sel = select_beztriple(bezt, selstatus, SELECT, VISIBLE);
- if (sel && !cont) {
- lastsel = true;
- }
- }
- }
- else {
- bezt += next;
- lastsel = false;
- }
- /* move around in zigzag way so that we go through each */
- bezt -= (next - next / abs(next));
- }
- }
- else {
- a = nu->pntsu * nu->pntsv;
- bp = nu->bp;
- if (next < 0) {
- bp = &nu->bp[a - 1];
- }
- while (a--) {
- if (a - abs(next) < 0) {
- break;
- }
- if ((lastsel == false) && (bp->hide == 0) && ((bp->f1 & SELECT) || (selstatus == DESELECT))) {
- bp += next;
- if (!(bp->f1 & SELECT) || (selstatus == DESELECT)) {
- bool sel = select_bpoint(bp, selstatus, SELECT, VISIBLE);
- if (sel && !cont) {
- lastsel = true;
- }
- }
- }
- else {
- bp += next;
- lastsel = false;
- }
- /* move around in zigzag way so that we go through each */
- bp -= (next - next / abs(next));
- }
- }
- }
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+ bool lastsel = false;
+
+ if (next == 0) {
+ return;
+ }
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ lastsel = false;
+ if (nu->type == CU_BEZIER) {
+ a = nu->pntsu;
+ bezt = nu->bezt;
+ if (next < 0) {
+ bezt = &nu->bezt[a - 1];
+ }
+ while (a--) {
+ if (a - abs(next) < 0) {
+ break;
+ }
+ if ((lastsel == false) && (bezt->hide == 0) &&
+ ((bezt->f2 & SELECT) || (selstatus == DESELECT))) {
+ bezt += next;
+ if (!(bezt->f2 & SELECT) || (selstatus == DESELECT)) {
+ bool sel = select_beztriple(bezt, selstatus, SELECT, VISIBLE);
+ if (sel && !cont) {
+ lastsel = true;
+ }
+ }
+ }
+ else {
+ bezt += next;
+ lastsel = false;
+ }
+ /* move around in zigzag way so that we go through each */
+ bezt -= (next - next / abs(next));
+ }
+ }
+ else {
+ a = nu->pntsu * nu->pntsv;
+ bp = nu->bp;
+ if (next < 0) {
+ bp = &nu->bp[a - 1];
+ }
+ while (a--) {
+ if (a - abs(next) < 0) {
+ break;
+ }
+ if ((lastsel == false) && (bp->hide == 0) &&
+ ((bp->f1 & SELECT) || (selstatus == DESELECT))) {
+ bp += next;
+ if (!(bp->f1 & SELECT) || (selstatus == DESELECT)) {
+ bool sel = select_bpoint(bp, selstatus, SELECT, VISIBLE);
+ if (sel && !cont) {
+ lastsel = true;
+ }
+ }
+ }
+ else {
+ bp += next;
+ lastsel = false;
+ }
+ /* move around in zigzag way so that we go through each */
+ bp -= (next - next / abs(next));
+ }
+ }
+ }
}
/**************** select start/end operators **************/
@@ -413,570 +417,579 @@ static void select_adjacent_cp(
*/
static void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap, bool selstatus)
{
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- BPoint *bp;
- BezTriple *bezt;
- Curve *cu;
- int a;
-
- if (obedit == NULL) {
- return;
- }
-
- cu = (Curve *)obedit->data;
- cu->actvert = CU_ACT_NONE;
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- a = nu->pntsu;
-
- /* which point? */
- if (selfirst == LAST) { /* select last */
- bezt = &nu->bezt[a - 1];
- }
- else { /* select first */
- bezt = nu->bezt;
- }
-
- while (a--) {
- bool sel;
- if (doswap) {
- sel = swap_selection_beztriple(bezt);
- }
- else {
- sel = select_beztriple(bezt, selstatus, SELECT, VISIBLE);
- }
-
- if (sel == true) {
- break;
- }
- }
- }
- else {
- a = nu->pntsu * nu->pntsv;
-
- /* which point? */
- if (selfirst == LAST) { /* select last */
- bp = &nu->bp[a - 1];
- }
- else { /* select first */
- bp = nu->bp;
- }
-
- while (a--) {
- if (bp->hide == 0) {
- bool sel;
- if (doswap) {
- sel = swap_selection_bpoint(bp);
- }
- else {
- sel = select_bpoint(bp, selstatus, SELECT, VISIBLE);
- }
-
- if (sel == true) {
- break;
- }
- }
- }
- }
- }
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ Curve *cu;
+ int a;
+
+ if (obedit == NULL) {
+ return;
+ }
+
+ cu = (Curve *)obedit->data;
+ cu->actvert = CU_ACT_NONE;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ a = nu->pntsu;
+
+ /* which point? */
+ if (selfirst == LAST) { /* select last */
+ bezt = &nu->bezt[a - 1];
+ }
+ else { /* select first */
+ bezt = nu->bezt;
+ }
+
+ while (a--) {
+ bool sel;
+ if (doswap) {
+ sel = swap_selection_beztriple(bezt);
+ }
+ else {
+ sel = select_beztriple(bezt, selstatus, SELECT, VISIBLE);
+ }
+
+ if (sel == true) {
+ break;
+ }
+ }
+ }
+ else {
+ a = nu->pntsu * nu->pntsv;
+
+ /* which point? */
+ if (selfirst == LAST) { /* select last */
+ bp = &nu->bp[a - 1];
+ }
+ else { /* select first */
+ bp = nu->bp;
+ }
+
+ while (a--) {
+ if (bp->hide == 0) {
+ bool sel;
+ if (doswap) {
+ sel = swap_selection_bpoint(bp);
+ }
+ else {
+ sel = select_bpoint(bp, selstatus, SELECT, VISIBLE);
+ }
+
+ if (sel == true) {
+ break;
+ }
+ }
+ }
+ }
+ }
}
static int de_select_first_exec(bContext *C, wmOperator *UNUSED(op))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- selectend_nurb(obedit, FIRST, true, DESELECT);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- BKE_curve_nurb_vert_active_validate(obedit->data);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ selectend_nurb(obedit, FIRST, true, DESELECT);
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ BKE_curve_nurb_vert_active_validate(obedit->data);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_de_select_first(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "(De)select First";
- ot->idname = "CURVE_OT_de_select_first";
- ot->description = "(De)select first of visible part of each NURBS";
+ /* identifiers */
+ ot->name = "(De)select First";
+ ot->idname = "CURVE_OT_de_select_first";
+ ot->description = "(De)select first of visible part of each NURBS";
- /* api cfirstbacks */
- ot->exec = de_select_first_exec;
- ot->poll = ED_operator_editcurve;
+ /* api cfirstbacks */
+ ot->exec = de_select_first_exec;
+ ot->poll = ED_operator_editcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int de_select_last_exec(bContext *C, wmOperator *UNUSED(op))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- selectend_nurb(obedit, LAST, true, DESELECT);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- BKE_curve_nurb_vert_active_validate(obedit->data);
- }
-
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ selectend_nurb(obedit, LAST, true, DESELECT);
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ BKE_curve_nurb_vert_active_validate(obedit->data);
+ }
+
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_de_select_last(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "(De)select Last";
- ot->idname = "CURVE_OT_de_select_last";
- ot->description = "(De)select last of visible part of each NURBS";
+ /* identifiers */
+ ot->name = "(De)select Last";
+ ot->idname = "CURVE_OT_de_select_last";
+ ot->description = "(De)select last of visible part of each NURBS";
- /* api clastbacks */
- ot->exec = de_select_last_exec;
- ot->poll = ED_operator_editcurve;
+ /* api clastbacks */
+ ot->exec = de_select_last_exec;
+ ot->poll = ED_operator_editcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int de_select_all_exec(bContext *C, wmOperator *op)
{
- int action = RNA_enum_get(op->ptr, "action");
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- if (action == SEL_TOGGLE) {
- action = SEL_SELECT;
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
-
- if (ED_curve_select_check(v3d, cu->editnurb)) {
- action = SEL_DESELECT;
- break;
- }
- }
- }
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
- bool changed = false;
-
- switch (action) {
- case SEL_SELECT:
- changed = ED_curve_select_all(cu->editnurb);
- break;
- case SEL_DESELECT:
- changed = ED_curve_deselect_all(cu->editnurb);
- break;
- case SEL_INVERT:
- changed = ED_curve_select_swap(cu->editnurb, (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0);
- break;
- }
-
- if (changed) {
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- BKE_curve_nurb_vert_active_validate(cu);
- }
- }
-
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ int action = RNA_enum_get(op->ptr, "action");
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ if (action == SEL_TOGGLE) {
+ action = SEL_SELECT;
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+
+ if (ED_curve_select_check(v3d, cu->editnurb)) {
+ action = SEL_DESELECT;
+ break;
+ }
+ }
+ }
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+ bool changed = false;
+
+ switch (action) {
+ case SEL_SELECT:
+ changed = ED_curve_select_all(cu->editnurb);
+ break;
+ case SEL_DESELECT:
+ changed = ED_curve_deselect_all(cu->editnurb);
+ break;
+ case SEL_INVERT:
+ changed = ED_curve_select_swap(
+ cu->editnurb, (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0);
+ break;
+ }
+
+ if (changed) {
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ BKE_curve_nurb_vert_active_validate(cu);
+ }
+ }
+
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_select_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "(De)select All";
- ot->idname = "CURVE_OT_select_all";
- ot->description = "(De)select all control points";
+ /* identifiers */
+ ot->name = "(De)select All";
+ ot->idname = "CURVE_OT_select_all";
+ ot->description = "(De)select all control points";
- /* api callbacks */
- ot->exec = de_select_all_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = de_select_all_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_select_all(ot);
+ /* properties */
+ WM_operator_properties_select_all(ot);
}
-
-
/***************** select linked operator ******************/
static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
- EditNurb *editnurb = cu->editnurb;
- ListBase *nurbs = &editnurb->nurbs;
- Nurb *nu;
- bool changed = false;
-
- for (nu = nurbs->first; nu; nu = nu->next) {
- if (ED_curve_nurb_select_check(v3d, nu)) {
- changed |= ED_curve_nurb_select_all(nu);
- }
- }
-
- if (changed) {
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- }
- }
- MEM_freeN(objects);
-
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+ EditNurb *editnurb = cu->editnurb;
+ ListBase *nurbs = &editnurb->nurbs;
+ Nurb *nu;
+ bool changed = false;
+
+ for (nu = nurbs->first; nu; nu = nu->next) {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+ changed |= ED_curve_nurb_select_all(nu);
+ }
+ }
+
+ if (changed) {
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ }
+ }
+ MEM_freeN(objects);
+
+ return OPERATOR_FINISHED;
}
static int select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- return select_linked_exec(C, op);
+ return select_linked_exec(C, op);
}
void CURVE_OT_select_linked(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Linked All";
- ot->idname = "CURVE_OT_select_linked";
- ot->description = "Select all control points linked to the current selection";
+ /* identifiers */
+ ot->name = "Select Linked All";
+ ot->idname = "CURVE_OT_select_linked";
+ ot->description = "Select all control points linked to the current selection";
- /* api callbacks */
- ot->exec = select_linked_exec;
- ot->invoke = select_linked_invoke;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = select_linked_exec;
+ ot->invoke = select_linked_invoke;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
+ /* properties */
}
-
/***************** select linked pick operator ******************/
static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewContext vc;
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
- const bool select = !RNA_boolean_get(op->ptr, "deselect");
- Base *basact = NULL;
-
- view3d_operator_needs_opengl(C);
- ED_view3d_viewcontext_init(C, &vc);
- copy_v2_v2_int(vc.mval, event->mval);
-
- if (!ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, NULL, &basact)) {
- return OPERATOR_CANCELLED;
- }
-
- if (bezt) {
- a = nu->pntsu;
- bezt = nu->bezt;
- while (a--) {
- select_beztriple(bezt, select, SELECT, VISIBLE);
- bezt++;
- }
- }
- else if (bp) {
- a = nu->pntsu * nu->pntsv;
- bp = nu->bp;
- while (a--) {
- select_bpoint(bp, select, SELECT, VISIBLE);
- bp++;
- }
- }
-
- Object *obedit = basact->object;
-
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
-
- if (!select) {
- BKE_curve_nurb_vert_active_validate(obedit->data);
- }
-
- return OPERATOR_FINISHED;
+ ViewContext vc;
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+ const bool select = !RNA_boolean_get(op->ptr, "deselect");
+ Base *basact = NULL;
+
+ view3d_operator_needs_opengl(C);
+ ED_view3d_viewcontext_init(C, &vc);
+ copy_v2_v2_int(vc.mval, event->mval);
+
+ if (!ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, NULL, &basact)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (bezt) {
+ a = nu->pntsu;
+ bezt = nu->bezt;
+ while (a--) {
+ select_beztriple(bezt, select, SELECT, VISIBLE);
+ bezt++;
+ }
+ }
+ else if (bp) {
+ a = nu->pntsu * nu->pntsv;
+ bp = nu->bp;
+ while (a--) {
+ select_bpoint(bp, select, SELECT, VISIBLE);
+ bp++;
+ }
+ }
+
+ Object *obedit = basact->object;
+
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
+ if (!select) {
+ BKE_curve_nurb_vert_active_validate(obedit->data);
+ }
+
+ return OPERATOR_FINISHED;
}
void CURVE_OT_select_linked_pick(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Linked";
- ot->idname = "CURVE_OT_select_linked_pick";
- ot->description = "Select all control points linked to already selected ones";
-
- /* api callbacks */
- ot->invoke = select_linked_pick_invoke;
- ot->poll = ED_operator_editsurfcurve_region_view3d;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect linked control points rather than selecting them");
+ /* identifiers */
+ ot->name = "Select Linked";
+ ot->idname = "CURVE_OT_select_linked_pick";
+ ot->description = "Select all control points linked to already selected ones";
+
+ /* api callbacks */
+ ot->invoke = select_linked_pick_invoke;
+ ot->poll = ED_operator_editsurfcurve_region_view3d;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna,
+ "deselect",
+ 0,
+ "Deselect",
+ "Deselect linked control points rather than selecting them");
}
/***************** select row operator **********************/
static int select_row_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- ListBase *editnurb = object_editcurve_get(obedit);
- static BPoint *last = NULL;
- static int direction = 0;
- Nurb *nu = NULL;
- BPoint *bp = NULL;
- int u = 0, v = 0, a, b;
-
- if (!BKE_curve_nurb_vert_active_get(cu, &nu, (void *)&bp)) {
- return OPERATOR_CANCELLED;
- }
-
- if (last == bp) {
- direction = 1 - direction;
- BKE_nurbList_flag_set(editnurb, 0);
- }
- last = bp;
-
- u = cu->actvert % nu->pntsu;
- v = cu->actvert / nu->pntsu;
- bp = nu->bp;
- for (a = 0; a < nu->pntsv; a++) {
- for (b = 0; b < nu->pntsu; b++, bp++) {
- if (direction) {
- if (a == v) {
- select_bpoint(bp, SELECT, SELECT, VISIBLE);
- }
- }
- else {
- if (b == u) {
- select_bpoint(bp, SELECT, SELECT, VISIBLE);
- }
- }
- }
- }
-
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
-
- return OPERATOR_FINISHED;
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ ListBase *editnurb = object_editcurve_get(obedit);
+ static BPoint *last = NULL;
+ static int direction = 0;
+ Nurb *nu = NULL;
+ BPoint *bp = NULL;
+ int u = 0, v = 0, a, b;
+
+ if (!BKE_curve_nurb_vert_active_get(cu, &nu, (void *)&bp)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (last == bp) {
+ direction = 1 - direction;
+ BKE_nurbList_flag_set(editnurb, 0);
+ }
+ last = bp;
+
+ u = cu->actvert % nu->pntsu;
+ v = cu->actvert / nu->pntsu;
+ bp = nu->bp;
+ for (a = 0; a < nu->pntsv; a++) {
+ for (b = 0; b < nu->pntsu; b++, bp++) {
+ if (direction) {
+ if (a == v) {
+ select_bpoint(bp, SELECT, SELECT, VISIBLE);
+ }
+ }
+ else {
+ if (b == u) {
+ select_bpoint(bp, SELECT, SELECT, VISIBLE);
+ }
+ }
+ }
+ }
+
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
+ return OPERATOR_FINISHED;
}
void CURVE_OT_select_row(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Control Point Row";
- ot->idname = "CURVE_OT_select_row";
- ot->description = "Select a row of control points including active one";
+ /* identifiers */
+ ot->name = "Select Control Point Row";
+ ot->idname = "CURVE_OT_select_row";
+ ot->description = "Select a row of control points including active one";
- /* api callbacks */
- ot->exec = select_row_exec;
- ot->poll = ED_operator_editsurf;
+ /* api callbacks */
+ ot->exec = select_row_exec;
+ ot->poll = ED_operator_editsurf;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/***************** select next operator **********************/
static int select_next_exec(bContext *C, wmOperator *UNUSED(op))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- ListBase *editnurb = object_editcurve_get(obedit);
- select_adjacent_cp(editnurb, 1, 0, SELECT);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
+ select_adjacent_cp(editnurb, 1, 0, SELECT);
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_select_next(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Next";
- ot->idname = "CURVE_OT_select_next";
- ot->description = "Select control points following already selected ones along the curves";
+ /* identifiers */
+ ot->name = "Select Next";
+ ot->idname = "CURVE_OT_select_next";
+ ot->description = "Select control points following already selected ones along the curves";
- /* api callbacks */
- ot->exec = select_next_exec;
- ot->poll = ED_operator_editcurve;
+ /* api callbacks */
+ ot->exec = select_next_exec;
+ ot->poll = ED_operator_editcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/***************** select previous operator **********************/
static int select_previous_exec(bContext *C, wmOperator *UNUSED(op))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- ListBase *editnurb = object_editcurve_get(obedit);
- select_adjacent_cp(editnurb, -1, 0, SELECT);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
+ select_adjacent_cp(editnurb, -1, 0, SELECT);
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_select_previous(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Previous";
- ot->idname = "CURVE_OT_select_previous";
- ot->description = "Select control points preceding already selected ones along the curves";
+ /* identifiers */
+ ot->name = "Select Previous";
+ ot->idname = "CURVE_OT_select_previous";
+ ot->description = "Select control points preceding already selected ones along the curves";
- /* api callbacks */
- ot->exec = select_previous_exec;
- ot->poll = ED_operator_editcurve;
+ /* api callbacks */
+ ot->exec = select_previous_exec;
+ ot->poll = ED_operator_editcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/***************** select more operator **********************/
static void curve_select_more(Object *obedit)
{
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- BPoint *bp, *tempbp;
- int a;
- short sel = 0;
-
- /* note that NURBS surface is a special case because we mimic */
- /* the behavior of "select more" of mesh tools. */
- /* The algorithm is designed to work in planar cases so it */
- /* may not be optimal always (example: end of NURBS sphere) */
- if (obedit->type == OB_SURF) {
- for (nu = editnurb->first; nu; nu = nu->next) {
- BLI_bitmap *selbpoints;
- a = nu->pntsu * nu->pntsv;
- bp = nu->bp;
- selbpoints = BLI_BITMAP_NEW(a, "selectlist");
- while (a > 0) {
- if ((!BLI_BITMAP_TEST(selbpoints, a)) && (bp->hide == 0) && (bp->f1 & SELECT)) {
- /* upper control point */
- if (a % nu->pntsu != 0) {
- tempbp = bp - 1;
- if (!(tempbp->f1 & SELECT)) {
- select_bpoint(tempbp, SELECT, SELECT, VISIBLE);
- }
- }
-
- /* left control point. select only if it is not selected already */
- if (a - nu->pntsu > 0) {
- sel = 0;
- tempbp = bp + nu->pntsu;
- if (!(tempbp->f1 & SELECT)) {
- sel = select_bpoint(tempbp, SELECT, SELECT, VISIBLE);
- }
- /* make sure selected bpoint is discarded */
- if (sel == 1) {
- BLI_BITMAP_ENABLE(selbpoints, a - nu->pntsu);
- }
- }
-
- /* right control point */
- if (a + nu->pntsu < nu->pntsu * nu->pntsv) {
- tempbp = bp - nu->pntsu;
- if (!(tempbp->f1 & SELECT)) {
- select_bpoint(tempbp, SELECT, SELECT, VISIBLE);
- }
- }
-
- /* lower control point. skip next bp in case selection was made */
- if (a % nu->pntsu != 1) {
- sel = 0;
- tempbp = bp + 1;
- if (!(tempbp->f1 & SELECT)) {
- sel = select_bpoint(tempbp, SELECT, SELECT, VISIBLE);
- }
- if (sel) {
- bp++;
- a--;
- }
- }
- }
-
- bp++;
- a--;
- }
-
- MEM_freeN(selbpoints);
- }
- }
- else {
- select_adjacent_cp(editnurb, 1, 0, SELECT);
- select_adjacent_cp(editnurb, -1, 0, SELECT);
- }
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ BPoint *bp, *tempbp;
+ int a;
+ short sel = 0;
+
+ /* note that NURBS surface is a special case because we mimic */
+ /* the behavior of "select more" of mesh tools. */
+ /* The algorithm is designed to work in planar cases so it */
+ /* may not be optimal always (example: end of NURBS sphere) */
+ if (obedit->type == OB_SURF) {
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ BLI_bitmap *selbpoints;
+ a = nu->pntsu * nu->pntsv;
+ bp = nu->bp;
+ selbpoints = BLI_BITMAP_NEW(a, "selectlist");
+ while (a > 0) {
+ if ((!BLI_BITMAP_TEST(selbpoints, a)) && (bp->hide == 0) && (bp->f1 & SELECT)) {
+ /* upper control point */
+ if (a % nu->pntsu != 0) {
+ tempbp = bp - 1;
+ if (!(tempbp->f1 & SELECT)) {
+ select_bpoint(tempbp, SELECT, SELECT, VISIBLE);
+ }
+ }
+
+ /* left control point. select only if it is not selected already */
+ if (a - nu->pntsu > 0) {
+ sel = 0;
+ tempbp = bp + nu->pntsu;
+ if (!(tempbp->f1 & SELECT)) {
+ sel = select_bpoint(tempbp, SELECT, SELECT, VISIBLE);
+ }
+ /* make sure selected bpoint is discarded */
+ if (sel == 1) {
+ BLI_BITMAP_ENABLE(selbpoints, a - nu->pntsu);
+ }
+ }
+
+ /* right control point */
+ if (a + nu->pntsu < nu->pntsu * nu->pntsv) {
+ tempbp = bp - nu->pntsu;
+ if (!(tempbp->f1 & SELECT)) {
+ select_bpoint(tempbp, SELECT, SELECT, VISIBLE);
+ }
+ }
+
+ /* lower control point. skip next bp in case selection was made */
+ if (a % nu->pntsu != 1) {
+ sel = 0;
+ tempbp = bp + 1;
+ if (!(tempbp->f1 & SELECT)) {
+ sel = select_bpoint(tempbp, SELECT, SELECT, VISIBLE);
+ }
+ if (sel) {
+ bp++;
+ a--;
+ }
+ }
+ }
+
+ bp++;
+ a--;
+ }
+
+ MEM_freeN(selbpoints);
+ }
+ }
+ else {
+ select_adjacent_cp(editnurb, 1, 0, SELECT);
+ select_adjacent_cp(editnurb, -1, 0, SELECT);
+ }
}
static int curve_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- curve_select_more(obedit);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ curve_select_more(obedit);
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_select_more(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select More";
- ot->idname = "CURVE_OT_select_more";
- ot->description = "Select control points directly linked to already selected ones";
+ /* identifiers */
+ ot->name = "Select More";
+ ot->idname = "CURVE_OT_select_more";
+ ot->description = "Select control points directly linked to already selected ones";
- /* api callbacks */
- ot->exec = curve_select_more_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = curve_select_more_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/******************** select less operator *****************/
@@ -984,437 +997,439 @@ void CURVE_OT_select_more(wmOperatorType *ot)
/* basic method: deselect if control point doesn't have all neighbors selected */
static void curve_select_less(Object *obedit)
{
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- BPoint *bp;
- BezTriple *bezt;
- int a;
- int sel = 0;
- bool lastsel = false;
-
- if (obedit->type == OB_SURF) {
- for (nu = editnurb->first; nu; nu = nu->next) {
- BLI_bitmap *selbpoints;
- a = nu->pntsu * nu->pntsv;
- bp = nu->bp;
- selbpoints = BLI_BITMAP_NEW(a, "selectlist");
- while (a--) {
- if ((bp->hide == 0) && (bp->f1 & SELECT)) {
- sel = 0;
-
- /* check if neighbors have been selected */
- /* edges of surface are an exception */
- if ((a + 1) % nu->pntsu == 0) {
- sel++;
- }
- else {
- bp--;
- if (BLI_BITMAP_TEST(selbpoints, a + 1) || ((bp->hide == 0) && (bp->f1 & SELECT))) {
- sel++;
- }
- bp++;
- }
-
- if ((a + 1) % nu->pntsu == 1) {
- sel++;
- }
- else {
- bp++;
- if ((bp->hide == 0) && (bp->f1 & SELECT)) {
- sel++;
- }
- bp--;
- }
-
- if (a + 1 > nu->pntsu * nu->pntsv - nu->pntsu) {
- sel++;
- }
- else {
- bp -= nu->pntsu;
- if (BLI_BITMAP_TEST(selbpoints, a + nu->pntsu) || ((bp->hide == 0) && (bp->f1 & SELECT))) {
- sel++;
- }
- bp += nu->pntsu;
- }
-
- if (a < nu->pntsu) {
- sel++;
- }
- else {
- bp += nu->pntsu;
- if ((bp->hide == 0) && (bp->f1 & SELECT)) {
- sel++;
- }
- bp -= nu->pntsu;
- }
-
- if (sel != 4) {
- select_bpoint(bp, DESELECT, SELECT, VISIBLE);
- BLI_BITMAP_ENABLE(selbpoints, a);
- }
- }
- else {
- lastsel = false;
- }
-
- bp++;
- }
-
- MEM_freeN(selbpoints);
- }
- }
- else {
- for (nu = editnurb->first; nu; nu = nu->next) {
- lastsel = false;
- /* check what type of curve/nurb it is */
- if (nu->type == CU_BEZIER) {
- a = nu->pntsu;
- bezt = nu->bezt;
- while (a--) {
- if ((bezt->hide == 0) && (bezt->f2 & SELECT)) {
- sel = (lastsel == 1);
-
- /* check if neighbors have been selected */
- /* first and last are exceptions */
- if (a == nu->pntsu - 1) {
- sel++;
- }
- else {
- bezt--;
- if ((bezt->hide == 0) && (bezt->f2 & SELECT)) {
- sel++;
- }
- bezt++;
- }
-
- if (a == 0) {
- sel++;
- }
- else {
- bezt++;
- if ((bezt->hide == 0) && (bezt->f2 & SELECT)) {
- sel++;
- }
- bezt--;
- }
-
- if (sel != 2) {
- select_beztriple(bezt, DESELECT, SELECT, VISIBLE);
- lastsel = true;
- }
- else {
- lastsel = false;
- }
- }
- else {
- lastsel = false;
- }
-
- bezt++;
- }
- }
- else {
- a = nu->pntsu * nu->pntsv;
- bp = nu->bp;
- while (a--) {
- if ((lastsel == false) && (bp->hide == 0) && (bp->f1 & SELECT)) {
- sel = 0;
-
- /* first and last are exceptions */
- if (a == nu->pntsu * nu->pntsv - 1) {
- sel++;
- }
- else {
- bp--;
- if ((bp->hide == 0) && (bp->f1 & SELECT)) {
- sel++;
- }
- bp++;
- }
-
- if (a == 0) {
- sel++;
- }
- else {
- bp++;
- if ((bp->hide == 0) && (bp->f1 & SELECT)) {
- sel++;
- }
- bp--;
- }
-
- if (sel != 2) {
- select_bpoint(bp, DESELECT, SELECT, VISIBLE);
- lastsel = true;
- }
- else {
- lastsel = false;
- }
- }
- else {
- lastsel = false;
- }
-
- bp++;
- }
- }
- }
- }
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ int a;
+ int sel = 0;
+ bool lastsel = false;
+
+ if (obedit->type == OB_SURF) {
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ BLI_bitmap *selbpoints;
+ a = nu->pntsu * nu->pntsv;
+ bp = nu->bp;
+ selbpoints = BLI_BITMAP_NEW(a, "selectlist");
+ while (a--) {
+ if ((bp->hide == 0) && (bp->f1 & SELECT)) {
+ sel = 0;
+
+ /* check if neighbors have been selected */
+ /* edges of surface are an exception */
+ if ((a + 1) % nu->pntsu == 0) {
+ sel++;
+ }
+ else {
+ bp--;
+ if (BLI_BITMAP_TEST(selbpoints, a + 1) || ((bp->hide == 0) && (bp->f1 & SELECT))) {
+ sel++;
+ }
+ bp++;
+ }
+
+ if ((a + 1) % nu->pntsu == 1) {
+ sel++;
+ }
+ else {
+ bp++;
+ if ((bp->hide == 0) && (bp->f1 & SELECT)) {
+ sel++;
+ }
+ bp--;
+ }
+
+ if (a + 1 > nu->pntsu * nu->pntsv - nu->pntsu) {
+ sel++;
+ }
+ else {
+ bp -= nu->pntsu;
+ if (BLI_BITMAP_TEST(selbpoints, a + nu->pntsu) ||
+ ((bp->hide == 0) && (bp->f1 & SELECT))) {
+ sel++;
+ }
+ bp += nu->pntsu;
+ }
+
+ if (a < nu->pntsu) {
+ sel++;
+ }
+ else {
+ bp += nu->pntsu;
+ if ((bp->hide == 0) && (bp->f1 & SELECT)) {
+ sel++;
+ }
+ bp -= nu->pntsu;
+ }
+
+ if (sel != 4) {
+ select_bpoint(bp, DESELECT, SELECT, VISIBLE);
+ BLI_BITMAP_ENABLE(selbpoints, a);
+ }
+ }
+ else {
+ lastsel = false;
+ }
+
+ bp++;
+ }
+
+ MEM_freeN(selbpoints);
+ }
+ }
+ else {
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ lastsel = false;
+ /* check what type of curve/nurb it is */
+ if (nu->type == CU_BEZIER) {
+ a = nu->pntsu;
+ bezt = nu->bezt;
+ while (a--) {
+ if ((bezt->hide == 0) && (bezt->f2 & SELECT)) {
+ sel = (lastsel == 1);
+
+ /* check if neighbors have been selected */
+ /* first and last are exceptions */
+ if (a == nu->pntsu - 1) {
+ sel++;
+ }
+ else {
+ bezt--;
+ if ((bezt->hide == 0) && (bezt->f2 & SELECT)) {
+ sel++;
+ }
+ bezt++;
+ }
+
+ if (a == 0) {
+ sel++;
+ }
+ else {
+ bezt++;
+ if ((bezt->hide == 0) && (bezt->f2 & SELECT)) {
+ sel++;
+ }
+ bezt--;
+ }
+
+ if (sel != 2) {
+ select_beztriple(bezt, DESELECT, SELECT, VISIBLE);
+ lastsel = true;
+ }
+ else {
+ lastsel = false;
+ }
+ }
+ else {
+ lastsel = false;
+ }
+
+ bezt++;
+ }
+ }
+ else {
+ a = nu->pntsu * nu->pntsv;
+ bp = nu->bp;
+ while (a--) {
+ if ((lastsel == false) && (bp->hide == 0) && (bp->f1 & SELECT)) {
+ sel = 0;
+
+ /* first and last are exceptions */
+ if (a == nu->pntsu * nu->pntsv - 1) {
+ sel++;
+ }
+ else {
+ bp--;
+ if ((bp->hide == 0) && (bp->f1 & SELECT)) {
+ sel++;
+ }
+ bp++;
+ }
+
+ if (a == 0) {
+ sel++;
+ }
+ else {
+ bp++;
+ if ((bp->hide == 0) && (bp->f1 & SELECT)) {
+ sel++;
+ }
+ bp--;
+ }
+
+ if (sel != 2) {
+ select_bpoint(bp, DESELECT, SELECT, VISIBLE);
+ lastsel = true;
+ }
+ else {
+ lastsel = false;
+ }
+ }
+ else {
+ lastsel = false;
+ }
+
+ bp++;
+ }
+ }
+ }
+ }
}
static int curve_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- curve_select_less(obedit);
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- }
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ curve_select_less(obedit);
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ }
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_select_less(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Less";
- ot->idname = "CURVE_OT_select_less";
- ot->description = "Reduce current selection by deselecting boundary elements";
+ /* identifiers */
+ ot->name = "Select Less";
+ ot->idname = "CURVE_OT_select_less";
+ ot->description = "Reduce current selection by deselecting boundary elements";
- /* api callbacks */
- ot->exec = curve_select_less_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = curve_select_less_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/********************** select random *********************/
static void curve_select_random(ListBase *editnurb, float randfac, int seed, bool select)
{
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
-
- RNG *rng = BLI_rng_new_srandom(seed);
-
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- if (!bezt->hide) {
- if (BLI_rng_get_float(rng) < randfac) {
- select_beztriple(bezt, select, SELECT, VISIBLE);
- }
- }
- bezt++;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
-
- while (a--) {
- if (!bp->hide) {
- if (BLI_rng_get_float(rng) < randfac) {
- select_bpoint(bp, select, SELECT, VISIBLE);
- }
- }
- bp++;
- }
- }
- }
-
- BLI_rng_free(rng);
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+
+ RNG *rng = BLI_rng_new_srandom(seed);
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ while (a--) {
+ if (!bezt->hide) {
+ if (BLI_rng_get_float(rng) < randfac) {
+ select_beztriple(bezt, select, SELECT, VISIBLE);
+ }
+ }
+ bezt++;
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+
+ while (a--) {
+ if (!bp->hide) {
+ if (BLI_rng_get_float(rng) < randfac) {
+ select_bpoint(bp, select, SELECT, VISIBLE);
+ }
+ }
+ bp++;
+ }
+ }
+ }
+
+ BLI_rng_free(rng);
}
static int curve_select_random_exec(bContext *C, wmOperator *op)
{
- const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
- const int seed = WM_operator_properties_select_random_seed_increment_get(op);
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- ListBase *editnurb = object_editcurve_get(obedit);
- int seed_iter = seed;
-
- /* This gives a consistent result regardless of object order. */
- if (ob_index) {
- seed_iter += BLI_ghashutil_strhash_p(obedit->id.name);
- }
-
- curve_select_random(editnurb, randfac, seed_iter, select);
- BKE_curve_nurb_vert_active_validate(obedit->data);
-
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- }
-
- MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
+ const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ const int seed = WM_operator_properties_select_random_seed_increment_get(op);
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
+ int seed_iter = seed;
+
+ /* This gives a consistent result regardless of object order. */
+ if (ob_index) {
+ seed_iter += BLI_ghashutil_strhash_p(obedit->id.name);
+ }
+
+ curve_select_random(editnurb, randfac, seed_iter, select);
+ BKE_curve_nurb_vert_active_validate(obedit->data);
+
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ }
+
+ MEM_freeN(objects);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_select_random(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Random";
- ot->idname = "CURVE_OT_select_random";
- ot->description = "Randomly select some control points";
+ /* identifiers */
+ ot->name = "Select Random";
+ ot->idname = "CURVE_OT_select_random";
+ ot->description = "Randomly select some control points";
- /* api callbacks */
- ot->exec = curve_select_random_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = curve_select_random_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_select_random(ot);
+ /* properties */
+ WM_operator_properties_select_random(ot);
}
/********************* every nth number of point *******************/
static void select_nth_bezt(Nurb *nu, BezTriple *bezt, const struct CheckerIntervalParams *params)
{
- int a, start;
+ int a, start;
- start = bezt - nu->bezt;
- a = nu->pntsu;
- bezt = &nu->bezt[a - 1];
+ start = bezt - nu->bezt;
+ a = nu->pntsu;
+ bezt = &nu->bezt[a - 1];
- while (a--) {
- const int depth = abs(start - a);
- if (WM_operator_properties_checker_interval_test(params, depth)) {
- select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
- }
+ while (a--) {
+ const int depth = abs(start - a);
+ if (WM_operator_properties_checker_interval_test(params, depth)) {
+ select_beztriple(bezt, DESELECT, SELECT, HIDDEN);
+ }
- bezt--;
- }
+ bezt--;
+ }
}
static void select_nth_bp(Nurb *nu, BPoint *bp, const struct CheckerIntervalParams *params)
{
- int a, startrow, startpnt;
- int row, pnt;
-
- startrow = (bp - nu->bp) / nu->pntsu;
- startpnt = (bp - nu->bp) % nu->pntsu;
-
- a = nu->pntsu * nu->pntsv;
- bp = &nu->bp[a - 1];
- row = nu->pntsv - 1;
- pnt = nu->pntsu - 1;
-
- while (a--) {
- const int depth = abs(pnt - startpnt) + abs(row - startrow);
- if (WM_operator_properties_checker_interval_test(params, depth)) {
- select_bpoint(bp, DESELECT, SELECT, HIDDEN);
- }
-
- pnt--;
- if (pnt < 0) {
- pnt = nu->pntsu - 1;
- row--;
- }
-
- bp--;
- }
+ int a, startrow, startpnt;
+ int row, pnt;
+
+ startrow = (bp - nu->bp) / nu->pntsu;
+ startpnt = (bp - nu->bp) % nu->pntsu;
+
+ a = nu->pntsu * nu->pntsv;
+ bp = &nu->bp[a - 1];
+ row = nu->pntsv - 1;
+ pnt = nu->pntsu - 1;
+
+ while (a--) {
+ const int depth = abs(pnt - startpnt) + abs(row - startrow);
+ if (WM_operator_properties_checker_interval_test(params, depth)) {
+ select_bpoint(bp, DESELECT, SELECT, HIDDEN);
+ }
+
+ pnt--;
+ if (pnt < 0) {
+ pnt = nu->pntsu - 1;
+ row--;
+ }
+
+ bp--;
+ }
}
static bool ed_curve_select_nth(Curve *cu, const struct CheckerIntervalParams *params)
{
- Nurb *nu = NULL;
- void *vert = NULL;
+ Nurb *nu = NULL;
+ void *vert = NULL;
- if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) {
- return false;
- }
+ if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) {
+ return false;
+ }
- if (nu->bezt) {
- select_nth_bezt(nu, vert, params);
- }
- else {
- select_nth_bp(nu, vert, params);
- }
+ if (nu->bezt) {
+ select_nth_bezt(nu, vert, params);
+ }
+ else {
+ select_nth_bp(nu, vert, params);
+ }
- return true;
+ return true;
}
static int select_nth_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *obact = CTX_data_edit_object(C);
- View3D *v3d = CTX_wm_view3d(C);
- bool changed = false;
-
- struct CheckerIntervalParams op_params;
- WM_operator_properties_checker_interval_from_op(op, &op_params);
-
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
-
- if (!ED_curve_select_check(v3d, cu->editnurb)) {
- continue;
- }
-
- if (ed_curve_select_nth(obedit->data, &op_params) == true) {
- changed = true;
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- }
- }
- MEM_freeN(objects);
-
- if (!changed) {
- if (obact->type == OB_SURF) {
- BKE_report(op->reports, RPT_ERROR,
- (objects_len == 1 ?
- "Surface has no active point" :
- "Surfaces have no active point"));
- }
- else {
- BKE_report(op->reports, RPT_ERROR,
- (objects_len == 1 ?
- "Curve has no active point" :
- "Curves have no active point"));
- }
- return OPERATOR_CANCELLED;
- }
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *obact = CTX_data_edit_object(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ bool changed = false;
+
+ struct CheckerIntervalParams op_params;
+ WM_operator_properties_checker_interval_from_op(op, &op_params);
+
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+
+ if (!ED_curve_select_check(v3d, cu->editnurb)) {
+ continue;
+ }
+
+ if (ed_curve_select_nth(obedit->data, &op_params) == true) {
+ changed = true;
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ }
+ }
+ MEM_freeN(objects);
+
+ if (!changed) {
+ if (obact->type == OB_SURF) {
+ BKE_report(
+ op->reports,
+ RPT_ERROR,
+ (objects_len == 1 ? "Surface has no active point" : "Surfaces have no active point"));
+ }
+ else {
+ BKE_report(op->reports,
+ RPT_ERROR,
+ (objects_len == 1 ? "Curve has no active point" : "Curves have no active point"));
+ }
+ return OPERATOR_CANCELLED;
+ }
+ return OPERATOR_FINISHED;
}
void CURVE_OT_select_nth(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Checker Deselect";
- ot->description = "Deselect every other vertex";
- ot->idname = "CURVE_OT_select_nth";
+ /* identifiers */
+ ot->name = "Checker Deselect";
+ ot->description = "Deselect every other vertex";
+ ot->idname = "CURVE_OT_select_nth";
- /* api callbacks */
- ot->exec = select_nth_exec;
- ot->poll = ED_operator_editsurfcurve;
+ /* api callbacks */
+ ot->exec = select_nth_exec;
+ ot->poll = ED_operator_editsurfcurve;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- WM_operator_properties_checker_interval(ot, false);
+ WM_operator_properties_checker_interval(ot, false);
}
-
/* -------------------------------------------------------------------- */
/* Select Similar */
@@ -1422,373 +1437,365 @@ void CURVE_OT_select_nth(wmOperatorType *ot)
* \{ */
static const EnumPropertyItem curve_prop_similar_compare_types[] = {
- {SIM_CMP_EQ, "EQUAL", 0, "Equal", ""},
- {SIM_CMP_GT, "GREATER", 0, "Greater", ""},
- {SIM_CMP_LT, "LESS", 0, "Less", ""},
+ {SIM_CMP_EQ, "EQUAL", 0, "Equal", ""},
+ {SIM_CMP_GT, "GREATER", 0, "Greater", ""},
+ {SIM_CMP_LT, "LESS", 0, "Less", ""},
- {0, NULL, 0, NULL, NULL},
+ {0, NULL, 0, NULL, NULL},
};
enum {
- SIMCURHAND_TYPE = 0,
- SIMCURHAND_RADIUS,
- SIMCURHAND_WEIGHT,
- SIMCURHAND_DIRECTION,
+ SIMCURHAND_TYPE = 0,
+ SIMCURHAND_RADIUS,
+ SIMCURHAND_WEIGHT,
+ SIMCURHAND_DIRECTION,
};
static const EnumPropertyItem curve_prop_similar_types[] = {
- {SIMCURHAND_TYPE, "TYPE", 0, "Type", ""},
- {SIMCURHAND_RADIUS, "RADIUS", 0, "Radius", ""},
- {SIMCURHAND_WEIGHT, "WEIGHT", 0, "Weight", ""},
- {SIMCURHAND_DIRECTION, "DIRECTION", 0, "Direction", ""},
- {0, NULL, 0, NULL, NULL},
+ {SIMCURHAND_TYPE, "TYPE", 0, "Type", ""},
+ {SIMCURHAND_RADIUS, "RADIUS", 0, "Radius", ""},
+ {SIMCURHAND_WEIGHT, "WEIGHT", 0, "Weight", ""},
+ {SIMCURHAND_DIRECTION, "DIRECTION", 0, "Direction", ""},
+ {0, NULL, 0, NULL, NULL},
};
-static void nurb_bezt_direction_worldspace_get(Object *ob, Nurb *nu, BezTriple *bezt, float r_dir[3])
+static void nurb_bezt_direction_worldspace_get(Object *ob,
+ Nurb *nu,
+ BezTriple *bezt,
+ float r_dir[3])
{
- float rsmat[3][3];
- BKE_nurb_bezt_calc_normal(nu, bezt, r_dir);
- copy_m3_m4(rsmat, ob->obmat);
- mul_m3_v3(rsmat, r_dir);
- normalize_v3(r_dir);
+ float rsmat[3][3];
+ BKE_nurb_bezt_calc_normal(nu, bezt, r_dir);
+ copy_m3_m4(rsmat, ob->obmat);
+ mul_m3_v3(rsmat, r_dir);
+ normalize_v3(r_dir);
}
static void nurb_bpoint_direction_worldspace_get(Object *ob, Nurb *nu, BPoint *bp, float r_dir[3])
{
- float rsmat[3][3];
- BKE_nurb_bpoint_calc_normal(nu, bp, r_dir);
- copy_m3_m4(rsmat, ob->obmat);
- mul_m3_v3(rsmat, r_dir);
- normalize_v3(r_dir);
+ float rsmat[3][3];
+ BKE_nurb_bpoint_calc_normal(nu, bp, r_dir);
+ copy_m3_m4(rsmat, ob->obmat);
+ mul_m3_v3(rsmat, r_dir);
+ normalize_v3(r_dir);
}
static void curve_nurb_selected_type_get(
- Object *ob, Nurb *nu, const int type, KDTree_1d *tree_1d, KDTree_3d *tree_3d)
+ Object *ob, Nurb *nu, const int type, KDTree_1d *tree_1d, KDTree_3d *tree_3d)
{
- float tree_entry[3] = {0.0f, 0.0f, 0.0f};
-
- if (nu->type == CU_BEZIER) {
- BezTriple *bezt;
- int i;
- int tree_index = 0;
-
- for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
- if ((!bezt->hide) && (bezt->f1 & SELECT)) {
-
- switch (type) {
- case SIMCURHAND_RADIUS:
- {
- float radius_ref = bezt->radius;
- tree_entry[0] = radius_ref;
- break;
- }
- case SIMCURHAND_WEIGHT:
- {
- float weight_ref = bezt->weight;
- tree_entry[0] = weight_ref;
- break;
- }
- case SIMCURHAND_DIRECTION:
- {
- nurb_bezt_direction_worldspace_get(ob, nu, bezt, tree_entry);
- break;
- }
- }
- if (tree_1d) {
- BLI_kdtree_1d_insert(tree_1d, tree_index++, tree_entry);
- }
- else {
- BLI_kdtree_3d_insert(tree_3d, tree_index++, tree_entry);
- }
- }
- }
- }
- else {
- BPoint *bp;
- int i;
- int tree_index = 0;
-
- for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
- if (!bp->hide && bp->f1 & SELECT) {
- switch (type) {
- case SIMCURHAND_RADIUS:
- {
- float radius_ref = bp->radius;
- tree_entry[0] = radius_ref;
- break;
- }
- case SIMCURHAND_WEIGHT:
- {
- float weight_ref = bp->weight;
- tree_entry[0] = weight_ref;
- break;
- }
- case SIMCURHAND_DIRECTION:
- {
- nurb_bpoint_direction_worldspace_get(ob, nu, bp, tree_entry);
- break;
- }
- }
- if (tree_1d) {
- BLI_kdtree_1d_insert(tree_1d, tree_index++, tree_entry);
- }
- else {
- BLI_kdtree_3d_insert(tree_3d, tree_index++, tree_entry);
- }
- }
- }
- }
+ float tree_entry[3] = {0.0f, 0.0f, 0.0f};
+
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt;
+ int i;
+ int tree_index = 0;
+
+ for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
+ if ((!bezt->hide) && (bezt->f1 & SELECT)) {
+
+ switch (type) {
+ case SIMCURHAND_RADIUS: {
+ float radius_ref = bezt->radius;
+ tree_entry[0] = radius_ref;
+ break;
+ }
+ case SIMCURHAND_WEIGHT: {
+ float weight_ref = bezt->weight;
+ tree_entry[0] = weight_ref;
+ break;
+ }
+ case SIMCURHAND_DIRECTION: {
+ nurb_bezt_direction_worldspace_get(ob, nu, bezt, tree_entry);
+ break;
+ }
+ }
+ if (tree_1d) {
+ BLI_kdtree_1d_insert(tree_1d, tree_index++, tree_entry);
+ }
+ else {
+ BLI_kdtree_3d_insert(tree_3d, tree_index++, tree_entry);
+ }
+ }
+ }
+ }
+ else {
+ BPoint *bp;
+ int i;
+ int tree_index = 0;
+
+ for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
+ if (!bp->hide && bp->f1 & SELECT) {
+ switch (type) {
+ case SIMCURHAND_RADIUS: {
+ float radius_ref = bp->radius;
+ tree_entry[0] = radius_ref;
+ break;
+ }
+ case SIMCURHAND_WEIGHT: {
+ float weight_ref = bp->weight;
+ tree_entry[0] = weight_ref;
+ break;
+ }
+ case SIMCURHAND_DIRECTION: {
+ nurb_bpoint_direction_worldspace_get(ob, nu, bp, tree_entry);
+ break;
+ }
+ }
+ if (tree_1d) {
+ BLI_kdtree_1d_insert(tree_1d, tree_index++, tree_entry);
+ }
+ else {
+ BLI_kdtree_3d_insert(tree_3d, tree_index++, tree_entry);
+ }
+ }
+ }
+ }
}
-static bool curve_nurb_select_similar_type(
- Object *ob, Nurb *nu, const int type,
- const KDTree_1d *tree_1d, const KDTree_3d *tree_3d,
- const float thresh, const int compare)
+static bool curve_nurb_select_similar_type(Object *ob,
+ Nurb *nu,
+ const int type,
+ const KDTree_1d *tree_1d,
+ const KDTree_3d *tree_3d,
+ const float thresh,
+ const int compare)
{
- const float thresh_cos = cosf(thresh * (float)M_PI_2);
- bool changed = false;
-
- if (nu->type == CU_BEZIER) {
- BezTriple *bezt;
- int i;
-
- for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
- if (!bezt->hide) {
- bool select = false;
-
- switch (type) {
- case SIMCURHAND_RADIUS:
- {
- float radius_ref = bezt->radius;
- if (ED_select_similar_compare_float_tree(tree_1d, radius_ref, thresh, compare)) {
- select = true;
- }
- break;
- }
- case SIMCURHAND_WEIGHT:
- {
- float weight_ref = bezt->weight;
- if (ED_select_similar_compare_float_tree(tree_1d, weight_ref, thresh, compare)) {
- select = true;
- }
- break;
- }
- case SIMCURHAND_DIRECTION:
- {
- float dir[3];
- nurb_bezt_direction_worldspace_get(ob, nu, bezt, dir);
- KDTreeNearest_3d nearest;
- if (BLI_kdtree_3d_find_nearest(tree_3d, dir, &nearest) != -1) {
- float orient = angle_normalized_v3v3(dir, nearest.co);
- float delta = thresh_cos - fabsf(cosf(orient));
- if (ED_select_similar_compare_float(delta, thresh, compare)) {
- select = true;
- }
- }
- break;
- }
- }
-
- if (select) {
- select_beztriple(bezt, SELECT, SELECT, VISIBLE);
- changed = true;
- }
- }
- }
- }
- else {
- BPoint *bp;
- int i;
-
- for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
- if (!bp->hide) {
- bool select = false;
-
- switch (type) {
- case SIMCURHAND_RADIUS:
- {
- float radius_ref = bp->radius;
- if (ED_select_similar_compare_float_tree(tree_1d, radius_ref, thresh, compare)) {
- select = true;
- }
- break;
- }
- case SIMCURHAND_WEIGHT:
- {
- float weight_ref = bp->weight;
- if (ED_select_similar_compare_float_tree(tree_1d, weight_ref, thresh, compare)) {
- select = true;
- }
- break;
- }
- case SIMCURHAND_DIRECTION:
- {
- float dir[3];
- nurb_bpoint_direction_worldspace_get(ob, nu, bp, dir);
- KDTreeNearest_3d nearest;
- if (BLI_kdtree_3d_find_nearest(tree_3d, dir, &nearest) != -1) {
- float orient = angle_normalized_v3v3(dir, nearest.co);
- float delta = fabsf(cosf(orient)) - thresh_cos;
- if (ED_select_similar_compare_float(delta, thresh, compare)) {
- select = true;
- }
- }
- break;
- }
- }
-
- if (select) {
- select_bpoint(bp, SELECT, SELECT, VISIBLE);
- changed = true;
- }
- }
- }
- }
- return changed;
+ const float thresh_cos = cosf(thresh * (float)M_PI_2);
+ bool changed = false;
+
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt;
+ int i;
+
+ for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
+ if (!bezt->hide) {
+ bool select = false;
+
+ switch (type) {
+ case SIMCURHAND_RADIUS: {
+ float radius_ref = bezt->radius;
+ if (ED_select_similar_compare_float_tree(tree_1d, radius_ref, thresh, compare)) {
+ select = true;
+ }
+ break;
+ }
+ case SIMCURHAND_WEIGHT: {
+ float weight_ref = bezt->weight;
+ if (ED_select_similar_compare_float_tree(tree_1d, weight_ref, thresh, compare)) {
+ select = true;
+ }
+ break;
+ }
+ case SIMCURHAND_DIRECTION: {
+ float dir[3];
+ nurb_bezt_direction_worldspace_get(ob, nu, bezt, dir);
+ KDTreeNearest_3d nearest;
+ if (BLI_kdtree_3d_find_nearest(tree_3d, dir, &nearest) != -1) {
+ float orient = angle_normalized_v3v3(dir, nearest.co);
+ float delta = thresh_cos - fabsf(cosf(orient));
+ if (ED_select_similar_compare_float(delta, thresh, compare)) {
+ select = true;
+ }
+ }
+ break;
+ }
+ }
+
+ if (select) {
+ select_beztriple(bezt, SELECT, SELECT, VISIBLE);
+ changed = true;
+ }
+ }
+ }
+ }
+ else {
+ BPoint *bp;
+ int i;
+
+ for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
+ if (!bp->hide) {
+ bool select = false;
+
+ switch (type) {
+ case SIMCURHAND_RADIUS: {
+ float radius_ref = bp->radius;
+ if (ED_select_similar_compare_float_tree(tree_1d, radius_ref, thresh, compare)) {
+ select = true;
+ }
+ break;
+ }
+ case SIMCURHAND_WEIGHT: {
+ float weight_ref = bp->weight;
+ if (ED_select_similar_compare_float_tree(tree_1d, weight_ref, thresh, compare)) {
+ select = true;
+ }
+ break;
+ }
+ case SIMCURHAND_DIRECTION: {
+ float dir[3];
+ nurb_bpoint_direction_worldspace_get(ob, nu, bp, dir);
+ KDTreeNearest_3d nearest;
+ if (BLI_kdtree_3d_find_nearest(tree_3d, dir, &nearest) != -1) {
+ float orient = angle_normalized_v3v3(dir, nearest.co);
+ float delta = fabsf(cosf(orient)) - thresh_cos;
+ if (ED_select_similar_compare_float(delta, thresh, compare)) {
+ select = true;
+ }
+ }
+ break;
+ }
+ }
+
+ if (select) {
+ select_bpoint(bp, SELECT, SELECT, VISIBLE);
+ changed = true;
+ }
+ }
+ }
+ }
+ return changed;
}
static int curve_select_similar_exec(bContext *C, wmOperator *op)
{
- /* Get props. */
- const int optype = RNA_enum_get(op->ptr, "type");
- const float thresh = RNA_float_get(op->ptr, "threshold");
- const int compare = RNA_enum_get(op->ptr, "compare");
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- int tot_nurbs_selected_all = 0;
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
- tot_nurbs_selected_all += ED_curve_select_count(v3d, cu->editnurb);
- }
-
- if (tot_nurbs_selected_all == 0) {
- BKE_report(op->reports, RPT_ERROR, "No control point selected");
- MEM_freeN(objects);
- return OPERATOR_CANCELLED;
- }
-
- KDTree_1d *tree_1d = NULL;
- KDTree_3d *tree_3d = NULL;
- short type_ref = 0;
-
- switch (optype) {
- case SIMCURHAND_RADIUS:
- case SIMCURHAND_WEIGHT:
- tree_1d = BLI_kdtree_1d_new(tot_nurbs_selected_all);
- break;
- case SIMCURHAND_DIRECTION:
- tree_3d = BLI_kdtree_3d_new(tot_nurbs_selected_all);
- break;
- }
-
- /* Get type of selected control points. */
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
- EditNurb *editnurb = cu->editnurb;
-
- Nurb *nu;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- if (!ED_curve_nurb_select_check(v3d, nu)) {
- continue;
- }
- switch (optype) {
- case SIMCURHAND_TYPE:
- {
- type_ref |= nu->type;
- break;
- }
- case SIMCURHAND_RADIUS:
- case SIMCURHAND_WEIGHT:
- case SIMCURHAND_DIRECTION:
- curve_nurb_selected_type_get(obedit, nu, optype, tree_1d, tree_3d);
- break;
- }
- }
- }
-
- if (tree_1d != NULL) {
- BLI_kdtree_1d_deduplicate(tree_1d);
- BLI_kdtree_1d_balance(tree_1d);
- }
- if (tree_3d != NULL) {
- BLI_kdtree_3d_deduplicate(tree_3d);
- BLI_kdtree_3d_balance(tree_3d);
- }
-
- /* Select control points with desired type. */
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- Curve *cu = obedit->data;
- EditNurb *editnurb = cu->editnurb;
- bool changed = false;
- Nurb *nu;
-
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- switch (optype) {
- case SIMCURHAND_TYPE:
- {
- if (nu->type & type_ref) {
- changed |= ED_curve_nurb_select_all(nu);
- }
- break;
- }
- case SIMCURHAND_RADIUS:
- case SIMCURHAND_WEIGHT:
- case SIMCURHAND_DIRECTION:
- changed = curve_nurb_select_similar_type(
- obedit, nu, optype, tree_1d, tree_3d, thresh, compare);
- break;
- }
- }
-
- if (changed) {
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- }
- }
-
- MEM_freeN(objects);
-
- if (tree_1d != NULL) {
- BLI_kdtree_1d_free(tree_1d);
- }
- if (tree_3d != NULL) {
- BLI_kdtree_3d_free(tree_3d);
- }
- return OPERATOR_FINISHED;
-
+ /* Get props. */
+ const int optype = RNA_enum_get(op->ptr, "type");
+ const float thresh = RNA_float_get(op->ptr, "threshold");
+ const int compare = RNA_enum_get(op->ptr, "compare");
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ int tot_nurbs_selected_all = 0;
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+ tot_nurbs_selected_all += ED_curve_select_count(v3d, cu->editnurb);
+ }
+
+ if (tot_nurbs_selected_all == 0) {
+ BKE_report(op->reports, RPT_ERROR, "No control point selected");
+ MEM_freeN(objects);
+ return OPERATOR_CANCELLED;
+ }
+
+ KDTree_1d *tree_1d = NULL;
+ KDTree_3d *tree_3d = NULL;
+ short type_ref = 0;
+
+ switch (optype) {
+ case SIMCURHAND_RADIUS:
+ case SIMCURHAND_WEIGHT:
+ tree_1d = BLI_kdtree_1d_new(tot_nurbs_selected_all);
+ break;
+ case SIMCURHAND_DIRECTION:
+ tree_3d = BLI_kdtree_3d_new(tot_nurbs_selected_all);
+ break;
+ }
+
+ /* Get type of selected control points. */
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+ EditNurb *editnurb = cu->editnurb;
+
+ Nurb *nu;
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ if (!ED_curve_nurb_select_check(v3d, nu)) {
+ continue;
+ }
+ switch (optype) {
+ case SIMCURHAND_TYPE: {
+ type_ref |= nu->type;
+ break;
+ }
+ case SIMCURHAND_RADIUS:
+ case SIMCURHAND_WEIGHT:
+ case SIMCURHAND_DIRECTION:
+ curve_nurb_selected_type_get(obedit, nu, optype, tree_1d, tree_3d);
+ break;
+ }
+ }
+ }
+
+ if (tree_1d != NULL) {
+ BLI_kdtree_1d_deduplicate(tree_1d);
+ BLI_kdtree_1d_balance(tree_1d);
+ }
+ if (tree_3d != NULL) {
+ BLI_kdtree_3d_deduplicate(tree_3d);
+ BLI_kdtree_3d_balance(tree_3d);
+ }
+
+ /* Select control points with desired type. */
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Curve *cu = obedit->data;
+ EditNurb *editnurb = cu->editnurb;
+ bool changed = false;
+ Nurb *nu;
+
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ switch (optype) {
+ case SIMCURHAND_TYPE: {
+ if (nu->type & type_ref) {
+ changed |= ED_curve_nurb_select_all(nu);
+ }
+ break;
+ }
+ case SIMCURHAND_RADIUS:
+ case SIMCURHAND_WEIGHT:
+ case SIMCURHAND_DIRECTION:
+ changed = curve_nurb_select_similar_type(
+ obedit, nu, optype, tree_1d, tree_3d, thresh, compare);
+ break;
+ }
+ }
+
+ if (changed) {
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ }
+ }
+
+ MEM_freeN(objects);
+
+ if (tree_1d != NULL) {
+ BLI_kdtree_1d_free(tree_1d);
+ }
+ if (tree_3d != NULL) {
+ BLI_kdtree_3d_free(tree_3d);
+ }
+ return OPERATOR_FINISHED;
}
void CURVE_OT_select_similar(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Similar";
- ot->idname = "CURVE_OT_select_similar";
- ot->description = "Select similar curve points by property type";
-
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = curve_select_similar_exec;
- ot->poll = ED_operator_editsurfcurve;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", curve_prop_similar_types, SIMCURHAND_WEIGHT, "Type", "");
- RNA_def_enum(ot->srna, "compare", curve_prop_similar_compare_types, SIM_CMP_EQ, "Compare", "");
- RNA_def_float(ot->srna, "threshold", 0.1, 0.0, FLT_MAX, "Threshold", "", 0.0, 100.0);
+ /* identifiers */
+ ot->name = "Select Similar";
+ ot->idname = "CURVE_OT_select_similar";
+ ot->description = "Select similar curve points by property type";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = curve_select_similar_exec;
+ ot->poll = ED_operator_editsurfcurve;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", curve_prop_similar_types, SIMCURHAND_WEIGHT, "Type", "");
+ RNA_def_enum(ot->srna, "compare", curve_prop_similar_compare_types, SIM_CMP_EQ, "Compare", "");
+ RNA_def_float(ot->srna, "threshold", 0.1, 0.0, FLT_MAX, "Threshold", "", 0.0, 100.0);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Select Shortest Path */
@@ -1797,232 +1804,230 @@ void CURVE_OT_select_similar(wmOperatorType *ot)
static float curve_calc_dist_pair(const Nurb *nu, int a, int b)
{
- const float *a_fl, *b_fl;
-
- if (nu->type == CU_BEZIER) {
- a_fl = nu->bezt[a].vec[1];
- b_fl = nu->bezt[b].vec[1];
- }
- else {
- a_fl = nu->bp[a].vec;
- b_fl = nu->bp[b].vec;
- }
-
- return len_v3v3(a_fl, b_fl);
+ const float *a_fl, *b_fl;
+
+ if (nu->type == CU_BEZIER) {
+ a_fl = nu->bezt[a].vec[1];
+ b_fl = nu->bezt[b].vec[1];
+ }
+ else {
+ a_fl = nu->bp[a].vec;
+ b_fl = nu->bp[b].vec;
+ }
+
+ return len_v3v3(a_fl, b_fl);
}
static float curve_calc_dist_span(Nurb *nu, int vert_src, int vert_dst)
{
- const int u = nu->pntsu;
- int i_prev, i;
- float dist = 0.0f;
+ const int u = nu->pntsu;
+ int i_prev, i;
+ float dist = 0.0f;
- BLI_assert(nu->pntsv == 1);
+ BLI_assert(nu->pntsv == 1);
- i_prev = vert_src;
- i = (i_prev + 1) % u;
+ i_prev = vert_src;
+ i = (i_prev + 1) % u;
- while (true) {
- dist += curve_calc_dist_pair(nu, i_prev, i);
+ while (true) {
+ dist += curve_calc_dist_pair(nu, i_prev, i);
- if (i == vert_dst) {
- break;
- }
- i = (i + 1) % u;
- }
- return dist;
+ if (i == vert_dst) {
+ break;
+ }
+ i = (i + 1) % u;
+ }
+ return dist;
}
static void curve_select_shortest_path_curve(Nurb *nu, int vert_src, int vert_dst)
{
- const int u = nu->pntsu;
- int i;
-
- if (vert_src > vert_dst) {
- SWAP(int, vert_src, vert_dst);
- }
-
- if (nu->flagu & CU_NURB_CYCLIC) {
- if (curve_calc_dist_span(nu, vert_src, vert_dst) >
- curve_calc_dist_span(nu, vert_dst, vert_src))
- {
- SWAP(int, vert_src, vert_dst);
- }
- }
-
- i = vert_src;
- while (true) {
- if (nu->type & CU_BEZIER) {
- select_beztriple(&nu->bezt[i], SELECT, SELECT, HIDDEN);
- }
- else {
- select_bpoint(&nu->bp[i], SELECT, SELECT, HIDDEN);
- }
-
- if (i == vert_dst) {
- break;
- }
- i = (i + 1) % u;
- }
+ const int u = nu->pntsu;
+ int i;
+
+ if (vert_src > vert_dst) {
+ SWAP(int, vert_src, vert_dst);
+ }
+
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ if (curve_calc_dist_span(nu, vert_src, vert_dst) >
+ curve_calc_dist_span(nu, vert_dst, vert_src)) {
+ SWAP(int, vert_src, vert_dst);
+ }
+ }
+
+ i = vert_src;
+ while (true) {
+ if (nu->type & CU_BEZIER) {
+ select_beztriple(&nu->bezt[i], SELECT, SELECT, HIDDEN);
+ }
+ else {
+ select_bpoint(&nu->bp[i], SELECT, SELECT, HIDDEN);
+ }
+
+ if (i == vert_dst) {
+ break;
+ }
+ i = (i + 1) % u;
+ }
}
static void curve_select_shortest_path_surf(Nurb *nu, int vert_src, int vert_dst)
{
- HeapSimple *heap;
-
- int i, vert_curr;
-
- int totu = nu->pntsu;
- int totv = nu->pntsv;
- int vert_num = totu * totv;
-
- /* custom data */
- struct PointAdj {
- int vert, vert_prev;
- float cost;
- } *data;
-
- /* init connectivity data */
- data = MEM_mallocN(sizeof(*data) * vert_num, __func__);
- for (i = 0; i < vert_num; i++) {
- data[i].vert = i;
- data[i].vert_prev = -1;
- data[i].cost = FLT_MAX;
- }
-
- /* init heap */
- heap = BLI_heapsimple_new();
-
- vert_curr = data[vert_src].vert;
- BLI_heapsimple_insert(heap, 0.0f, &data[vert_src].vert);
- data[vert_src].cost = 0.0f;
- data[vert_src].vert_prev = vert_src; /* nop */
-
- while (!BLI_heapsimple_is_empty(heap)) {
- int axis, sign;
- int u, v;
-
- vert_curr = *((int *)BLI_heapsimple_pop_min(heap));
- if (vert_curr == vert_dst) {
- break;
- }
-
- BKE_nurb_index_to_uv(nu, vert_curr, &u, &v);
-
- /* loop over 4 adjacent verts */
- for (sign = -1; sign != 3; sign += 2) {
- for (axis = 0; axis != 2; axis += 1) {
- int uv_other[2] = {u, v};
- int vert_other;
-
- uv_other[axis] += sign;
-
- vert_other = BKE_nurb_index_from_uv(nu, uv_other[0], uv_other[1]);
- if (vert_other != -1) {
- const float dist = data[vert_curr].cost + curve_calc_dist_pair(nu, vert_curr, vert_other);
-
- if (data[vert_other].cost > dist) {
- data[vert_other].cost = dist;
- if (data[vert_other].vert_prev == -1) {
- BLI_heapsimple_insert(heap, data[vert_other].cost, &data[vert_other].vert);
- }
- data[vert_other].vert_prev = vert_curr;
- }
- }
-
- }
- }
-
- }
-
- BLI_heapsimple_free(heap, NULL);
-
- if (vert_curr == vert_dst) {
- i = 0;
- while (vert_curr != vert_src && i++ < vert_num) {
- if (nu->type == CU_BEZIER) {
- select_beztriple(&nu->bezt[vert_curr], SELECT, SELECT, HIDDEN);
- }
- else {
- select_bpoint(&nu->bp[vert_curr], SELECT, SELECT, HIDDEN);
- }
- vert_curr = data[vert_curr].vert_prev;
- }
- }
-
- MEM_freeN(data);
+ HeapSimple *heap;
+
+ int i, vert_curr;
+
+ int totu = nu->pntsu;
+ int totv = nu->pntsv;
+ int vert_num = totu * totv;
+
+ /* custom data */
+ struct PointAdj {
+ int vert, vert_prev;
+ float cost;
+ } * data;
+
+ /* init connectivity data */
+ data = MEM_mallocN(sizeof(*data) * vert_num, __func__);
+ for (i = 0; i < vert_num; i++) {
+ data[i].vert = i;
+ data[i].vert_prev = -1;
+ data[i].cost = FLT_MAX;
+ }
+
+ /* init heap */
+ heap = BLI_heapsimple_new();
+
+ vert_curr = data[vert_src].vert;
+ BLI_heapsimple_insert(heap, 0.0f, &data[vert_src].vert);
+ data[vert_src].cost = 0.0f;
+ data[vert_src].vert_prev = vert_src; /* nop */
+
+ while (!BLI_heapsimple_is_empty(heap)) {
+ int axis, sign;
+ int u, v;
+
+ vert_curr = *((int *)BLI_heapsimple_pop_min(heap));
+ if (vert_curr == vert_dst) {
+ break;
+ }
+
+ BKE_nurb_index_to_uv(nu, vert_curr, &u, &v);
+
+ /* loop over 4 adjacent verts */
+ for (sign = -1; sign != 3; sign += 2) {
+ for (axis = 0; axis != 2; axis += 1) {
+ int uv_other[2] = {u, v};
+ int vert_other;
+
+ uv_other[axis] += sign;
+
+ vert_other = BKE_nurb_index_from_uv(nu, uv_other[0], uv_other[1]);
+ if (vert_other != -1) {
+ const float dist = data[vert_curr].cost +
+ curve_calc_dist_pair(nu, vert_curr, vert_other);
+
+ if (data[vert_other].cost > dist) {
+ data[vert_other].cost = dist;
+ if (data[vert_other].vert_prev == -1) {
+ BLI_heapsimple_insert(heap, data[vert_other].cost, &data[vert_other].vert);
+ }
+ data[vert_other].vert_prev = vert_curr;
+ }
+ }
+ }
+ }
+ }
+
+ BLI_heapsimple_free(heap, NULL);
+
+ if (vert_curr == vert_dst) {
+ i = 0;
+ while (vert_curr != vert_src && i++ < vert_num) {
+ if (nu->type == CU_BEZIER) {
+ select_beztriple(&nu->bezt[vert_curr], SELECT, SELECT, HIDDEN);
+ }
+ else {
+ select_bpoint(&nu->bp[vert_curr], SELECT, SELECT, HIDDEN);
+ }
+ vert_curr = data[vert_curr].vert_prev;
+ }
+ }
+
+ MEM_freeN(data);
}
static int edcu_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewContext vc;
- Nurb *nu_dst;
- BezTriple *bezt_dst;
- BPoint *bp_dst;
- int vert_dst;
- void *vert_dst_p;
- Base *basact = NULL;
-
- view3d_operator_needs_opengl(C);
- ED_view3d_viewcontext_init(C, &vc);
- copy_v2_v2_int(vc.mval, event->mval);
-
- if (!ED_curve_pick_vert(&vc, 1, &nu_dst, &bezt_dst, &bp_dst, NULL, &basact)) {
- return OPERATOR_PASS_THROUGH;
- }
-
- ED_view3d_viewcontext_init_object(&vc, basact->object);
- Object *obedit = basact->object;
- Curve *cu = obedit->data;
- Nurb *nu_src = BKE_curve_nurb_active_get(cu);
- int vert_src = cu->actvert;
-
- if (vert_src == CU_ACT_NONE) {
- return OPERATOR_PASS_THROUGH;
- }
-
- if (nu_src != nu_dst) {
- BKE_report(op->reports, RPT_ERROR, "Control point belongs to another spline");
- return OPERATOR_CANCELLED;
- }
-
- vert_dst_p = bezt_dst ? (void *)bezt_dst : (void *)bp_dst;
- vert_dst = BKE_curve_nurb_vert_index_get(nu_dst, vert_dst_p);
- if (vert_src == vert_dst) {
- return OPERATOR_CANCELLED;
- }
-
- if ((obedit->type == OB_SURF) && (nu_src->pntsv > 1)) {
- curve_select_shortest_path_surf(nu_src, vert_src, vert_dst);
- }
- else {
- curve_select_shortest_path_curve(nu_src, vert_src, vert_dst);
- }
-
- BKE_curve_nurb_vert_active_set(cu, nu_dst, vert_dst_p);
-
- if (vc.view_layer->basact != basact) {
- ED_object_base_activate(C, basact);
- }
-
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
- return OPERATOR_FINISHED;
+ ViewContext vc;
+ Nurb *nu_dst;
+ BezTriple *bezt_dst;
+ BPoint *bp_dst;
+ int vert_dst;
+ void *vert_dst_p;
+ Base *basact = NULL;
+
+ view3d_operator_needs_opengl(C);
+ ED_view3d_viewcontext_init(C, &vc);
+ copy_v2_v2_int(vc.mval, event->mval);
+
+ if (!ED_curve_pick_vert(&vc, 1, &nu_dst, &bezt_dst, &bp_dst, NULL, &basact)) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ ED_view3d_viewcontext_init_object(&vc, basact->object);
+ Object *obedit = basact->object;
+ Curve *cu = obedit->data;
+ Nurb *nu_src = BKE_curve_nurb_active_get(cu);
+ int vert_src = cu->actvert;
+
+ if (vert_src == CU_ACT_NONE) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ if (nu_src != nu_dst) {
+ BKE_report(op->reports, RPT_ERROR, "Control point belongs to another spline");
+ return OPERATOR_CANCELLED;
+ }
+
+ vert_dst_p = bezt_dst ? (void *)bezt_dst : (void *)bp_dst;
+ vert_dst = BKE_curve_nurb_vert_index_get(nu_dst, vert_dst_p);
+ if (vert_src == vert_dst) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if ((obedit->type == OB_SURF) && (nu_src->pntsv > 1)) {
+ curve_select_shortest_path_surf(nu_src, vert_src, vert_dst);
+ }
+ else {
+ curve_select_shortest_path_curve(nu_src, vert_src, vert_dst);
+ }
+
+ BKE_curve_nurb_vert_active_set(cu, nu_dst, vert_dst_p);
+
+ if (vc.view_layer->basact != basact) {
+ ED_object_base_activate(C, basact);
+ }
+
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ return OPERATOR_FINISHED;
}
void CURVE_OT_shortest_path_pick(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Pick Shortest Path";
- ot->idname = "CURVE_OT_shortest_path_pick";
- ot->description = "Select shortest path between two selections";
+ /* identifiers */
+ ot->name = "Pick Shortest Path";
+ ot->idname = "CURVE_OT_shortest_path_pick";
+ ot->description = "Select shortest path between two selections";
- /* api callbacks */
- ot->invoke = edcu_shortest_path_pick_invoke;
- ot->poll = ED_operator_editsurfcurve_region_view3d;
+ /* api callbacks */
+ ot->invoke = edcu_shortest_path_pick_invoke;
+ ot->poll = ED_operator_editsurfcurve_region_view3d;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
diff --git a/source/blender/editors/curve/editcurve_undo.c b/source/blender/editors/curve/editcurve_undo.c
index 6cde9abb33f..d0c2afcb1d2 100644
--- a/source/blender/editors/curve/editcurve_undo.c
+++ b/source/blender/editors/curve/editcurve_undo.c
@@ -58,133 +58,131 @@ static CLG_LogRef LOG = {"ed.undo.curve"};
* \{ */
typedef struct {
- ListBase nubase;
- int actvert;
- GHash *undoIndex;
- ListBase fcurves, drivers;
- int actnu;
- int 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;
+ ListBase nubase;
+ int actvert;
+ GHash *undoIndex;
+ ListBase fcurves, drivers;
+ int actnu;
+ int 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;
} UndoCurve;
static void undocurve_to_editcurve(Main *bmain, UndoCurve *ucu, Curve *cu, short *r_shapenr)
{
- ListBase *undobase = &ucu->nubase;
- ListBase *editbase = BKE_curve_editNurbs_get(cu);
- Nurb *nu, *newnu;
- 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) {
- if (ad->action) {
- free_fcurves(&ad->action->curves);
- copy_fcurves(&ad->action->curves, &ucu->fcurves);
- }
-
- free_fcurves(&ad->drivers);
- copy_fcurves(&ad->drivers, &ucu->drivers);
- }
-
- /* copy */
- for (nu = undobase->first; nu; nu = nu->next) {
- 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);
+ ListBase *undobase = &ucu->nubase;
+ ListBase *editbase = BKE_curve_editNurbs_get(cu);
+ Nurb *nu, *newnu;
+ 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) {
+ if (ad->action) {
+ free_fcurves(&ad->action->curves);
+ copy_fcurves(&ad->action->curves, &ucu->fcurves);
+ }
+
+ free_fcurves(&ad->drivers);
+ copy_fcurves(&ad->drivers, &ucu->drivers);
+ }
+
+ /* copy */
+ for (nu = undobase->first; nu; nu = nu->next) {
+ 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));
- ListBase *nubase = BKE_curve_editNurbs_get(cu);
- EditNurb *editnurb = cu->editnurb, tmpEditnurb;
- Nurb *nu, *newnu;
- AnimData *ad = BKE_animdata_from_id(&cu->id);
-
- /* TODO: include size of fcurve & undoIndex */
- // ucu->undo_size = 0;
-
- if (editnurb->keyindex) {
- ucu->undoIndex = ED_curve_keyindex_hash_duplicate(editnurb->keyindex);
- tmpEditnurb.keyindex = ucu->undoIndex;
- }
-
- if (ad) {
- if (ad->action) {
- copy_fcurves(&ucu->fcurves, &ad->action->curves);
- }
-
- copy_fcurves(&ucu->drivers, &ad->drivers);
- }
-
- /* copy */
- for (nu = nubase->first; nu; nu = nu->next) {
- 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;
+ BLI_assert(BLI_array_is_zeroed(ucu, 1));
+ ListBase *nubase = BKE_curve_editNurbs_get(cu);
+ EditNurb *editnurb = cu->editnurb, tmpEditnurb;
+ Nurb *nu, *newnu;
+ AnimData *ad = BKE_animdata_from_id(&cu->id);
+
+ /* TODO: include size of fcurve & undoIndex */
+ // ucu->undo_size = 0;
+
+ if (editnurb->keyindex) {
+ ucu->undoIndex = ED_curve_keyindex_hash_duplicate(editnurb->keyindex);
+ tmpEditnurb.keyindex = ucu->undoIndex;
+ }
+
+ if (ad) {
+ if (ad->action) {
+ copy_fcurves(&ucu->fcurves, &ad->action->curves);
+ }
+
+ copy_fcurves(&ucu->drivers, &ad->drivers);
+ }
+
+ /* copy */
+ for (nu = nubase->first; nu; nu = nu->next) {
+ 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_nurbList_free(&uc->nubase);
- BKE_curve_editNurb_keyIndex_free(&uc->undoIndex);
+ BKE_curve_editNurb_keyIndex_free(&uc->undoIndex);
- free_fcurves(&uc->fcurves);
- free_fcurves(&uc->drivers);
+ free_fcurves(&uc->fcurves);
+ free_fcurves(&uc->drivers);
}
static Object *editcurve_object_from_context(bContext *C)
{
- Object *obedit = CTX_data_edit_object(C);
- if (obedit && ELEM(obedit->type, OB_CURVE, OB_SURF)) {
- Curve *cu = obedit->data;
- if (BKE_curve_editNurbs_get(cu) != NULL) {
- return obedit;
- }
- }
- return NULL;
+ Object *obedit = CTX_data_edit_object(C);
+ if (obedit && ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ Curve *cu = obedit->data;
+ if (BKE_curve_editNurbs_get(cu) != NULL) {
+ return obedit;
+ }
+ }
+ return NULL;
}
/** \} */
@@ -196,113 +194,123 @@ static Object *editcurve_object_from_context(bContext *C)
* \{ */
typedef struct CurveUndoStep_Elem {
- UndoRefID_Object obedit_ref;
- UndoCurve data;
+ UndoRefID_Object obedit_ref;
+ UndoCurve data;
} CurveUndoStep_Elem;
typedef struct CurveUndoStep {
- UndoStep step;
- CurveUndoStep_Elem *elems;
- uint elems_len;
+ UndoStep step;
+ CurveUndoStep_Elem *elems;
+ uint elems_len;
} CurveUndoStep;
static bool curve_undosys_poll(bContext *C)
{
- Object *obedit = editcurve_object_from_context(C);
- return (obedit != NULL);
+ Object *obedit = editcurve_object_from_context(C);
+ return (obedit != NULL);
}
-static bool curve_undosys_step_encode(struct bContext *C, struct Main *UNUSED(bmain), UndoStep *us_p)
+static bool curve_undosys_step_encode(struct bContext *C,
+ struct Main *UNUSED(bmain),
+ UndoStep *us_p)
{
- CurveUndoStep *us = (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. */
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, NULL, &objects_len);
-
- us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
- us->elems_len = objects_len;
-
- for (uint i = 0; i < objects_len; i++) {
- Object *ob = objects[i];
- CurveUndoStep_Elem *elem = &us->elems[i];
-
- elem->obedit_ref.ptr = ob;
- undocurve_from_editcurve(&elem->data, ob->data, ob->shapenr);
- us->step.data_size += elem->data.undo_size;
- }
- MEM_freeN(objects);
- return true;
+ CurveUndoStep *us = (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. */
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, NULL, &objects_len);
+
+ us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
+ us->elems_len = objects_len;
+
+ for (uint i = 0; i < objects_len; i++) {
+ Object *ob = objects[i];
+ CurveUndoStep_Elem *elem = &us->elems[i];
+
+ elem->obedit_ref.ptr = ob;
+ undocurve_from_editcurve(&elem->data, ob->data, ob->shapenr);
+ us->step.data_size += elem->data.undo_size;
+ }
+ MEM_freeN(objects);
+ return true;
}
-static void curve_undosys_step_decode(struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir))
+static void curve_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ int UNUSED(dir))
{
- CurveUndoStep *us = (CurveUndoStep *)us_p;
-
- /* Load all our objects into edit-mode, clear everything else. */
- ED_undo_object_editmode_restore_helper(
- C, &us->elems[0].obedit_ref.ptr, us->elems_len, sizeof(*us->elems));
-
- BLI_assert(curve_undosys_poll(C));
-
- for (uint i = 0; i < us->elems_len; i++) {
- CurveUndoStep_Elem *elem = &us->elems[i];
- Object *obedit = elem->obedit_ref.ptr;
- Curve *cu = obedit->data;
- if (cu->editnurb == NULL) {
- /* 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, obedit->data, &obedit->shapenr);
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
- }
-
- /* The first element is always active */
- ED_undo_object_set_active_or_warn(CTX_data_view_layer(C), us->elems[0].obedit_ref.ptr, us_p->name, &LOG);
-
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
+ CurveUndoStep *us = (CurveUndoStep *)us_p;
+
+ /* Load all our objects into edit-mode, clear everything else. */
+ ED_undo_object_editmode_restore_helper(
+ C, &us->elems[0].obedit_ref.ptr, us->elems_len, sizeof(*us->elems));
+
+ BLI_assert(curve_undosys_poll(C));
+
+ for (uint i = 0; i < us->elems_len; i++) {
+ CurveUndoStep_Elem *elem = &us->elems[i];
+ Object *obedit = elem->obedit_ref.ptr;
+ Curve *cu = obedit->data;
+ if (cu->editnurb == NULL) {
+ /* 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, obedit->data, &obedit->shapenr);
+ DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ }
+
+ /* The first element is always active */
+ ED_undo_object_set_active_or_warn(
+ CTX_data_view_layer(C), us->elems[0].obedit_ref.ptr, us_p->name, &LOG);
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
static void curve_undosys_step_free(UndoStep *us_p)
{
- CurveUndoStep *us = (CurveUndoStep *)us_p;
+ CurveUndoStep *us = (CurveUndoStep *)us_p;
- for (uint i = 0; i < us->elems_len; i++) {
- CurveUndoStep_Elem *elem = &us->elems[i];
- undocurve_free_data(&elem->data);
- }
- MEM_freeN(us->elems);
+ for (uint i = 0; i < us->elems_len; i++) {
+ CurveUndoStep_Elem *elem = &us->elems[i];
+ undocurve_free_data(&elem->data);
+ }
+ MEM_freeN(us->elems);
}
-static void curve_undosys_foreach_ID_ref(
- UndoStep *us_p, UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data)
+static void curve_undosys_foreach_ID_ref(UndoStep *us_p,
+ UndoTypeForEachIDRefFn foreach_ID_ref_fn,
+ void *user_data)
{
- CurveUndoStep *us = (CurveUndoStep *)us_p;
+ CurveUndoStep *us = (CurveUndoStep *)us_p;
- for (uint i = 0; i < us->elems_len; i++) {
- CurveUndoStep_Elem *elem = &us->elems[i];
- foreach_ID_ref_fn(user_data, ((UndoRefID *)&elem->obedit_ref));
- }
+ for (uint i = 0; i < us->elems_len; i++) {
+ CurveUndoStep_Elem *elem = &us->elems[i];
+ foreach_ID_ref_fn(user_data, ((UndoRefID *)&elem->obedit_ref));
+ }
}
/* Export for ED_undo_sys. */
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->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->step_foreach_ID_ref = curve_undosys_foreach_ID_ref;
- ut->use_context = true;
+ ut->use_context = true;
- ut->step_size = sizeof(CurveUndoStep);
+ ut->step_size = sizeof(CurveUndoStep);
}
/** \} */
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 480819dd47a..d1b1f43d8dd 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -21,7 +21,6 @@
* \ingroup edcurve
*/
-
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
@@ -76,1927 +75,2118 @@ static int kill_selection(Object *obedit, int ins);
static char findaccent(char char1, unsigned int code)
{
- char new = 0;
-
- if (char1 == 'a') {
- if (code == '`') { new = 224; }
- else if (code == 39) { new = 225; }
- else if (code == '^') { new = 226; }
- else if (code == '~') { new = 227; }
- else if (code == '"') { new = 228; }
- else if (code == 'o') { new = 229; }
- else if (code == 'e') { new = 230; }
- else if (code == '-') { new = 170; }
- }
- else if (char1 == 'c') {
- if (code == ',') { new = 231; }
- else if (code == '|') { new = 162; }
- else if (code == 'o') { new = 169; }
- }
- else if (char1 == 'e') {
- if (code == '`') { new = 232; }
- else if (code == 39) { new = 233; }
- else if (code == '^') { new = 234; }
- else if (code == '"') { new = 235; }
- }
- else if (char1 == 'i') {
- if (code == '`') { new = 236; }
- else if (code == 39) { new = 237; }
- else if (code == '^') { new = 238; }
- else if (code == '"') { new = 239; }
- }
- else if (char1 == 'n') {
- if (code == '~') { new = 241; }
- }
- else if (char1 == 'o') {
- if (code == '`') { new = 242; }
- else if (code == 39) { new = 243; }
- else if (code == '^') { new = 244; }
- else if (code == '~') { new = 245; }
- else if (code == '"') { new = 246; }
- else if (code == '/') { new = 248; }
- else if (code == '-') { new = 186; }
- else if (code == 'e') { new = 143; }
- else if (code == 'c') { new = 169; }
- else if (code == 'r') { new = 174; }
- }
- else if (char1 == 'r') {
- if (code == 'o') { new = 174; }
- }
- else if (char1 == 's') {
- if (code == 's') { new = 167; }
- }
- else if (char1 == 't') {
- if (code == 'm') { new = 153; }
- }
- else if (char1 == 'u') {
- if (code == '`') { new = 249; }
- else if (code == 39) { new = 250; }
- else if (code == '^') { new = 251; }
- else if (code == '"') { new = 252; }
- }
- else if (char1 == 'y') {
- if (code == 39) { new = 253; }
- else if (code == '"') { new = 255; }
- }
- else if (char1 == 'A') {
- if (code == '`') { new = 192; }
- else if (code == 39) { new = 193; }
- else if (code == '^') { new = 194; }
- else if (code == '~') { new = 195; }
- else if (code == '"') { new = 196; }
- else if (code == 'o') { new = 197; }
- else if (code == 'e') { new = 198; }
- }
- else if (char1 == 'C') {
- if (code == ',') { new = 199; }
- }
- else if (char1 == 'E') {
- if (code == '`') { new = 200; }
- else if (code == 39) { new = 201; }
- else if (code == '^') { new = 202; }
- else if (code == '"') { new = 203; }
- }
- else if (char1 == 'I') {
- if (code == '`') { new = 204; }
- else if (code == 39) { new = 205; }
- else if (code == '^') { new = 206; }
- else if (code == '"') { new = 207; }
- }
- else if (char1 == 'N') {
- if (code == '~') { new = 209; }
- }
- else if (char1 == 'O') {
- if (code == '`') { new = 210; }
- else if (code == 39) { new = 211; }
- else if (code == '^') { new = 212; }
- else if (code == '~') { new = 213; }
- else if (code == '"') { new = 214; }
- else if (code == '/') { new = 216; }
- else if (code == 'e') { new = 141; }
- }
- else if (char1 == 'U') {
- if (code == '`') { new = 217; }
- else if (code == 39) { new = 218; }
- else if (code == '^') { new = 219; }
- else if (code == '"') { new = 220; }
- }
- else if (char1 == 'Y') {
- if (code == 39) { new = 221; }
- }
- else if (char1 == '1') {
- if (code == '4') { new = 188; }
- if (code == '2') { new = 189; }
- }
- else if (char1 == '3') {
- if (code == '4') { new = 190; }
- }
- else if (char1 == ':') {
- if (code == '-') { new = 247; }
- }
- else if (char1 == '-') {
- if (code == ':') { new = 247; }
- if (code == '|') { new = 135; }
- if (code == '+') { new = 177; }
- }
- else if (char1 == '|') {
- if (code == '-') { new = 135; }
- if (code == '=') { new = 136; }
- }
- else if (char1 == '=') {
- if (code == '|') { new = 136; }
- }
- else if (char1 == '+') {
- if (code == '-') { new = 177; }
- }
-
- if (new) {
- return new;
- }
- else {
- return char1;
- }
+ char new = 0;
+
+ if (char1 == 'a') {
+ if (code == '`') {
+ new = 224;
+ }
+ else if (code == 39) {
+ new = 225;
+ }
+ else if (code == '^') {
+ new = 226;
+ }
+ else if (code == '~') {
+ new = 227;
+ }
+ else if (code == '"') {
+ new = 228;
+ }
+ else if (code == 'o') {
+ new = 229;
+ }
+ else if (code == 'e') {
+ new = 230;
+ }
+ else if (code == '-') {
+ new = 170;
+ }
+ }
+ else if (char1 == 'c') {
+ if (code == ',') {
+ new = 231;
+ }
+ else if (code == '|') {
+ new = 162;
+ }
+ else if (code == 'o') {
+ new = 169;
+ }
+ }
+ else if (char1 == 'e') {
+ if (code == '`') {
+ new = 232;
+ }
+ else if (code == 39) {
+ new = 233;
+ }
+ else if (code == '^') {
+ new = 234;
+ }
+ else if (code == '"') {
+ new = 235;
+ }
+ }
+ else if (char1 == 'i') {
+ if (code == '`') {
+ new = 236;
+ }
+ else if (code == 39) {
+ new = 237;
+ }
+ else if (code == '^') {
+ new = 238;
+ }
+ else if (code == '"') {
+ new = 239;
+ }
+ }
+ else if (char1 == 'n') {
+ if (code == '~') {
+ new = 241;
+ }
+ }
+ else if (char1 == 'o') {
+ if (code == '`') {
+ new = 242;
+ }
+ else if (code == 39) {
+ new = 243;
+ }
+ else if (code == '^') {
+ new = 244;
+ }
+ else if (code == '~') {
+ new = 245;
+ }
+ else if (code == '"') {
+ new = 246;
+ }
+ else if (code == '/') {
+ new = 248;
+ }
+ else if (code == '-') {
+ new = 186;
+ }
+ else if (code == 'e') {
+ new = 143;
+ }
+ else if (code == 'c') {
+ new = 169;
+ }
+ else if (code == 'r') {
+ new = 174;
+ }
+ }
+ else if (char1 == 'r') {
+ if (code == 'o') {
+ new = 174;
+ }
+ }
+ else if (char1 == 's') {
+ if (code == 's') {
+ new = 167;
+ }
+ }
+ else if (char1 == 't') {
+ if (code == 'm') {
+ new = 153;
+ }
+ }
+ else if (char1 == 'u') {
+ if (code == '`') {
+ new = 249;
+ }
+ else if (code == 39) {
+ new = 250;
+ }
+ else if (code == '^') {
+ new = 251;
+ }
+ else if (code == '"') {
+ new = 252;
+ }
+ }
+ else if (char1 == 'y') {
+ if (code == 39) {
+ new = 253;
+ }
+ else if (code == '"') {
+ new = 255;
+ }
+ }
+ else if (char1 == 'A') {
+ if (code == '`') {
+ new = 192;
+ }
+ else if (code == 39) {
+ new = 193;
+ }
+ else if (code == '^') {
+ new = 194;
+ }
+ else if (code == '~') {
+ new = 195;
+ }
+ else if (code == '"') {
+ new = 196;
+ }
+ else if (code == 'o') {
+ new = 197;
+ }
+ else if (code == 'e') {
+ new = 198;
+ }
+ }
+ else if (char1 == 'C') {
+ if (code == ',') {
+ new = 199;
+ }
+ }
+ else if (char1 == 'E') {
+ if (code == '`') {
+ new = 200;
+ }
+ else if (code == 39) {
+ new = 201;
+ }
+ else if (code == '^') {
+ new = 202;
+ }
+ else if (code == '"') {
+ new = 203;
+ }
+ }
+ else if (char1 == 'I') {
+ if (code == '`') {
+ new = 204;
+ }
+ else if (code == 39) {
+ new = 205;
+ }
+ else if (code == '^') {
+ new = 206;
+ }
+ else if (code == '"') {
+ new = 207;
+ }
+ }
+ else if (char1 == 'N') {
+ if (code == '~') {
+ new = 209;
+ }
+ }
+ else if (char1 == 'O') {
+ if (code == '`') {
+ new = 210;
+ }
+ else if (code == 39) {
+ new = 211;
+ }
+ else if (code == '^') {
+ new = 212;
+ }
+ else if (code == '~') {
+ new = 213;
+ }
+ else if (code == '"') {
+ new = 214;
+ }
+ else if (code == '/') {
+ new = 216;
+ }
+ else if (code == 'e') {
+ new = 141;
+ }
+ }
+ else if (char1 == 'U') {
+ if (code == '`') {
+ new = 217;
+ }
+ else if (code == 39) {
+ new = 218;
+ }
+ else if (code == '^') {
+ new = 219;
+ }
+ else if (code == '"') {
+ new = 220;
+ }
+ }
+ else if (char1 == 'Y') {
+ if (code == 39) {
+ new = 221;
+ }
+ }
+ else if (char1 == '1') {
+ if (code == '4') {
+ new = 188;
+ }
+ if (code == '2') {
+ new = 189;
+ }
+ }
+ else if (char1 == '3') {
+ if (code == '4') {
+ new = 190;
+ }
+ }
+ else if (char1 == ':') {
+ if (code == '-') {
+ new = 247;
+ }
+ }
+ else if (char1 == '-') {
+ if (code == ':') {
+ new = 247;
+ }
+ if (code == '|') {
+ new = 135;
+ }
+ if (code == '+') {
+ new = 177;
+ }
+ }
+ else if (char1 == '|') {
+ if (code == '-') {
+ new = 135;
+ }
+ if (code == '=') {
+ new = 136;
+ }
+ }
+ else if (char1 == '=') {
+ if (code == '|') {
+ new = 136;
+ }
+ }
+ else if (char1 == '+') {
+ if (code == '-') {
+ new = 177;
+ }
+ }
+
+ if (new) {
+ return new;
+ }
+ else {
+ return char1;
+ }
}
static int insert_into_textbuf(Object *obedit, uintptr_t c)
{
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
-
- if (ef->len < MAXTEXT - 1) {
- int x;
-
- for (x = ef->len; x > ef->pos; x--) {
- ef->textbuf[x] = ef->textbuf[x - 1];
- }
- for (x = ef->len; x > ef->pos; x--) {
- ef->textbufinfo[x] = ef->textbufinfo[x - 1];
- }
- ef->textbuf[ef->pos] = c;
- ef->textbufinfo[ef->pos] = cu->curinfo;
- ef->textbufinfo[ef->pos].kern = 0;
- ef->textbufinfo[ef->pos].mat_nr = obedit->actcol;
-
- ef->pos++;
- ef->len++;
- ef->textbuf[ef->len] = '\0';
-
- return 1;
- }
- else {
- return 0;
- }
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+
+ if (ef->len < MAXTEXT - 1) {
+ int x;
+
+ for (x = ef->len; x > ef->pos; x--) {
+ ef->textbuf[x] = ef->textbuf[x - 1];
+ }
+ for (x = ef->len; x > ef->pos; x--) {
+ ef->textbufinfo[x] = ef->textbufinfo[x - 1];
+ }
+ ef->textbuf[ef->pos] = c;
+ ef->textbufinfo[ef->pos] = cu->curinfo;
+ ef->textbufinfo[ef->pos].kern = 0;
+ ef->textbufinfo[ef->pos].mat_nr = obedit->actcol;
+
+ ef->pos++;
+ ef->len++;
+ ef->textbuf[ef->len] = '\0';
+
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
static void text_update_edited(bContext *C, Object *obedit, int mode)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
-
- BLI_assert(ef->len >= 0);
-
- /* run update first since it can move the cursor */
- if (mode == FO_EDIT) {
- /* re-tesselllate */
- DEG_id_tag_update(obedit->data, 0);
- }
- else {
- /* depsgraph runs above, but since we're not tagging for update, call direct */
- /* We need evaluated data here. */
- BKE_vfont_to_curve(DEG_get_evaluated_object(depsgraph, obedit), mode);
- }
-
- cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0];
-
- if (obedit->totcol > 0) {
- obedit->actcol = cu->curinfo.mat_nr;
-
- /* since this array is calloc'd, it can be 0 even though we try ensure
- * (mat_nr > 0) almost everywhere */
- if (obedit->actcol < 1) {
- obedit->actcol = 1;
- }
- }
-
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+
+ BLI_assert(ef->len >= 0);
+
+ /* run update first since it can move the cursor */
+ if (mode == FO_EDIT) {
+ /* re-tesselllate */
+ DEG_id_tag_update(obedit->data, 0);
+ }
+ else {
+ /* depsgraph runs above, but since we're not tagging for update, call direct */
+ /* We need evaluated data here. */
+ BKE_vfont_to_curve(DEG_get_evaluated_object(depsgraph, obedit), mode);
+ }
+
+ cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0];
+
+ if (obedit->totcol > 0) {
+ obedit->actcol = cu->curinfo.mat_nr;
+
+ /* since this array is calloc'd, it can be 0 even though we try ensure
+ * (mat_nr > 0) almost everywhere */
+ if (obedit->actcol < 1) {
+ obedit->actcol = 1;
+ }
+ }
+
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
}
/* -------------------------------------------------------------------- */
/* Generic Paste Functions */
/* text_update_edited(C, scene, obedit, 1, FO_EDIT); */
-static bool font_paste_wchar(Object *obedit, const wchar_t *str, const size_t str_len,
+static bool font_paste_wchar(Object *obedit,
+ const wchar_t *str,
+ const size_t str_len,
/* optional */
struct CharInfo *str_info)
{
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- int selend, selstart;
-
- if (BKE_vfont_select_get(obedit, &selstart, &selend) == 0) {
- selstart = selend = 0;
- }
-
- /* Verify that the copy buffer => [copy buffer len] + ef->len < MAXTEXT */
- if ((ef->len + str_len) - (selend - selstart) <= MAXTEXT) {
-
- kill_selection(obedit, 0);
-
- if (str_len) {
- int size = (ef->len * sizeof(wchar_t)) - (ef->pos * sizeof(wchar_t)) + sizeof(wchar_t);
- memmove(ef->textbuf + ef->pos + str_len, ef->textbuf + ef->pos, size);
- memcpy(ef->textbuf + ef->pos, str, str_len * sizeof(wchar_t));
-
- memmove(ef->textbufinfo + ef->pos + str_len, ef->textbufinfo + ef->pos, (ef->len - ef->pos + 1) * sizeof(CharInfo));
- if (str_info) {
- memcpy(ef->textbufinfo + ef->pos, str_info, str_len * sizeof(CharInfo));
- }
- else {
- memset(ef->textbufinfo + ef->pos, '\0', str_len * sizeof(CharInfo));
- }
-
- ef->len += str_len;
- ef->pos += str_len;
- }
-
- return true;
- }
-
- return false;
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ int selend, selstart;
+
+ if (BKE_vfont_select_get(obedit, &selstart, &selend) == 0) {
+ selstart = selend = 0;
+ }
+
+ /* Verify that the copy buffer => [copy buffer len] + ef->len < MAXTEXT */
+ if ((ef->len + str_len) - (selend - selstart) <= MAXTEXT) {
+
+ kill_selection(obedit, 0);
+
+ if (str_len) {
+ int size = (ef->len * sizeof(wchar_t)) - (ef->pos * sizeof(wchar_t)) + sizeof(wchar_t);
+ memmove(ef->textbuf + ef->pos + str_len, ef->textbuf + ef->pos, size);
+ memcpy(ef->textbuf + ef->pos, str, str_len * sizeof(wchar_t));
+
+ memmove(ef->textbufinfo + ef->pos + str_len,
+ ef->textbufinfo + ef->pos,
+ (ef->len - ef->pos + 1) * sizeof(CharInfo));
+ if (str_info) {
+ memcpy(ef->textbufinfo + ef->pos, str_info, str_len * sizeof(CharInfo));
+ }
+ else {
+ memset(ef->textbufinfo + ef->pos, '\0', str_len * sizeof(CharInfo));
+ }
+
+ ef->len += str_len;
+ ef->pos += str_len;
+ }
+
+ return true;
+ }
+
+ return false;
}
static bool font_paste_utf8(bContext *C, const char *str, const size_t str_len)
{
- Object *obedit = CTX_data_edit_object(C);
- bool retval;
+ Object *obedit = CTX_data_edit_object(C);
+ bool retval;
- int tmplen;
+ int tmplen;
- wchar_t *mem = MEM_mallocN((sizeof(wchar_t) * (str_len + 1)), __func__);
+ wchar_t *mem = MEM_mallocN((sizeof(wchar_t) * (str_len + 1)), __func__);
- tmplen = BLI_strncpy_wchar_from_utf8(mem, str, str_len + 1);
+ tmplen = BLI_strncpy_wchar_from_utf8(mem, str, str_len + 1);
- retval = font_paste_wchar(obedit, mem, tmplen, NULL);
+ retval = font_paste_wchar(obedit, mem, tmplen, NULL);
- MEM_freeN(mem);
+ MEM_freeN(mem);
- return retval;
+ return retval;
}
-
/* -------------------------------------------------------------------- */
/* Paste From File*/
static int paste_from_file(bContext *C, ReportList *reports, const char *filename)
{
- Object *obedit = CTX_data_edit_object(C);
- char *strp;
- size_t filelen;
- int retval;
-
- strp = BLI_file_read_text_as_mem(filename, 1, &filelen);
- if (strp == NULL) {
- BKE_reportf(reports, RPT_ERROR, "Failed to open file '%s'", filename);
- return OPERATOR_CANCELLED;
- }
- strp[filelen] = 0;
-
- if (font_paste_utf8(C, strp, filelen)) {
- text_update_edited(C, obedit, FO_EDIT);
- retval = OPERATOR_FINISHED;
-
- }
- else {
- BKE_reportf(reports, RPT_ERROR, "File too long %s", filename);
- retval = OPERATOR_CANCELLED;
- }
-
- MEM_freeN(strp);
-
- return retval;
+ Object *obedit = CTX_data_edit_object(C);
+ char *strp;
+ size_t filelen;
+ int retval;
+
+ strp = BLI_file_read_text_as_mem(filename, 1, &filelen);
+ if (strp == NULL) {
+ BKE_reportf(reports, RPT_ERROR, "Failed to open file '%s'", filename);
+ return OPERATOR_CANCELLED;
+ }
+ strp[filelen] = 0;
+
+ if (font_paste_utf8(C, strp, filelen)) {
+ text_update_edited(C, obedit, FO_EDIT);
+ retval = OPERATOR_FINISHED;
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR, "File too long %s", filename);
+ retval = OPERATOR_CANCELLED;
+ }
+
+ MEM_freeN(strp);
+
+ return retval;
}
static int paste_from_file_exec(bContext *C, wmOperator *op)
{
- char *path;
- int retval;
+ char *path;
+ int retval;
- path = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0);
- retval = paste_from_file(C, op->reports, path);
- MEM_freeN(path);
+ path = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0);
+ retval = paste_from_file(C, op->reports, path);
+ MEM_freeN(path);
- return retval;
+ return retval;
}
static int paste_from_file_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (RNA_struct_property_is_set(op->ptr, "filepath")) {
- return paste_from_file_exec(C, op);
- }
+ if (RNA_struct_property_is_set(op->ptr, "filepath")) {
+ return paste_from_file_exec(C, op);
+ }
- WM_event_add_fileselect(C, op);
+ WM_event_add_fileselect(C, op);
- return OPERATOR_RUNNING_MODAL;
+ return OPERATOR_RUNNING_MODAL;
}
void FONT_OT_text_paste_from_file(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Paste File";
- ot->description = "Paste contents from file";
- ot->idname = "FONT_OT_text_paste_from_file";
-
- /* api callbacks */
- ot->exec = paste_from_file_exec;
- ot->invoke = paste_from_file_invoke;
- ot->poll = ED_operator_editfont;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- WM_operator_properties_filesel(
- ot, FILE_TYPE_FOLDER | FILE_TYPE_TEXT, FILE_SPECIAL, FILE_OPENFILE,
- WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
+ /* identifiers */
+ ot->name = "Paste File";
+ ot->description = "Paste contents from file";
+ ot->idname = "FONT_OT_text_paste_from_file";
+
+ /* api callbacks */
+ ot->exec = paste_from_file_exec;
+ ot->invoke = paste_from_file_invoke;
+ ot->poll = ED_operator_editfont;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_filesel(ot,
+ FILE_TYPE_FOLDER | FILE_TYPE_TEXT,
+ FILE_SPECIAL,
+ FILE_OPENFILE,
+ WM_FILESEL_FILEPATH,
+ FILE_DEFAULTDISPLAY,
+ FILE_SORT_ALPHA);
}
/******************* text to object operator ********************/
static void txt_add_object(bContext *C, TextLine *firstline, int totline, const float offset[3])
{
- Main *bmain = CTX_data_main(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Curve *cu;
- Object *obedit;
- Base *base;
- struct TextLine *tmp;
- int nchars = 0, nbytes = 0;
- char *s;
- int a;
- float rot[3] = {0.f, 0.f, 0.f};
-
- obedit = BKE_object_add(bmain, scene, view_layer, OB_FONT, NULL);
- base = view_layer->basact;
+ Main *bmain = CTX_data_main(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Curve *cu;
+ Object *obedit;
+ Base *base;
+ struct TextLine *tmp;
+ int nchars = 0, nbytes = 0;
+ char *s;
+ int a;
+ float rot[3] = {0.f, 0.f, 0.f};
- /* seems to assume view align ? TODO - look into this, could be an operator option */
- ED_object_base_init_transform(C, base, NULL, rot);
+ obedit = BKE_object_add(bmain, scene, view_layer, OB_FONT, NULL);
+ base = view_layer->basact;
- BKE_object_where_is_calc(depsgraph, scene, obedit);
+ /* seems to assume view align ? TODO - look into this, could be an operator option */
+ ED_object_base_init_transform(C, base, NULL, rot);
- add_v3_v3(obedit->loc, offset);
+ BKE_object_where_is_calc(depsgraph, scene, obedit);
- cu = obedit->data;
- cu->vfont = BKE_vfont_builtin_get();
- id_us_plus(&cu->vfont->id);
+ add_v3_v3(obedit->loc, offset);
- for (tmp = firstline, a = 0; nbytes < MAXTEXT && a < totline; tmp = tmp->next, a++) {
- size_t nchars_line, nbytes_line;
- nchars_line = BLI_strlen_utf8_ex(tmp->line, &nbytes_line);
- nchars += nchars_line + 1;
- nbytes += nbytes_line + 1;
- }
+ cu = obedit->data;
+ cu->vfont = BKE_vfont_builtin_get();
+ id_us_plus(&cu->vfont->id);
- if (cu->str) {
- MEM_freeN(cu->str);
- }
- if (cu->strinfo) {
- MEM_freeN(cu->strinfo);
- }
+ for (tmp = firstline, a = 0; nbytes < MAXTEXT && a < totline; tmp = tmp->next, a++) {
+ size_t nchars_line, nbytes_line;
+ nchars_line = BLI_strlen_utf8_ex(tmp->line, &nbytes_line);
+ nchars += nchars_line + 1;
+ nbytes += nbytes_line + 1;
+ }
- cu->str = MEM_mallocN(nbytes + 4, "str");
- cu->strinfo = MEM_callocN((nchars + 4) * sizeof(CharInfo), "strinfo");
+ if (cu->str) {
+ MEM_freeN(cu->str);
+ }
+ if (cu->strinfo) {
+ MEM_freeN(cu->strinfo);
+ }
- cu->len = 0;
- cu->len_wchar = nchars - 1;
- cu->pos = 0;
+ cu->str = MEM_mallocN(nbytes + 4, "str");
+ cu->strinfo = MEM_callocN((nchars + 4) * sizeof(CharInfo), "strinfo");
- s = cu->str;
+ cu->len = 0;
+ cu->len_wchar = nchars - 1;
+ cu->pos = 0;
- for (tmp = firstline, a = 0; cu->len < MAXTEXT && a < totline; tmp = tmp->next, a++) {
- size_t nbytes_line;
+ s = cu->str;
- nbytes_line = BLI_strcpy_rlen(s, tmp->line);
+ for (tmp = firstline, a = 0; cu->len < MAXTEXT && a < totline; tmp = tmp->next, a++) {
+ size_t nbytes_line;
- s += nbytes_line;
- cu->len += nbytes_line;
+ nbytes_line = BLI_strcpy_rlen(s, tmp->line);
- if (tmp->next) {
- nbytes_line = BLI_strcpy_rlen(s, "\n");
+ s += nbytes_line;
+ cu->len += nbytes_line;
- s += nbytes_line;
- cu->len += nbytes_line;
- }
+ if (tmp->next) {
+ nbytes_line = BLI_strcpy_rlen(s, "\n");
- }
+ s += nbytes_line;
+ cu->len += nbytes_line;
+ }
+ }
- cu->pos = cu->len_wchar;
- *s = '\0';
+ cu->pos = cu->len_wchar;
+ *s = '\0';
- WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, obedit);
+ WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, obedit);
}
void ED_text_to_object(bContext *C, Text *text, const bool split_lines)
{
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- TextLine *line;
- float offset[3];
- int linenum = 0;
-
- if (!text || !text->lines.first) {
- return;
- }
-
- if (split_lines) {
- for (line = text->lines.first; line; line = line->next) {
- /* skip lines with no text, but still make space for them */
- if (line->line[0] == '\0') {
- linenum++;
- continue;
- }
-
- /* do the translation */
- offset[0] = 0;
- offset[1] = -linenum;
- offset[2] = 0;
-
- if (rv3d) {
- mul_mat3_m4_v3(rv3d->viewinv, offset);
- }
-
- txt_add_object(C, line, 1, offset);
-
- linenum++;
- }
- }
- else {
- offset[0] = 0.0f;
- offset[1] = 0.0f;
- offset[2] = 0.0f;
-
- txt_add_object(C, text->lines.first, BLI_listbase_count(&text->lines), offset);
- }
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ TextLine *line;
+ float offset[3];
+ int linenum = 0;
+
+ if (!text || !text->lines.first) {
+ return;
+ }
+
+ if (split_lines) {
+ for (line = text->lines.first; line; line = line->next) {
+ /* skip lines with no text, but still make space for them */
+ if (line->line[0] == '\0') {
+ linenum++;
+ continue;
+ }
+
+ /* do the translation */
+ offset[0] = 0;
+ offset[1] = -linenum;
+ offset[2] = 0;
+
+ if (rv3d) {
+ mul_mat3_m4_v3(rv3d->viewinv, offset);
+ }
+
+ txt_add_object(C, line, 1, offset);
+
+ linenum++;
+ }
+ }
+ else {
+ offset[0] = 0.0f;
+ offset[1] = 0.0f;
+ offset[2] = 0.0f;
+
+ txt_add_object(C, text->lines.first, BLI_listbase_count(&text->lines), offset);
+ }
}
/********************** utilities ***************************/
-static int kill_selection(Object *obedit, int ins) /* 1 == new character */
+static int kill_selection(Object *obedit, int ins) /* 1 == new character */
{
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- int selend, selstart, direction;
- int offset = 0;
- int getfrom;
-
- direction = BKE_vfont_select_get(obedit, &selstart, &selend);
- if (direction) {
- int size;
- if (ins) {
- offset = 1;
- }
- if (ef->pos >= selstart) {
- ef->pos = selstart + offset;
- }
- if ((direction == -1) && ins) {
- selstart++;
- selend++;
- }
- getfrom = selend + offset;
- if (ins == 0) {
- getfrom++;
- }
- size = (ef->len * sizeof(wchar_t)) - (selstart * sizeof(wchar_t)) + (offset * sizeof(wchar_t));
- memmove(ef->textbuf + selstart, ef->textbuf + getfrom, size);
- memmove(ef->textbufinfo + selstart, ef->textbufinfo + getfrom, ((ef->len - selstart) + offset) * sizeof(CharInfo));
- ef->len -= ((selend - selstart) + 1);
- ef->selstart = ef->selend = 0;
- }
-
- return(direction);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ int selend, selstart, direction;
+ int offset = 0;
+ int getfrom;
+
+ direction = BKE_vfont_select_get(obedit, &selstart, &selend);
+ if (direction) {
+ int size;
+ if (ins) {
+ offset = 1;
+ }
+ if (ef->pos >= selstart) {
+ ef->pos = selstart + offset;
+ }
+ if ((direction == -1) && ins) {
+ selstart++;
+ selend++;
+ }
+ getfrom = selend + offset;
+ if (ins == 0) {
+ getfrom++;
+ }
+ size = (ef->len * sizeof(wchar_t)) - (selstart * sizeof(wchar_t)) + (offset * sizeof(wchar_t));
+ memmove(ef->textbuf + selstart, ef->textbuf + getfrom, size);
+ memmove(ef->textbufinfo + selstart,
+ ef->textbufinfo + getfrom,
+ ((ef->len - selstart) + offset) * sizeof(CharInfo));
+ ef->len -= ((selend - selstart) + 1);
+ ef->selstart = ef->selend = 0;
+ }
+
+ return (direction);
}
/******************* set style operator ********************/
static const EnumPropertyItem style_items[] = {
- {CU_CHINFO_BOLD, "BOLD", 0, "Bold", ""},
- {CU_CHINFO_ITALIC, "ITALIC", 0, "Italic", ""},
- {CU_CHINFO_UNDERLINE, "UNDERLINE", 0, "Underline", ""},
- {CU_CHINFO_SMALLCAPS, "SMALL_CAPS", 0, "Small Caps", ""},
- {0, NULL, 0, NULL, NULL},
+ {CU_CHINFO_BOLD, "BOLD", 0, "Bold", ""},
+ {CU_CHINFO_ITALIC, "ITALIC", 0, "Italic", ""},
+ {CU_CHINFO_UNDERLINE, "UNDERLINE", 0, "Underline", ""},
+ {CU_CHINFO_SMALLCAPS, "SMALL_CAPS", 0, "Small Caps", ""},
+ {0, NULL, 0, NULL, NULL},
};
static int set_style(bContext *C, const int style, const bool clear)
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- int i, selstart, selend;
-
- if (!BKE_vfont_select_get(obedit, &selstart, &selend)) {
- return OPERATOR_CANCELLED;
- }
-
- for (i = selstart; i <= selend; i++) {
- if (clear) {
- ef->textbufinfo[i].flag &= ~style;
- }
- else {
- ef->textbufinfo[i].flag |= style;
- }
- }
-
- DEG_id_tag_update(obedit->data, 0);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
-
- return OPERATOR_FINISHED;
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ int i, selstart, selend;
+
+ if (!BKE_vfont_select_get(obedit, &selstart, &selend)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ for (i = selstart; i <= selend; i++) {
+ if (clear) {
+ ef->textbufinfo[i].flag &= ~style;
+ }
+ else {
+ ef->textbufinfo[i].flag |= style;
+ }
+ }
+
+ DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+
+ return OPERATOR_FINISHED;
}
static int set_style_exec(bContext *C, wmOperator *op)
{
- const int style = RNA_enum_get(op->ptr, "style");
- const bool clear = RNA_boolean_get(op->ptr, "clear");
+ const int style = RNA_enum_get(op->ptr, "style");
+ const bool clear = RNA_boolean_get(op->ptr, "clear");
- return set_style(C, style, clear);
+ return set_style(C, style, clear);
}
void FONT_OT_style_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Style";
- ot->description = "Set font style";
- ot->idname = "FONT_OT_style_set";
-
- /* api callbacks */
- ot->exec = set_style_exec;
- ot->poll = ED_operator_editfont;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_enum(ot->srna, "style", style_items, CU_CHINFO_BOLD, "Style", "Style to set selection to");
- RNA_def_boolean(ot->srna, "clear", 0, "Clear", "Clear style rather than setting it");
+ /* identifiers */
+ ot->name = "Set Style";
+ ot->description = "Set font style";
+ ot->idname = "FONT_OT_style_set";
+
+ /* api callbacks */
+ ot->exec = set_style_exec;
+ ot->poll = ED_operator_editfont;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(
+ ot->srna, "style", style_items, CU_CHINFO_BOLD, "Style", "Style to set selection to");
+ RNA_def_boolean(ot->srna, "clear", 0, "Clear", "Clear style rather than setting it");
}
/******************* toggle style operator ********************/
static int toggle_style_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- int style, clear, selstart, selend;
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ int style, clear, selstart, selend;
- if (!BKE_vfont_select_get(obedit, &selstart, &selend)) {
- return OPERATOR_CANCELLED;
- }
+ if (!BKE_vfont_select_get(obedit, &selstart, &selend)) {
+ return OPERATOR_CANCELLED;
+ }
- style = RNA_enum_get(op->ptr, "style");
+ style = RNA_enum_get(op->ptr, "style");
- cu->curinfo.flag ^= style;
- clear = (cu->curinfo.flag & style) == 0;
+ cu->curinfo.flag ^= style;
+ clear = (cu->curinfo.flag & style) == 0;
- return set_style(C, style, clear);
+ return set_style(C, style, clear);
}
void FONT_OT_style_toggle(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Toggle Style";
- ot->description = "Toggle font style";
- ot->idname = "FONT_OT_style_toggle";
+ /* identifiers */
+ ot->name = "Toggle Style";
+ ot->description = "Toggle font style";
+ ot->idname = "FONT_OT_style_toggle";
- /* api callbacks */
- ot->exec = toggle_style_exec;
- ot->poll = ED_operator_editfont;
+ /* api callbacks */
+ ot->exec = toggle_style_exec;
+ ot->poll = ED_operator_editfont;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_enum(ot->srna, "style", style_items, CU_CHINFO_BOLD, "Style", "Style to set selection to");
+ /* properties */
+ RNA_def_enum(
+ ot->srna, "style", style_items, CU_CHINFO_BOLD, "Style", "Style to set selection to");
}
-
/* -------------------------------------------------------------------- */
/* Select All */
static int font_select_all_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
-
- if (ef->len) {
- ef->selstart = 1;
- ef->selend = ef->len;
- ef->pos = ef->len;
-
- text_update_edited(C, obedit, FO_SELCHANGE);
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
-
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+
+ if (ef->len) {
+ ef->selstart = 1;
+ ef->selend = ef->len;
+ ef->pos = ef->len;
+
+ text_update_edited(C, obedit, FO_SELCHANGE);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void FONT_OT_select_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select All";
- ot->description = "Select all text";
- ot->idname = "FONT_OT_select_all";
+ /* identifiers */
+ ot->name = "Select All";
+ ot->description = "Select all text";
+ ot->idname = "FONT_OT_select_all";
- /* api callbacks */
- ot->exec = font_select_all_exec;
- ot->poll = ED_operator_editfont;
+ /* api callbacks */
+ ot->exec = font_select_all_exec;
+ ot->poll = ED_operator_editfont;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
/******************* copy text operator ********************/
static void copy_selection(Object *obedit)
{
- int selstart, selend;
-
- if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- char *buf = NULL;
- wchar_t *text_buf;
- size_t len_utf8;
-
- /* internal clipboard (for style) */
- BKE_vfont_clipboard_set(ef->textbuf + selstart, ef->textbufinfo + selstart, selend - selstart + 1);
- BKE_vfont_clipboard_get(&text_buf, NULL, &len_utf8, NULL);
-
- /* system clipboard */
- buf = MEM_mallocN(len_utf8 + 1, __func__);
- if (buf) {
- BLI_strncpy_wchar_as_utf8(buf, text_buf, len_utf8 + 1);
- WM_clipboard_text_set(buf, false);
- MEM_freeN(buf);
- }
- }
+ int selstart, selend;
+
+ if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ char *buf = NULL;
+ wchar_t *text_buf;
+ size_t len_utf8;
+
+ /* internal clipboard (for style) */
+ BKE_vfont_clipboard_set(
+ ef->textbuf + selstart, ef->textbufinfo + selstart, selend - selstart + 1);
+ BKE_vfont_clipboard_get(&text_buf, NULL, &len_utf8, NULL);
+
+ /* system clipboard */
+ buf = MEM_mallocN(len_utf8 + 1, __func__);
+ if (buf) {
+ BLI_strncpy_wchar_as_utf8(buf, text_buf, len_utf8 + 1);
+ WM_clipboard_text_set(buf, false);
+ MEM_freeN(buf);
+ }
+ }
}
static int copy_text_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
+ Object *obedit = CTX_data_edit_object(C);
- copy_selection(obedit);
+ copy_selection(obedit);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void FONT_OT_text_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Text";
- ot->description = "Copy selected text to clipboard";
- ot->idname = "FONT_OT_text_copy";
-
- /* api callbacks */
- ot->exec = copy_text_exec;
- ot->poll = ED_operator_editfont;
+ /* identifiers */
+ ot->name = "Copy Text";
+ ot->description = "Copy selected text to clipboard";
+ ot->idname = "FONT_OT_text_copy";
+
+ /* api callbacks */
+ ot->exec = copy_text_exec;
+ ot->poll = ED_operator_editfont;
}
/******************* cut text operator ********************/
static int cut_text_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- int selstart, selend;
+ Object *obedit = CTX_data_edit_object(C);
+ int selstart, selend;
- if (!BKE_vfont_select_get(obedit, &selstart, &selend)) {
- return OPERATOR_CANCELLED;
- }
+ if (!BKE_vfont_select_get(obedit, &selstart, &selend)) {
+ return OPERATOR_CANCELLED;
+ }
- copy_selection(obedit);
- kill_selection(obedit, 0);
+ copy_selection(obedit);
+ kill_selection(obedit, 0);
- text_update_edited(C, obedit, FO_EDIT);
+ text_update_edited(C, obedit, FO_EDIT);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void FONT_OT_text_cut(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Cut Text";
- ot->description = "Cut selected text to clipboard";
- ot->idname = "FONT_OT_text_cut";
+ /* identifiers */
+ ot->name = "Cut Text";
+ ot->description = "Cut selected text to clipboard";
+ ot->idname = "FONT_OT_text_cut";
- /* api callbacks */
- ot->exec = cut_text_exec;
- ot->poll = ED_operator_editfont;
+ /* api callbacks */
+ ot->exec = cut_text_exec;
+ ot->poll = ED_operator_editfont;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/******************* paste text operator ********************/
static bool paste_selection(Object *obedit, ReportList *reports)
{
- wchar_t *text_buf;
- CharInfo *info_buf;
- size_t len;
-
- BKE_vfont_clipboard_get(&text_buf, &info_buf, NULL, &len);
-
- if (font_paste_wchar(obedit, text_buf, len, info_buf)) {
- return true;
- }
- else {
- BKE_report(reports, RPT_WARNING, "Text too long");
- return false;
- }
+ wchar_t *text_buf;
+ CharInfo *info_buf;
+ size_t len;
+
+ BKE_vfont_clipboard_get(&text_buf, &info_buf, NULL, &len);
+
+ if (font_paste_wchar(obedit, text_buf, len, info_buf)) {
+ return true;
+ }
+ else {
+ BKE_report(reports, RPT_WARNING, "Text too long");
+ return false;
+ }
}
static int paste_text_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- int retval;
- size_t len_utf8;
- wchar_t *text_buf;
-
- /* Store both clipboards as utf8 for comparison,
- * Give priority to the internal 'vfont' clipboard with its 'CharInfo' text styles
- * as long as its synchronized with the systems clipboard. */
- struct {
- char *buf;
- int len;
- } clipboard_system = {NULL}, clipboard_vfont = {NULL};
-
- clipboard_system.buf = WM_clipboard_text_get(false, &clipboard_system.len);
-
- if (clipboard_system.buf == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- BKE_vfont_clipboard_get(&text_buf, NULL, &len_utf8, NULL);
-
- if (text_buf) {
- clipboard_vfont.buf = MEM_mallocN(len_utf8 + 1, __func__);
-
- if (clipboard_vfont.buf == NULL) {
- MEM_freeN(clipboard_system.buf);
- return OPERATOR_CANCELLED;
- }
-
- BLI_strncpy_wchar_as_utf8(clipboard_vfont.buf, text_buf, len_utf8 + 1);
- }
-
- if (clipboard_vfont.buf && STREQ(clipboard_vfont.buf, clipboard_system.buf)) {
- retval = paste_selection(obedit, op->reports) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
- }
- else {
- if ((clipboard_system.len <= MAXTEXT) &&
- font_paste_utf8(C, clipboard_system.buf, clipboard_system.len))
- {
- text_update_edited(C, obedit, FO_EDIT);
- retval = OPERATOR_FINISHED;
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "Clipboard too long");
- retval = OPERATOR_CANCELLED;
- }
-
- /* free the existent clipboard buffer */
- BKE_vfont_clipboard_free();
- }
-
- if (retval != OPERATOR_CANCELLED) {
- text_update_edited(C, obedit, FO_EDIT);
- }
-
- /* cleanup */
- if (clipboard_vfont.buf) {
- MEM_freeN(clipboard_vfont.buf);
- }
-
- MEM_freeN(clipboard_system.buf);
-
- return retval;
+ Object *obedit = CTX_data_edit_object(C);
+ int retval;
+ size_t len_utf8;
+ wchar_t *text_buf;
+
+ /* Store both clipboards as utf8 for comparison,
+ * Give priority to the internal 'vfont' clipboard with its 'CharInfo' text styles
+ * as long as its synchronized with the systems clipboard. */
+ struct {
+ char *buf;
+ int len;
+ } clipboard_system = {NULL}, clipboard_vfont = {NULL};
+
+ clipboard_system.buf = WM_clipboard_text_get(false, &clipboard_system.len);
+
+ if (clipboard_system.buf == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_vfont_clipboard_get(&text_buf, NULL, &len_utf8, NULL);
+
+ if (text_buf) {
+ clipboard_vfont.buf = MEM_mallocN(len_utf8 + 1, __func__);
+
+ if (clipboard_vfont.buf == NULL) {
+ MEM_freeN(clipboard_system.buf);
+ return OPERATOR_CANCELLED;
+ }
+
+ BLI_strncpy_wchar_as_utf8(clipboard_vfont.buf, text_buf, len_utf8 + 1);
+ }
+
+ if (clipboard_vfont.buf && STREQ(clipboard_vfont.buf, clipboard_system.buf)) {
+ retval = paste_selection(obedit, op->reports) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ }
+ else {
+ if ((clipboard_system.len <= MAXTEXT) &&
+ font_paste_utf8(C, clipboard_system.buf, clipboard_system.len)) {
+ text_update_edited(C, obedit, FO_EDIT);
+ retval = OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Clipboard too long");
+ retval = OPERATOR_CANCELLED;
+ }
+
+ /* free the existent clipboard buffer */
+ BKE_vfont_clipboard_free();
+ }
+
+ if (retval != OPERATOR_CANCELLED) {
+ text_update_edited(C, obedit, FO_EDIT);
+ }
+
+ /* cleanup */
+ if (clipboard_vfont.buf) {
+ MEM_freeN(clipboard_vfont.buf);
+ }
+
+ MEM_freeN(clipboard_system.buf);
+
+ return retval;
}
void FONT_OT_text_paste(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Paste Text";
- ot->description = "Paste text from clipboard";
- ot->idname = "FONT_OT_text_paste";
+ /* identifiers */
+ ot->name = "Paste Text";
+ ot->description = "Paste text from clipboard";
+ ot->idname = "FONT_OT_text_paste";
- /* api callbacks */
- ot->exec = paste_text_exec;
- ot->poll = ED_operator_editfont;
+ /* api callbacks */
+ ot->exec = paste_text_exec;
+ ot->poll = ED_operator_editfont;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/************************ move operator ************************/
static const EnumPropertyItem move_type_items[] = {
- {LINE_BEGIN, "LINE_BEGIN", 0, "Line Begin", ""},
- {LINE_END, "LINE_END", 0, "Line End", ""},
- {PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
- {NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
- {PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
- {NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
- {PREV_LINE, "PREVIOUS_LINE", 0, "Previous Line", ""},
- {NEXT_LINE, "NEXT_LINE", 0, "Next Line", ""},
- {PREV_PAGE, "PREVIOUS_PAGE", 0, "Previous Page", ""},
- {NEXT_PAGE, "NEXT_PAGE", 0, "Next Page", ""},
- {0, NULL, 0, NULL, NULL},
+ {LINE_BEGIN, "LINE_BEGIN", 0, "Line Begin", ""},
+ {LINE_END, "LINE_END", 0, "Line End", ""},
+ {PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
+ {NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
+ {PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
+ {NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
+ {PREV_LINE, "PREVIOUS_LINE", 0, "Previous Line", ""},
+ {NEXT_LINE, "NEXT_LINE", 0, "Next Line", ""},
+ {PREV_PAGE, "PREVIOUS_PAGE", 0, "Previous Page", ""},
+ {NEXT_PAGE, "NEXT_PAGE", 0, "Next Page", ""},
+ {0, NULL, 0, NULL, NULL},
};
static int move_cursor(bContext *C, int type, const bool select)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- int cursmove = -1;
-
- if ((select) && (ef->selstart == 0)) {
- ef->selstart = ef->selend = ef->pos + 1;
- }
-
- switch (type) {
- case LINE_BEGIN:
- while (ef->pos > 0) {
- if (ef->textbuf[ef->pos - 1] == '\n') {
- break;
- }
- if (ef->textbufinfo[ef->pos - 1].flag & CU_CHINFO_WRAP) {
- break;
- }
- ef->pos--;
- }
- cursmove = FO_CURS;
- break;
-
- case LINE_END:
- while (ef->pos < ef->len) {
- if (ef->textbuf[ef->pos] == 0) {
- break;
- }
- if (ef->textbuf[ef->pos] == '\n') {
- break;
- }
- if (ef->textbufinfo[ef->pos].flag & CU_CHINFO_WRAP) {
- break;
- }
- ef->pos++;
- }
- cursmove = FO_CURS;
- break;
-
- case PREV_WORD:
- {
- int pos = ef->pos;
- BLI_str_cursor_step_wchar(ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
- ef->pos = pos;
- cursmove = FO_CURS;
- break;
- }
-
- case NEXT_WORD:
- {
- int pos = ef->pos;
- BLI_str_cursor_step_wchar(ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
- ef->pos = pos;
- cursmove = FO_CURS;
- break;
- }
-
- case PREV_CHAR:
- ef->pos--;
- cursmove = FO_CURS;
- break;
-
- case NEXT_CHAR:
- ef->pos++;
- cursmove = FO_CURS;
-
- break;
-
- case PREV_LINE:
- cursmove = FO_CURSUP;
- break;
-
- case NEXT_LINE:
- cursmove = FO_CURSDOWN;
- break;
-
- case PREV_PAGE:
- cursmove = FO_PAGEUP;
- break;
-
- case NEXT_PAGE:
- cursmove = FO_PAGEDOWN;
- break;
- }
-
- if (cursmove == -1) {
- return OPERATOR_CANCELLED;
- }
-
- if (ef->pos > ef->len) { ef->pos = ef->len; }
- else if (ef->pos >= MAXTEXT) { ef->pos = MAXTEXT; }
- else if (ef->pos < 0) { ef->pos = 0; }
-
- /* apply vertical cursor motion to position immediately
- * otherwise the selection will lag behind */
- if (FO_CURS_IS_MOTION(cursmove)) {
- BKE_vfont_to_curve(DEG_get_evaluated_object(depsgraph, obedit), cursmove);
- cursmove = FO_CURS;
- }
-
- if (select == 0) {
- if (ef->selstart) {
- ef->selstart = ef->selend = 0;
- BKE_vfont_to_curve(DEG_get_evaluated_object(depsgraph, obedit), FO_SELCHANGE);
- }
- }
-
- if (select) {
- ef->selend = ef->pos;
- }
-
- text_update_edited(C, obedit, cursmove);
-
- return OPERATOR_FINISHED;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ int cursmove = -1;
+
+ if ((select) && (ef->selstart == 0)) {
+ ef->selstart = ef->selend = ef->pos + 1;
+ }
+
+ switch (type) {
+ case LINE_BEGIN:
+ while (ef->pos > 0) {
+ if (ef->textbuf[ef->pos - 1] == '\n') {
+ break;
+ }
+ if (ef->textbufinfo[ef->pos - 1].flag & CU_CHINFO_WRAP) {
+ break;
+ }
+ ef->pos--;
+ }
+ cursmove = FO_CURS;
+ break;
+
+ case LINE_END:
+ while (ef->pos < ef->len) {
+ if (ef->textbuf[ef->pos] == 0) {
+ break;
+ }
+ if (ef->textbuf[ef->pos] == '\n') {
+ break;
+ }
+ if (ef->textbufinfo[ef->pos].flag & CU_CHINFO_WRAP) {
+ break;
+ }
+ ef->pos++;
+ }
+ cursmove = FO_CURS;
+ break;
+
+ case PREV_WORD: {
+ int pos = ef->pos;
+ BLI_str_cursor_step_wchar(
+ ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
+ ef->pos = pos;
+ cursmove = FO_CURS;
+ break;
+ }
+
+ case NEXT_WORD: {
+ int pos = ef->pos;
+ BLI_str_cursor_step_wchar(
+ ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
+ ef->pos = pos;
+ cursmove = FO_CURS;
+ break;
+ }
+
+ case PREV_CHAR:
+ ef->pos--;
+ cursmove = FO_CURS;
+ break;
+
+ case NEXT_CHAR:
+ ef->pos++;
+ cursmove = FO_CURS;
+
+ break;
+
+ case PREV_LINE:
+ cursmove = FO_CURSUP;
+ break;
+
+ case NEXT_LINE:
+ cursmove = FO_CURSDOWN;
+ break;
+
+ case PREV_PAGE:
+ cursmove = FO_PAGEUP;
+ break;
+
+ case NEXT_PAGE:
+ cursmove = FO_PAGEDOWN;
+ break;
+ }
+
+ if (cursmove == -1) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (ef->pos > ef->len) {
+ ef->pos = ef->len;
+ }
+ else if (ef->pos >= MAXTEXT) {
+ ef->pos = MAXTEXT;
+ }
+ else if (ef->pos < 0) {
+ ef->pos = 0;
+ }
+
+ /* apply vertical cursor motion to position immediately
+ * otherwise the selection will lag behind */
+ if (FO_CURS_IS_MOTION(cursmove)) {
+ BKE_vfont_to_curve(DEG_get_evaluated_object(depsgraph, obedit), cursmove);
+ cursmove = FO_CURS;
+ }
+
+ if (select == 0) {
+ if (ef->selstart) {
+ ef->selstart = ef->selend = 0;
+ BKE_vfont_to_curve(DEG_get_evaluated_object(depsgraph, obedit), FO_SELCHANGE);
+ }
+ }
+
+ if (select) {
+ ef->selend = ef->pos;
+ }
+
+ text_update_edited(C, obedit, cursmove);
+
+ return OPERATOR_FINISHED;
}
static int move_exec(bContext *C, wmOperator *op)
{
- int type = RNA_enum_get(op->ptr, "type");
+ int type = RNA_enum_get(op->ptr, "type");
- return move_cursor(C, type, false);
+ return move_cursor(C, type, false);
}
void FONT_OT_move(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Move Cursor";
- ot->description = "Move cursor to position type";
- ot->idname = "FONT_OT_move";
+ /* identifiers */
+ ot->name = "Move Cursor";
+ ot->description = "Move cursor to position type";
+ ot->idname = "FONT_OT_move";
- /* api callbacks */
- ot->exec = move_exec;
- ot->poll = ED_operator_editfont;
+ /* api callbacks */
+ ot->exec = move_exec;
+ ot->poll = ED_operator_editfont;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_enum(ot->srna, "type", move_type_items, LINE_BEGIN, "Type", "Where to move cursor to");
+ /* properties */
+ RNA_def_enum(ot->srna, "type", move_type_items, LINE_BEGIN, "Type", "Where to move cursor to");
}
/******************* move select operator ********************/
static int move_select_exec(bContext *C, wmOperator *op)
{
- int type = RNA_enum_get(op->ptr, "type");
+ int type = RNA_enum_get(op->ptr, "type");
- return move_cursor(C, type, true);
+ return move_cursor(C, type, true);
}
void FONT_OT_move_select(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Move Select";
- ot->description = "Move the cursor while selecting";
- ot->idname = "FONT_OT_move_select";
-
- /* api callbacks */
- ot->exec = move_select_exec;
- ot->poll = ED_operator_editfont;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_enum(ot->srna, "type", move_type_items, LINE_BEGIN, "Type", "Where to move cursor to, to make a selection");
+ /* identifiers */
+ ot->name = "Move Select";
+ ot->description = "Move the cursor while selecting";
+ ot->idname = "FONT_OT_move_select";
+
+ /* api callbacks */
+ ot->exec = move_select_exec;
+ ot->poll = ED_operator_editfont;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(ot->srna,
+ "type",
+ move_type_items,
+ LINE_BEGIN,
+ "Type",
+ "Where to move cursor to, to make a selection");
}
/************************* change spacing **********************/
static int change_spacing_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- int kern, delta = RNA_int_get(op->ptr, "delta");
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ int kern, delta = RNA_int_get(op->ptr, "delta");
- kern = ef->textbufinfo[ef->pos - 1].kern;
- kern += delta;
- CLAMP(kern, -20, 20);
+ kern = ef->textbufinfo[ef->pos - 1].kern;
+ kern += delta;
+ CLAMP(kern, -20, 20);
- if (ef->textbufinfo[ef->pos - 1].kern == kern) {
- return OPERATOR_CANCELLED;
- }
+ if (ef->textbufinfo[ef->pos - 1].kern == kern) {
+ return OPERATOR_CANCELLED;
+ }
- ef->textbufinfo[ef->pos - 1].kern = kern;
+ ef->textbufinfo[ef->pos - 1].kern = kern;
- text_update_edited(C, obedit, FO_EDIT);
+ text_update_edited(C, obedit, FO_EDIT);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void FONT_OT_change_spacing(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Change Spacing";
- ot->description = "Change font spacing";
- ot->idname = "FONT_OT_change_spacing";
-
- /* api callbacks */
- ot->exec = change_spacing_exec;
- ot->poll = ED_operator_editfont;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_int(ot->srna, "delta", 1, -20, 20, "Delta", "Amount to decrease or increase character spacing with", -20, 20);
+ /* identifiers */
+ ot->name = "Change Spacing";
+ ot->description = "Change font spacing";
+ ot->idname = "FONT_OT_change_spacing";
+
+ /* api callbacks */
+ ot->exec = change_spacing_exec;
+ ot->poll = ED_operator_editfont;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_int(ot->srna,
+ "delta",
+ 1,
+ -20,
+ 20,
+ "Delta",
+ "Amount to decrease or increase character spacing with",
+ -20,
+ 20);
}
/************************* change character **********************/
static int change_character_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- int character, delta = RNA_int_get(op->ptr, "delta");
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ int character, delta = RNA_int_get(op->ptr, "delta");
- if (ef->pos <= 0) {
- return OPERATOR_CANCELLED;
- }
+ if (ef->pos <= 0) {
+ return OPERATOR_CANCELLED;
+ }
- character = ef->textbuf[ef->pos - 1];
- character += delta;
- CLAMP(character, 0, 255);
+ character = ef->textbuf[ef->pos - 1];
+ character += delta;
+ CLAMP(character, 0, 255);
- if (character == ef->textbuf[ef->pos - 1]) {
- return OPERATOR_CANCELLED;
- }
+ if (character == ef->textbuf[ef->pos - 1]) {
+ return OPERATOR_CANCELLED;
+ }
- ef->textbuf[ef->pos - 1] = character;
+ ef->textbuf[ef->pos - 1] = character;
- text_update_edited(C, obedit, FO_EDIT);
+ text_update_edited(C, obedit, FO_EDIT);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void FONT_OT_change_character(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Change Character";
- ot->description = "Change font character code";
- ot->idname = "FONT_OT_change_character";
-
- /* api callbacks */
- ot->exec = change_character_exec;
- ot->poll = ED_operator_editfont;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_int(ot->srna, "delta", 1, -255, 255, "Delta", "Number to increase or decrease character code with", -255, 255);
+ /* identifiers */
+ ot->name = "Change Character";
+ ot->description = "Change font character code";
+ ot->idname = "FONT_OT_change_character";
+
+ /* api callbacks */
+ ot->exec = change_character_exec;
+ ot->poll = ED_operator_editfont;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_int(ot->srna,
+ "delta",
+ 1,
+ -255,
+ 255,
+ "Delta",
+ "Number to increase or decrease character code with",
+ -255,
+ 255);
}
/******************* line break operator ********************/
static int line_break_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
- insert_into_textbuf(obedit, '\n');
+ insert_into_textbuf(obedit, '\n');
- ef->selstart = ef->selend = 0;
+ ef->selstart = ef->selend = 0;
- text_update_edited(C, obedit, FO_EDIT);
+ text_update_edited(C, obedit, FO_EDIT);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void FONT_OT_line_break(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Line Break";
- ot->description = "Insert line break at cursor position";
- ot->idname = "FONT_OT_line_break";
+ /* identifiers */
+ ot->name = "Line Break";
+ ot->description = "Insert line break at cursor position";
+ ot->idname = "FONT_OT_line_break";
- /* api callbacks */
- ot->exec = line_break_exec;
- ot->poll = ED_operator_editfont;
+ /* api callbacks */
+ ot->exec = line_break_exec;
+ ot->poll = ED_operator_editfont;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/******************* delete operator **********************/
static const EnumPropertyItem delete_type_items[] = {
- {DEL_NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
- {DEL_PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
- {DEL_NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
- {DEL_PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
- {DEL_SELECTION, "SELECTION", 0, "Selection", ""},
- {DEL_NEXT_SEL, "NEXT_OR_SELECTION", 0, "Next or Selection", ""},
- {DEL_PREV_SEL, "PREVIOUS_OR_SELECTION", 0, "Previous or Selection", ""},
- {0, NULL, 0, NULL, NULL},
+ {DEL_NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
+ {DEL_PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
+ {DEL_NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
+ {DEL_PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
+ {DEL_SELECTION, "SELECTION", 0, "Selection", ""},
+ {DEL_NEXT_SEL, "NEXT_OR_SELECTION", 0, "Next or Selection", ""},
+ {DEL_PREV_SEL, "PREVIOUS_OR_SELECTION", 0, "Previous or Selection", ""},
+ {0, NULL, 0, NULL, NULL},
};
static int delete_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- int selstart, selend, type = RNA_enum_get(op->ptr, "type");
- int range[2] = {0, 0};
- bool has_select = false;
-
- if (ef->len == 0) {
- return OPERATOR_CANCELLED;
- }
-
- if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
- if (type == DEL_NEXT_SEL) {
- type = DEL_SELECTION;
- }
- else if (type == DEL_PREV_SEL) {
- type = DEL_SELECTION;
- }
- has_select = true;
- }
- else {
- if (type == DEL_NEXT_SEL) {
- type = DEL_NEXT_CHAR;
- }
- else if (type == DEL_PREV_SEL) {
- type = DEL_PREV_CHAR;
- }
- }
-
- switch (type) {
- case DEL_SELECTION:
- if (!kill_selection(obedit, 0)) {
- return OPERATOR_CANCELLED;
- }
- break;
- case DEL_PREV_CHAR:
- if (ef->pos <= 0) {
- return OPERATOR_CANCELLED;
- }
-
- range[0] = ef->pos - 1;
- range[1] = ef->pos;
-
- ef->pos--;
- break;
- case DEL_NEXT_CHAR:
- if (ef->pos >= ef->len) {
- return OPERATOR_CANCELLED;
- }
-
- range[0] = ef->pos;
- range[1] = ef->pos + 1;
- break;
- case DEL_NEXT_WORD:
- {
- int pos = ef->pos;
- BLI_str_cursor_step_wchar(ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
- range[0] = ef->pos;
- range[1] = pos;
- break;
- }
-
- case DEL_PREV_WORD:
- {
- int pos = ef->pos;
- BLI_str_cursor_step_wchar(ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
- range[0] = pos;
- range[1] = ef->pos;
- ef->pos = pos;
- break;
- }
- default:
- return OPERATOR_CANCELLED;
- }
-
- if (range[0] != range[1]) {
- BLI_assert(range[0] < range[1]);
- int len_remove = range[1] - range[0];
- int len_tail = ef->len - range[1];
- if (has_select) {
- for (int i = 0; i < 2; i++) {
- int *sel = i ? &ef->selend : &ef->selstart;
- if (*sel <= range[0]) {
- /* pass */
- }
- else if (*sel >= range[1]) {
- *sel -= len_remove;
- }
- else if (*sel < range[1]) {
- /* pass */
- *sel = range[0];
- }
- }
- }
-
- memmove(&ef->textbuf[range[0]], &ef->textbuf[range[1]], sizeof(*ef->textbuf) * len_tail);
- memmove(&ef->textbufinfo[range[0]], &ef->textbufinfo[range[1]], sizeof(*ef->textbufinfo) * len_tail);
-
- ef->len -= len_remove;
- ef->textbuf[ef->len] = '\0';
-
- BKE_vfont_select_clamp(obedit);
- }
-
- text_update_edited(C, obedit, FO_EDIT);
-
- return OPERATOR_FINISHED;
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ int selstart, selend, type = RNA_enum_get(op->ptr, "type");
+ int range[2] = {0, 0};
+ bool has_select = false;
+
+ if (ef->len == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
+ if (type == DEL_NEXT_SEL) {
+ type = DEL_SELECTION;
+ }
+ else if (type == DEL_PREV_SEL) {
+ type = DEL_SELECTION;
+ }
+ has_select = true;
+ }
+ else {
+ if (type == DEL_NEXT_SEL) {
+ type = DEL_NEXT_CHAR;
+ }
+ else if (type == DEL_PREV_SEL) {
+ type = DEL_PREV_CHAR;
+ }
+ }
+
+ switch (type) {
+ case DEL_SELECTION:
+ if (!kill_selection(obedit, 0)) {
+ return OPERATOR_CANCELLED;
+ }
+ break;
+ case DEL_PREV_CHAR:
+ if (ef->pos <= 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ range[0] = ef->pos - 1;
+ range[1] = ef->pos;
+
+ ef->pos--;
+ break;
+ case DEL_NEXT_CHAR:
+ if (ef->pos >= ef->len) {
+ return OPERATOR_CANCELLED;
+ }
+
+ range[0] = ef->pos;
+ range[1] = ef->pos + 1;
+ break;
+ case DEL_NEXT_WORD: {
+ int pos = ef->pos;
+ BLI_str_cursor_step_wchar(
+ ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
+ range[0] = ef->pos;
+ range[1] = pos;
+ break;
+ }
+
+ case DEL_PREV_WORD: {
+ int pos = ef->pos;
+ BLI_str_cursor_step_wchar(
+ ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
+ range[0] = pos;
+ range[1] = ef->pos;
+ ef->pos = pos;
+ break;
+ }
+ default:
+ return OPERATOR_CANCELLED;
+ }
+
+ if (range[0] != range[1]) {
+ BLI_assert(range[0] < range[1]);
+ int len_remove = range[1] - range[0];
+ int len_tail = ef->len - range[1];
+ if (has_select) {
+ for (int i = 0; i < 2; i++) {
+ int *sel = i ? &ef->selend : &ef->selstart;
+ if (*sel <= range[0]) {
+ /* pass */
+ }
+ else if (*sel >= range[1]) {
+ *sel -= len_remove;
+ }
+ else if (*sel < range[1]) {
+ /* pass */
+ *sel = range[0];
+ }
+ }
+ }
+
+ memmove(&ef->textbuf[range[0]], &ef->textbuf[range[1]], sizeof(*ef->textbuf) * len_tail);
+ memmove(&ef->textbufinfo[range[0]],
+ &ef->textbufinfo[range[1]],
+ sizeof(*ef->textbufinfo) * len_tail);
+
+ ef->len -= len_remove;
+ ef->textbuf[ef->len] = '\0';
+
+ BKE_vfont_select_clamp(obedit);
+ }
+
+ text_update_edited(C, obedit, FO_EDIT);
+
+ return OPERATOR_FINISHED;
}
void FONT_OT_delete(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete";
- ot->description = "Delete text by cursor position";
- ot->idname = "FONT_OT_delete";
-
- /* api callbacks */
- ot->exec = delete_exec;
- ot->poll = ED_operator_editfont;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_enum(ot->srna, "type", delete_type_items, DEL_PREV_CHAR, "Type", "Which part of the text to delete");
+ /* identifiers */
+ ot->name = "Delete";
+ ot->description = "Delete text by cursor position";
+ ot->idname = "FONT_OT_delete";
+
+ /* api callbacks */
+ ot->exec = delete_exec;
+ ot->poll = ED_operator_editfont;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(ot->srna,
+ "type",
+ delete_type_items,
+ DEL_PREV_CHAR,
+ "Type",
+ "Which part of the text to delete");
}
/*********************** insert text operator *************************/
static int insert_text_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- char *inserted_utf8;
- wchar_t *inserted_text;
- int a, len;
+ Object *obedit = CTX_data_edit_object(C);
+ char *inserted_utf8;
+ wchar_t *inserted_text;
+ int a, len;
- if (!RNA_struct_property_is_set(op->ptr, "text")) {
- return OPERATOR_CANCELLED;
- }
+ if (!RNA_struct_property_is_set(op->ptr, "text")) {
+ return OPERATOR_CANCELLED;
+ }
- inserted_utf8 = RNA_string_get_alloc(op->ptr, "text", NULL, 0);
- len = BLI_strlen_utf8(inserted_utf8);
+ inserted_utf8 = RNA_string_get_alloc(op->ptr, "text", NULL, 0);
+ len = BLI_strlen_utf8(inserted_utf8);
- inserted_text = MEM_callocN(sizeof(wchar_t) * (len + 1), "FONT_insert_text");
- BLI_strncpy_wchar_from_utf8(inserted_text, inserted_utf8, len + 1);
+ inserted_text = MEM_callocN(sizeof(wchar_t) * (len + 1), "FONT_insert_text");
+ BLI_strncpy_wchar_from_utf8(inserted_text, inserted_utf8, len + 1);
- for (a = 0; a < len; a++) {
- insert_into_textbuf(obedit, inserted_text[a]);
- }
+ for (a = 0; a < len; a++) {
+ insert_into_textbuf(obedit, inserted_text[a]);
+ }
- MEM_freeN(inserted_text);
- MEM_freeN(inserted_utf8);
+ MEM_freeN(inserted_text);
+ MEM_freeN(inserted_utf8);
- kill_selection(obedit, 1);
- text_update_edited(C, obedit, FO_EDIT);
+ kill_selection(obedit, 1);
+ text_update_edited(C, obedit, FO_EDIT);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- static int accentcode = 0;
- uintptr_t ascii = event->ascii;
- int alt = event->alt, shift = event->shift, ctrl = event->ctrl;
- int event_type = event->type, event_val = event->val;
- wchar_t inserted_text[2] = {0};
-
- if (RNA_struct_property_is_set(op->ptr, "text")) {
- return insert_text_exec(C, op);
- }
-
- if (RNA_struct_property_is_set(op->ptr, "accent")) {
- if (ef->len != 0 && ef->pos > 0) {
- accentcode = 1;
- }
- return OPERATOR_FINISHED;
- }
-
- /* tab should exit editmode, but we allow it to be typed using modifier keys */
- if (event_type == TABKEY) {
- if ((alt || ctrl || shift) == 0) {
- return OPERATOR_PASS_THROUGH;
- }
- else {
- ascii = 9;
- }
- }
-
- if (event_type == BACKSPACEKEY) {
- if (alt && ef->len != 0 && ef->pos > 0) {
- accentcode = 1;
- }
- return OPERATOR_PASS_THROUGH;
- }
-
- if (event_val && (ascii || event->utf8_buf[0])) {
- /* handle case like TAB (== 9) */
- if ( (ascii > 31 && ascii < 254 && ascii != 127) ||
- (ascii == 13) ||
- (ascii == 10) ||
- (ascii == 8) ||
- (event->utf8_buf[0]))
- {
-
- if (accentcode) {
- if (ef->pos > 0) {
- inserted_text[0] = findaccent(ef->textbuf[ef->pos - 1], ascii);
- ef->textbuf[ef->pos - 1] = inserted_text[0];
- }
- accentcode = 0;
- }
- else if (event->utf8_buf[0]) {
- inserted_text[0] = BLI_str_utf8_as_unicode(event->utf8_buf);
- ascii = inserted_text[0];
- insert_into_textbuf(obedit, ascii);
- accentcode = 0;
- }
- else if (ascii) {
- insert_into_textbuf(obedit, ascii);
- accentcode = 0;
- }
- else {
- BLI_assert(0);
- }
-
- kill_selection(obedit, 1);
- text_update_edited(C, obedit, FO_EDIT);
- }
- else {
- inserted_text[0] = ascii;
- insert_into_textbuf(obedit, ascii);
- text_update_edited(C, obedit, FO_EDIT);
- }
- }
- else {
- return OPERATOR_PASS_THROUGH;
- }
-
- if (inserted_text[0]) {
- /* store as utf8 in RNA string */
- char inserted_utf8[8] = {0};
-
- BLI_strncpy_wchar_as_utf8(inserted_utf8, inserted_text, sizeof(inserted_utf8));
- RNA_string_set(op->ptr, "text", inserted_utf8);
- }
-
- /* reset property? */
- if (event_val == 0) {
- accentcode = 0;
- }
-
- return OPERATOR_FINISHED;
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ static int accentcode = 0;
+ uintptr_t ascii = event->ascii;
+ int alt = event->alt, shift = event->shift, ctrl = event->ctrl;
+ int event_type = event->type, event_val = event->val;
+ wchar_t inserted_text[2] = {0};
+
+ if (RNA_struct_property_is_set(op->ptr, "text")) {
+ return insert_text_exec(C, op);
+ }
+
+ if (RNA_struct_property_is_set(op->ptr, "accent")) {
+ if (ef->len != 0 && ef->pos > 0) {
+ accentcode = 1;
+ }
+ return OPERATOR_FINISHED;
+ }
+
+ /* tab should exit editmode, but we allow it to be typed using modifier keys */
+ if (event_type == TABKEY) {
+ if ((alt || ctrl || shift) == 0) {
+ return OPERATOR_PASS_THROUGH;
+ }
+ else {
+ ascii = 9;
+ }
+ }
+
+ if (event_type == BACKSPACEKEY) {
+ if (alt && ef->len != 0 && ef->pos > 0) {
+ accentcode = 1;
+ }
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ if (event_val && (ascii || event->utf8_buf[0])) {
+ /* handle case like TAB (== 9) */
+ if ((ascii > 31 && ascii < 254 && ascii != 127) || (ascii == 13) || (ascii == 10) ||
+ (ascii == 8) || (event->utf8_buf[0])) {
+
+ if (accentcode) {
+ if (ef->pos > 0) {
+ inserted_text[0] = findaccent(ef->textbuf[ef->pos - 1], ascii);
+ ef->textbuf[ef->pos - 1] = inserted_text[0];
+ }
+ accentcode = 0;
+ }
+ else if (event->utf8_buf[0]) {
+ inserted_text[0] = BLI_str_utf8_as_unicode(event->utf8_buf);
+ ascii = inserted_text[0];
+ insert_into_textbuf(obedit, ascii);
+ accentcode = 0;
+ }
+ else if (ascii) {
+ insert_into_textbuf(obedit, ascii);
+ accentcode = 0;
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ kill_selection(obedit, 1);
+ text_update_edited(C, obedit, FO_EDIT);
+ }
+ else {
+ inserted_text[0] = ascii;
+ insert_into_textbuf(obedit, ascii);
+ text_update_edited(C, obedit, FO_EDIT);
+ }
+ }
+ else {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ if (inserted_text[0]) {
+ /* store as utf8 in RNA string */
+ char inserted_utf8[8] = {0};
+
+ BLI_strncpy_wchar_as_utf8(inserted_utf8, inserted_text, sizeof(inserted_utf8));
+ RNA_string_set(op->ptr, "text", inserted_utf8);
+ }
+
+ /* reset property? */
+ if (event_val == 0) {
+ accentcode = 0;
+ }
+
+ return OPERATOR_FINISHED;
}
void FONT_OT_text_insert(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Insert Text";
- ot->description = "Insert text at cursor position";
- ot->idname = "FONT_OT_text_insert";
-
- /* api callbacks */
- ot->exec = insert_text_exec;
- ot->invoke = insert_text_invoke;
- ot->poll = ED_operator_editfont;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-
- /* properties */
- RNA_def_string(ot->srna, "text", NULL, 0, "Text", "Text to insert at the cursor position");
- RNA_def_boolean(ot->srna, "accent", 0, "Accent mode", "Next typed character will strike through previous, for special character input");
+ /* identifiers */
+ ot->name = "Insert Text";
+ ot->description = "Insert text at cursor position";
+ ot->idname = "FONT_OT_text_insert";
+
+ /* api callbacks */
+ ot->exec = insert_text_exec;
+ ot->invoke = insert_text_invoke;
+ ot->poll = ED_operator_editfont;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_string(ot->srna, "text", NULL, 0, "Text", "Text to insert at the cursor position");
+ RNA_def_boolean(
+ ot->srna,
+ "accent",
+ 0,
+ "Accent mode",
+ "Next typed character will strike through previous, for special character input");
}
-
/*********************** textbox add operator *************************/
static int textbox_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_active_object(C);
- Curve *cu = obedit->data;
- int i;
-
- if (cu->totbox < 256) {
- for (i = cu->totbox; i > cu->actbox; i--) {
- cu->tb[i] = cu->tb[i - 1];
- }
- cu->tb[cu->actbox] = cu->tb[cu->actbox - 1];
- cu->actbox++;
- cu->totbox++;
- }
-
- DEG_id_tag_update(obedit->data, 0);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- return OPERATOR_FINISHED;
+ Object *obedit = CTX_data_active_object(C);
+ Curve *cu = obedit->data;
+ int i;
+
+ if (cu->totbox < 256) {
+ for (i = cu->totbox; i > cu->actbox; i--) {
+ cu->tb[i] = cu->tb[i - 1];
+ }
+ cu->tb[cu->actbox] = cu->tb[cu->actbox - 1];
+ cu->actbox++;
+ cu->totbox++;
+ }
+
+ DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ return OPERATOR_FINISHED;
}
void FONT_OT_textbox_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Textbox";
- ot->description = "Add a new text box";
- ot->idname = "FONT_OT_textbox_add";
-
- /* api callbacks */
- ot->exec = textbox_add_exec;
- ot->poll = ED_operator_object_active_editable_font;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* identifiers */
+ ot->name = "Add Textbox";
+ ot->description = "Add a new text box";
+ ot->idname = "FONT_OT_textbox_add";
+ /* api callbacks */
+ ot->exec = textbox_add_exec;
+ ot->poll = ED_operator_object_active_editable_font;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
-
/*********************** textbox remove operator *************************/
-
-
static int textbox_remove_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_active_object(C);
- Curve *cu = obedit->data;
- int i;
- int index = RNA_int_get(op->ptr, "index");
-
-
- if (cu->totbox > 1) {
- for (i = index; i < cu->totbox; i++) {
- cu->tb[i] = cu->tb[i + 1];
- }
- cu->totbox--;
- if (cu->actbox >= index) {
- cu->actbox--;
- }
- }
-
- DEG_id_tag_update(obedit->data, 0);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
-
- return OPERATOR_FINISHED;
+ Object *obedit = CTX_data_active_object(C);
+ Curve *cu = obedit->data;
+ int i;
+ int index = RNA_int_get(op->ptr, "index");
+
+ if (cu->totbox > 1) {
+ for (i = index; i < cu->totbox; i++) {
+ cu->tb[i] = cu->tb[i + 1];
+ }
+ cu->totbox--;
+ if (cu->actbox >= index) {
+ cu->actbox--;
+ }
+ }
+
+ DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+
+ return OPERATOR_FINISHED;
}
void FONT_OT_textbox_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Textbox";
- ot->description = "Remove the textbox";
- ot->idname = "FONT_OT_textbox_remove";
+ /* identifiers */
+ ot->name = "Remove Textbox";
+ ot->description = "Remove the textbox";
+ ot->idname = "FONT_OT_textbox_remove";
- /* api callbacks */
- ot->exec = textbox_remove_exec;
- ot->poll = ED_operator_object_active_editable_font;
+ /* api callbacks */
+ ot->exec = textbox_remove_exec;
+ ot->poll = ED_operator_object_active_editable_font;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "The current text box", 0, INT_MAX);
+ RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "The current text box", 0, INT_MAX);
}
-
-
/***************** editmode enter/exit ********************/
void ED_curve_editfont_make(Object *obedit)
{
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- int len_wchar;
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ int len_wchar;
- if (ef == NULL) {
- ef = cu->editfont = MEM_callocN(sizeof(EditFont), "editfont");
+ if (ef == NULL) {
+ ef = cu->editfont = MEM_callocN(sizeof(EditFont), "editfont");
- ef->textbuf = MEM_callocN((MAXTEXT + 4) * sizeof(wchar_t), "texteditbuf");
- ef->textbufinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "texteditbufinfo");
- }
+ ef->textbuf = MEM_callocN((MAXTEXT + 4) * sizeof(wchar_t), "texteditbuf");
+ ef->textbufinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "texteditbufinfo");
+ }
- /* Convert the original text to wchar_t */
- len_wchar = BLI_strncpy_wchar_from_utf8(ef->textbuf, cu->str, MAXTEXT + 4);
- BLI_assert(len_wchar == cu->len_wchar);
- ef->len = len_wchar;
- BLI_assert(ef->len >= 0);
+ /* Convert the original text to wchar_t */
+ len_wchar = BLI_strncpy_wchar_from_utf8(ef->textbuf, cu->str, MAXTEXT + 4);
+ BLI_assert(len_wchar == cu->len_wchar);
+ ef->len = len_wchar;
+ BLI_assert(ef->len >= 0);
- memcpy(ef->textbufinfo, cu->strinfo, ef->len * sizeof(CharInfo));
+ memcpy(ef->textbufinfo, cu->strinfo, ef->len * sizeof(CharInfo));
- if (ef->pos > ef->len) {
- ef->pos = ef->len;
- }
+ if (ef->pos > ef->len) {
+ ef->pos = ef->len;
+ }
- cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0];
+ cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0];
- /* Other vars */
- ef->pos = cu->pos;
- ef->selstart = cu->selstart;
- ef->selend = cu->selend;
+ /* Other vars */
+ ef->pos = cu->pos;
+ ef->selstart = cu->selstart;
+ ef->selend = cu->selend;
- /* text may have been modified by Python */
- BKE_vfont_select_clamp(obedit);
+ /* text may have been modified by Python */
+ BKE_vfont_select_clamp(obedit);
}
void ED_curve_editfont_load(Object *obedit)
{
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
- /* Free the old curve string */
- MEM_freeN(cu->str);
+ /* Free the old curve string */
+ MEM_freeN(cu->str);
- /* Calculate the actual string length in UTF-8 variable characters */
- cu->len_wchar = ef->len;
- cu->len = BLI_wstrlen_utf8(ef->textbuf);
+ /* Calculate the actual string length in UTF-8 variable characters */
+ cu->len_wchar = ef->len;
+ cu->len = BLI_wstrlen_utf8(ef->textbuf);
- /* Alloc memory for UTF-8 variable char length string */
- cu->str = MEM_mallocN(cu->len + sizeof(wchar_t), "str");
+ /* Alloc memory for UTF-8 variable char length string */
+ cu->str = MEM_mallocN(cu->len + sizeof(wchar_t), "str");
- /* Copy the wchar to UTF-8 */
- BLI_strncpy_wchar_as_utf8(cu->str, ef->textbuf, cu->len + 1);
+ /* Copy the wchar to UTF-8 */
+ BLI_strncpy_wchar_as_utf8(cu->str, ef->textbuf, cu->len + 1);
- if (cu->strinfo) {
- MEM_freeN(cu->strinfo);
- }
- cu->strinfo = MEM_callocN((cu->len_wchar + 4) * sizeof(CharInfo), "texteditinfo");
- memcpy(cu->strinfo, ef->textbufinfo, cu->len_wchar * sizeof(CharInfo));
+ if (cu->strinfo) {
+ MEM_freeN(cu->strinfo);
+ }
+ cu->strinfo = MEM_callocN((cu->len_wchar + 4) * sizeof(CharInfo), "texteditinfo");
+ memcpy(cu->strinfo, ef->textbufinfo, cu->len_wchar * sizeof(CharInfo));
- /* Other vars */
- cu->pos = ef->pos;
- cu->selstart = ef->selstart;
- cu->selend = ef->selend;
+ /* Other vars */
+ cu->pos = ef->pos;
+ cu->selstart = ef->selstart;
+ cu->selend = ef->selend;
}
void ED_curve_editfont_free(Object *obedit)
{
- BKE_curve_editfont_free((Curve *)obedit->data);
+ BKE_curve_editfont_free((Curve *)obedit->data);
}
/********************** set case operator *********************/
static const EnumPropertyItem case_items[] = {
- {CASE_LOWER, "LOWER", 0, "Lower", ""},
- {CASE_UPPER, "UPPER", 0, "Upper", ""},
- {0, NULL, 0, NULL, NULL},
+ {CASE_LOWER, "LOWER", 0, "Lower", ""},
+ {CASE_UPPER, "UPPER", 0, "Upper", ""},
+ {0, NULL, 0, NULL, NULL},
};
static int set_case(bContext *C, int ccase)
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- wchar_t *str;
- int len;
- int selstart, selend;
-
- if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
- len = (selend - selstart) + 1;
- str = &ef->textbuf[selstart];
- while (len) {
- if (*str >= 'a' && *str <= 'z') {
- *str -= 32;
- }
- len--;
- str++;
- }
-
- if (ccase == CASE_LOWER) {
- len = (selend - selstart) + 1;
- str = &ef->textbuf[selstart];
- while (len) {
- if (*str >= 'A' && *str <= 'Z') {
- *str += 32;
- }
- len--;
- str++;
- }
- }
-
- text_update_edited(C, obedit, FO_EDIT);
- }
-
- return OPERATOR_FINISHED;
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ wchar_t *str;
+ int len;
+ int selstart, selend;
+
+ if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
+ len = (selend - selstart) + 1;
+ str = &ef->textbuf[selstart];
+ while (len) {
+ if (*str >= 'a' && *str <= 'z') {
+ *str -= 32;
+ }
+ len--;
+ str++;
+ }
+
+ if (ccase == CASE_LOWER) {
+ len = (selend - selstart) + 1;
+ str = &ef->textbuf[selstart];
+ while (len) {
+ if (*str >= 'A' && *str <= 'Z') {
+ *str += 32;
+ }
+ len--;
+ str++;
+ }
+ }
+
+ text_update_edited(C, obedit, FO_EDIT);
+ }
+
+ return OPERATOR_FINISHED;
}
static int set_case_exec(bContext *C, wmOperator *op)
{
- return set_case(C, RNA_enum_get(op->ptr, "case"));
+ return set_case(C, RNA_enum_get(op->ptr, "case"));
}
void FONT_OT_case_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Case";
- ot->description = "Set font case";
- ot->idname = "FONT_OT_case_set";
+ /* identifiers */
+ ot->name = "Set Case";
+ ot->description = "Set font case";
+ ot->idname = "FONT_OT_case_set";
- /* api callbacks */
- ot->exec = set_case_exec;
- ot->poll = ED_operator_editfont;
+ /* api callbacks */
+ ot->exec = set_case_exec;
+ ot->poll = ED_operator_editfont;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_enum(ot->srna, "case", case_items, CASE_LOWER, "Case", "Lower or upper case");
+ /* properties */
+ RNA_def_enum(ot->srna, "case", case_items, CASE_LOWER, "Case", "Lower or upper case");
}
/********************** toggle case operator *********************/
static int toggle_case_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- wchar_t *str;
- int len, ccase = CASE_UPPER;
-
- len = wcslen(ef->textbuf);
- str = ef->textbuf;
- while (len) {
- if (*str >= 'a' && *str <= 'z') {
- ccase = CASE_LOWER;
- break;
- }
-
- len--;
- str++;
- }
-
- return set_case(C, ccase);
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ wchar_t *str;
+ int len, ccase = CASE_UPPER;
+
+ len = wcslen(ef->textbuf);
+ str = ef->textbuf;
+ while (len) {
+ if (*str >= 'a' && *str <= 'z') {
+ ccase = CASE_LOWER;
+ break;
+ }
+
+ len--;
+ str++;
+ }
+
+ return set_case(C, ccase);
}
void FONT_OT_case_toggle(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Toggle Case";
- ot->description = "Toggle font case";
- ot->idname = "FONT_OT_case_toggle";
+ /* identifiers */
+ ot->name = "Toggle Case";
+ ot->description = "Toggle font case";
+ ot->idname = "FONT_OT_case_toggle";
- /* api callbacks */
- ot->exec = toggle_case_exec;
- ot->poll = ED_operator_editfont;
+ /* api callbacks */
+ ot->exec = toggle_case_exec;
+ ot->poll = ED_operator_editfont;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* **************** Open Font ************** */
static void font_ui_template_init(bContext *C, wmOperator *op)
{
- PropertyPointerRNA *pprop;
+ PropertyPointerRNA *pprop;
- op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
- UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop);
+ op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
+ UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop);
}
static void font_open_cancel(bContext *UNUSED(C), wmOperator *op)
{
- MEM_freeN(op->customdata);
- op->customdata = NULL;
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
}
static int font_open_exec(bContext *C, wmOperator *op)
{
- struct Main *bmain = CTX_data_main(C);
- VFont *font;
- PropertyPointerRNA *pprop;
- PointerRNA idptr;
- char filepath[FILE_MAX];
- RNA_string_get(op->ptr, "filepath", filepath);
-
- font = BKE_vfont_load(bmain, filepath);
-
- if (!font) {
- if (op->customdata) {
- MEM_freeN(op->customdata);
- }
- return OPERATOR_CANCELLED;
- }
-
- if (!op->customdata) {
- font_ui_template_init(C, op);
- }
-
- /* hook into UI */
- pprop = op->customdata;
-
- if (pprop->prop) {
- /* when creating new ID blocks, use is already 1, but RNA
- * pointer use also increases user, so this compensates it */
- id_us_min(&font->id);
-
- RNA_id_pointer_create(&font->id, &idptr);
- RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
- RNA_property_update(C, &pprop->ptr, pprop->prop);
- }
-
- MEM_freeN(op->customdata);
-
- return OPERATOR_FINISHED;
+ struct Main *bmain = CTX_data_main(C);
+ VFont *font;
+ PropertyPointerRNA *pprop;
+ PointerRNA idptr;
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
+
+ font = BKE_vfont_load(bmain, filepath);
+
+ if (!font) {
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ }
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!op->customdata) {
+ font_ui_template_init(C, op);
+ }
+
+ /* hook into UI */
+ pprop = op->customdata;
+
+ if (pprop->prop) {
+ /* when creating new ID blocks, use is already 1, but RNA
+ * pointer use also increases user, so this compensates it */
+ id_us_min(&font->id);
+
+ RNA_id_pointer_create(&font->id, &idptr);
+ RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
+ RNA_property_update(C, &pprop->ptr, pprop->prop);
+ }
+
+ MEM_freeN(op->customdata);
+
+ return OPERATOR_FINISHED;
}
static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- VFont *vfont = NULL;
- const char *path;
+ VFont *vfont = NULL;
+ const char *path;
- PointerRNA idptr;
- PropertyPointerRNA *pprop;
+ PointerRNA idptr;
+ PropertyPointerRNA *pprop;
- font_ui_template_init(C, op);
+ font_ui_template_init(C, op);
- /* hook into UI */
- pprop = op->customdata;
+ /* hook into UI */
+ pprop = op->customdata;
- if (pprop->prop) {
- idptr = RNA_property_pointer_get((PointerRNA *)pprop, pprop->prop);
- vfont = idptr.id.data;
- }
+ if (pprop->prop) {
+ idptr = RNA_property_pointer_get((PointerRNA *)pprop, pprop->prop);
+ vfont = idptr.id.data;
+ }
- path = (vfont && !BKE_vfont_is_builtin(vfont)) ? vfont->name : U.fontdir;
+ path = (vfont && !BKE_vfont_is_builtin(vfont)) ? vfont->name : U.fontdir;
- if (RNA_struct_property_is_set(op->ptr, "filepath")) {
- return font_open_exec(C, op);
- }
+ if (RNA_struct_property_is_set(op->ptr, "filepath")) {
+ return font_open_exec(C, op);
+ }
- RNA_string_set(op->ptr, "filepath", path);
- WM_event_add_fileselect(C, op);
+ RNA_string_set(op->ptr, "filepath", path);
+ WM_event_add_fileselect(C, op);
- return OPERATOR_RUNNING_MODAL;
+ return OPERATOR_RUNNING_MODAL;
}
void FONT_OT_open(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Open Font";
- ot->idname = "FONT_OT_open";
- ot->description = "Load a new font from a file";
-
- /* api callbacks */
- ot->exec = font_open_exec;
- ot->invoke = open_invoke;
- ot->cancel = font_open_cancel;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- WM_operator_properties_filesel(
- ot, FILE_TYPE_FOLDER | FILE_TYPE_FTFONT, FILE_SPECIAL, FILE_OPENFILE,
- WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
+ /* identifiers */
+ ot->name = "Open Font";
+ ot->idname = "FONT_OT_open";
+ ot->description = "Load a new font from a file";
+
+ /* api callbacks */
+ ot->exec = font_open_exec;
+ ot->invoke = open_invoke;
+ ot->cancel = font_open_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_filesel(ot,
+ FILE_TYPE_FOLDER | FILE_TYPE_FTFONT,
+ FILE_SPECIAL,
+ FILE_OPENFILE,
+ WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
+ FILE_DEFAULTDISPLAY,
+ FILE_SORT_ALPHA);
}
/******************* delete operator *********************/
static int font_unlink_exec(bContext *C, wmOperator *op)
{
- VFont *builtin_font;
+ VFont *builtin_font;
- PointerRNA idptr;
- PropertyPointerRNA pprop;
+ PointerRNA idptr;
+ PropertyPointerRNA pprop;
- UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop);
+ UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop);
- if (pprop.prop == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Incorrect context for running font unlink");
- return OPERATOR_CANCELLED;
- }
+ if (pprop.prop == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Incorrect context for running font unlink");
+ return OPERATOR_CANCELLED;
+ }
- builtin_font = BKE_vfont_builtin_get();
+ builtin_font = BKE_vfont_builtin_get();
- RNA_id_pointer_create(&builtin_font->id, &idptr);
- RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr);
- RNA_property_update(C, &pprop.ptr, pprop.prop);
+ RNA_id_pointer_create(&builtin_font->id, &idptr);
+ RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr);
+ RNA_property_update(C, &pprop.ptr, pprop.prop);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void FONT_OT_unlink(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Unlink";
- ot->idname = "FONT_OT_unlink";
- ot->description = "Unlink active font data-block";
+ /* identifiers */
+ ot->name = "Unlink";
+ ot->idname = "FONT_OT_unlink";
+ ot->description = "Unlink active font data-block";
- /* api callbacks */
- ot->exec = font_unlink_exec;
+ /* api callbacks */
+ ot->exec = font_unlink_exec;
}
/**
* TextBox selection
*/
-bool ED_curve_editfont_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
+bool ED_curve_editfont_select_pick(
+ bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = obedit->data;
- ViewContext vc;
- /* bias against the active, in pixels, allows cycling */
- const float active_bias_px = 4.0f;
- const float mval_fl[2] = {UNPACK2(mval)};
- const int i_actbox = max_ii(0, cu->actbox - 1);
- int i_iter, actbox_select = -1;
- const float dist = ED_view3d_select_dist_px();
- float dist_sq_best = dist * dist;
-
- ED_view3d_viewcontext_init(C, &vc);
-
- ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
-
- /* currently only select active */
- (void)extend;
- (void)deselect;
- (void)toggle;
-
- for (i_iter = 0; i_iter < cu->totbox; i_iter++) {
- int i = (i_iter + i_actbox) % cu->totbox;
- float dist_sq_min;
- int j, j_prev;
-
- float obedit_co[4][3];
- float screen_co[4][2];
- rctf rect;
- int project_ok = 0;
-
-
- BKE_curve_rect_from_textbox(cu, &cu->tb[i], &rect);
-
- copy_v3_fl3(obedit_co[0], rect.xmin, rect.ymin, 0.0f);
- copy_v3_fl3(obedit_co[1], rect.xmin, rect.ymax, 0.0f);
- copy_v3_fl3(obedit_co[2], rect.xmax, rect.ymax, 0.0f);
- copy_v3_fl3(obedit_co[3], rect.xmax, rect.ymin, 0.0f);
-
- for (j = 0; j < 4; j++) {
- if (ED_view3d_project_float_object(vc.ar, obedit_co[j], screen_co[j],
- V3D_PROJ_TEST_CLIP_BB) == V3D_PROJ_RET_OK)
- {
- project_ok |= (1 << j);
- }
- }
-
- dist_sq_min = dist_sq_best;
- for (j = 0, j_prev = 3; j < 4; j_prev = j++) {
- if ((project_ok & (1 << j)) &&
- (project_ok & (1 << j_prev)))
- {
- const float dist_test_sq = dist_squared_to_line_segment_v2(mval_fl, screen_co[j_prev], screen_co[j]);
- if (dist_sq_min > dist_test_sq) {
- dist_sq_min = dist_test_sq;
- }
- }
- }
-
- /* bias in pixels to cycle seletion */
- if (i_iter == 0) {
- dist_sq_min += active_bias_px;
- }
-
- if (dist_sq_min < dist_sq_best) {
- dist_sq_best = dist_sq_min;
- actbox_select = i + 1;
- }
- }
-
- if (actbox_select != -1) {
- if (cu->actbox != actbox_select) {
- cu->actbox = actbox_select;
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- }
- return true;
- }
- else {
- return false;
- }
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ ViewContext vc;
+ /* bias against the active, in pixels, allows cycling */
+ const float active_bias_px = 4.0f;
+ const float mval_fl[2] = {UNPACK2(mval)};
+ const int i_actbox = max_ii(0, cu->actbox - 1);
+ int i_iter, actbox_select = -1;
+ const float dist = ED_view3d_select_dist_px();
+ float dist_sq_best = dist * dist;
+
+ ED_view3d_viewcontext_init(C, &vc);
+
+ ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
+
+ /* currently only select active */
+ (void)extend;
+ (void)deselect;
+ (void)toggle;
+
+ for (i_iter = 0; i_iter < cu->totbox; i_iter++) {
+ int i = (i_iter + i_actbox) % cu->totbox;
+ float dist_sq_min;
+ int j, j_prev;
+
+ float obedit_co[4][3];
+ float screen_co[4][2];
+ rctf rect;
+ int project_ok = 0;
+
+ BKE_curve_rect_from_textbox(cu, &cu->tb[i], &rect);
+
+ copy_v3_fl3(obedit_co[0], rect.xmin, rect.ymin, 0.0f);
+ copy_v3_fl3(obedit_co[1], rect.xmin, rect.ymax, 0.0f);
+ copy_v3_fl3(obedit_co[2], rect.xmax, rect.ymax, 0.0f);
+ copy_v3_fl3(obedit_co[3], rect.xmax, rect.ymin, 0.0f);
+
+ for (j = 0; j < 4; j++) {
+ if (ED_view3d_project_float_object(
+ vc.ar, obedit_co[j], screen_co[j], V3D_PROJ_TEST_CLIP_BB) == V3D_PROJ_RET_OK) {
+ project_ok |= (1 << j);
+ }
+ }
+
+ dist_sq_min = dist_sq_best;
+ for (j = 0, j_prev = 3; j < 4; j_prev = j++) {
+ if ((project_ok & (1 << j)) && (project_ok & (1 << j_prev))) {
+ const float dist_test_sq = dist_squared_to_line_segment_v2(
+ mval_fl, screen_co[j_prev], screen_co[j]);
+ if (dist_sq_min > dist_test_sq) {
+ dist_sq_min = dist_test_sq;
+ }
+ }
+ }
+
+ /* bias in pixels to cycle seletion */
+ if (i_iter == 0) {
+ dist_sq_min += active_bias_px;
+ }
+
+ if (dist_sq_min < dist_sq_best) {
+ dist_sq_best = dist_sq_min;
+ actbox_select = i + 1;
+ }
+ }
+
+ if (actbox_select != -1) {
+ if (cu->actbox != actbox_select) {
+ cu->actbox = actbox_select;
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
}
diff --git a/source/blender/editors/curve/editfont_undo.c b/source/blender/editors/curve/editfont_undo.c
index 13cbea77ab8..82c19db7a4a 100644
--- a/source/blender/editors/curve/editfont_undo.c
+++ b/source/blender/editors/curve/editfont_undo.c
@@ -27,7 +27,6 @@
#include "BLI_utildefines.h"
#include "BLI_array_utils.h"
-
#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -60,33 +59,32 @@
* \{ */
typedef struct UndoFont {
- wchar_t *textbuf;
- struct CharInfo *textbufinfo;
+ wchar_t *textbuf;
+ struct CharInfo *textbufinfo;
- int len, pos;
+ int len, pos;
#ifdef USE_ARRAY_STORE
- struct {
- BArrayState *textbuf;
- BArrayState *textbufinfo;
- } store;
+ struct {
+ BArrayState *textbuf;
+ BArrayState *textbufinfo;
+ } store;
#endif
- size_t undo_size;
+ size_t undo_size;
} UndoFont;
-
#ifdef USE_ARRAY_STORE
/** \name Array Store
* \{ */
static struct {
- struct BArrayStore_AtSize bs_stride;
- int users;
+ struct BArrayStore_AtSize bs_stride;
+ int users;
- /* We could have the undo API pass in the previous state, for now store a local list */
- ListBase local_links;
+ /* We could have the undo API pass in the previous state, for now store a local list */
+ ListBase local_links;
} uf_arraystore = {{NULL}};
@@ -95,33 +93,33 @@ static struct {
* 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)
+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 == NULL)); \
- if (create) { \
- BArrayState *state_reference = uf_ref ? uf_ref->store.id : NULL; \
- 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_freeN((uf)->id); \
- (uf)->id = NULL; \
- } ((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;
- }
+# define STATE_COMPACT(uf, id, len) \
+ if ((uf)->id) { \
+ BLI_assert(create == ((uf)->store.id == NULL)); \
+ if (create) { \
+ BArrayState *state_reference = uf_ref ? uf_ref->store.id : NULL; \
+ 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_freeN((uf)->id); \
+ (uf)->id = NULL; \
+ } \
+ ((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;
+ }
}
/**
@@ -129,35 +127,40 @@ static void uf_arraystore_compact_ex(
*/
static void uf_arraystore_compact(UndoFont *um, const UndoFont *uf_ref)
{
- uf_arraystore_compact_ex(um, uf_ref, true);
+ 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
+# 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
}
/**
@@ -165,156 +168,159 @@ static void uf_arraystore_compact_with_info(UndoFont *um, const UndoFont *uf_ref
*/
static void uf_arraystore_expand_clear(UndoFont *um)
{
- uf_arraystore_compact_ex(um, NULL, false);
+ uf_arraystore_compact_ex(um, NULL, 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); \
- BArrayState *state = (uf)->store.id; \
- size_t state_len; \
- (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
+# define STATE_EXPAND(uf, id, len) \
+ if ((uf)->store.id) { \
+ const size_t stride = sizeof(*(uf)->id); \
+ BArrayState *state = (uf)->store.id; \
+ size_t state_len; \
+ (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 = NULL; \
- } ((void)0)
+# 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 = NULL; \
+ } \
+ ((void)0)
- STATE_FREE(uf, textbuf);
- STATE_FREE(uf, textbufinfo);
+ STATE_FREE(uf, textbuf);
+ STATE_FREE(uf, textbufinfo);
-#undef STATE_FREE
+# undef STATE_FREE
- uf_arraystore.users -= 1;
+ uf_arraystore.users -= 1;
- BLI_assert(uf_arraystore.users >= 0);
+ BLI_assert(uf_arraystore.users >= 0);
- if (uf_arraystore.users == 0) {
-#ifdef DEBUG_PRINT
- printf("editfont undo store: freeing all data!\n");
-#endif
+ 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);
- }
+ BLI_array_store_at_size_clear(&uf_arraystore.bs_stride);
+ }
}
/** \} */
-#endif /* USE_ARRAY_STORE */
+#endif /* USE_ARRAY_STORE */
static void undofont_to_editfont(UndoFont *uf, Curve *cu)
{
- EditFont *ef = cu->editfont;
+ EditFont *ef = cu->editfont;
- size_t final_size;
+ size_t final_size;
#ifdef USE_ARRAY_STORE
- uf_arraystore_expand(uf);
+ uf_arraystore_expand(uf);
#endif
- final_size = sizeof(wchar_t) * (uf->len + 1);
- memcpy(ef->textbuf, uf->textbuf, final_size);
+ final_size = sizeof(wchar_t) * (uf->len + 1);
+ memcpy(ef->textbuf, uf->textbuf, final_size);
- final_size = sizeof(CharInfo) * (uf->len + 1);
- memcpy(ef->textbufinfo, uf->textbufinfo, final_size);
+ final_size = sizeof(CharInfo) * (uf->len + 1);
+ memcpy(ef->textbufinfo, uf->textbufinfo, final_size);
- ef->pos = uf->pos;
- ef->len = uf->len;
+ ef->pos = uf->pos;
+ ef->len = uf->len;
- ef->selstart = ef->selend = 0;
+ ef->selstart = ef->selend = 0;
#ifdef USE_ARRAY_STORE
- uf_arraystore_expand_clear(uf);
+ uf_arraystore_expand_clear(uf);
#endif
}
static void *undofont_from_editfont(UndoFont *uf, Curve *cu)
{
- BLI_assert(BLI_array_is_zeroed(uf, 1));
+ BLI_assert(BLI_array_is_zeroed(uf, 1));
- EditFont *ef = cu->editfont;
+ EditFont *ef = cu->editfont;
- size_t mem_used_prev = MEM_get_memory_in_use();
+ size_t mem_used_prev = MEM_get_memory_in_use();
- size_t final_size;
+ size_t final_size;
- final_size = sizeof(wchar_t) * (ef->len + 1);
- uf->textbuf = MEM_mallocN(final_size, __func__);
- memcpy(uf->textbuf, ef->textbuf, final_size);
+ final_size = sizeof(wchar_t) * (ef->len + 1);
+ uf->textbuf = MEM_mallocN(final_size, __func__);
+ memcpy(uf->textbuf, ef->textbuf, final_size);
- final_size = sizeof(CharInfo) * (ef->len + 1);
- uf->textbufinfo = MEM_mallocN(final_size, __func__);
- memcpy(uf->textbufinfo, ef->textbufinfo, final_size);
+ final_size = sizeof(CharInfo) * (ef->len + 1);
+ uf->textbufinfo = MEM_mallocN(final_size, __func__);
+ memcpy(uf->textbufinfo, ef->textbufinfo, final_size);
- uf->pos = ef->pos;
- uf->len = ef->len;
+ uf->pos = ef->pos;
+ uf->len = ef->len;
#ifdef USE_ARRAY_STORE
- {
- const UndoFont *uf_ref = uf_arraystore.local_links.last ?
- ((LinkData *)uf_arraystore.local_links.last)->data : NULL;
+ {
+ const UndoFont *uf_ref = uf_arraystore.local_links.last ?
+ ((LinkData *)uf_arraystore.local_links.last)->data :
+ NULL;
- /* add oursrlves */
- BLI_addtail(&uf_arraystore.local_links, BLI_genericNodeN(uf));
+ /* add oursrlves */
+ BLI_addtail(&uf_arraystore.local_links, BLI_genericNodeN(uf));
- uf_arraystore_compact_with_info(uf, uf_ref);
- }
+ uf_arraystore_compact_with_info(uf, uf_ref);
+ }
#endif
- size_t mem_used_curr = MEM_get_memory_in_use();
+ 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);
+ uf->undo_size = mem_used_prev < mem_used_curr ? mem_used_curr - mem_used_prev : sizeof(UndoFont);
- return uf;
+ return uf;
}
static void undofont_free_data(UndoFont *uf)
{
#ifdef USE_ARRAY_STORE
- {
- LinkData *link = BLI_findptr(&uf_arraystore.local_links, uf, offsetof(LinkData, data));
- BLI_remlink(&uf_arraystore.local_links, link);
- MEM_freeN(link);
- }
- uf_arraystore_free(uf);
+ {
+ LinkData *link = BLI_findptr(&uf_arraystore.local_links, uf, offsetof(LinkData, data));
+ BLI_remlink(&uf_arraystore.local_links, link);
+ MEM_freeN(link);
+ }
+ uf_arraystore_free(uf);
#endif
- if (uf->textbuf) {
- MEM_freeN(uf->textbuf);
- }
- if (uf->textbufinfo) {
- MEM_freeN(uf->textbufinfo);
- }
+ if (uf->textbuf) {
+ MEM_freeN(uf->textbuf);
+ }
+ if (uf->textbufinfo) {
+ MEM_freeN(uf->textbufinfo);
+ }
}
static Object *editfont_object_from_context(bContext *C)
{
- Object *obedit = CTX_data_edit_object(C);
- if (obedit && obedit->type == OB_FONT) {
- Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- if (ef != NULL) {
- return obedit;
- }
- }
- return NULL;
+ Object *obedit = CTX_data_edit_object(C);
+ if (obedit && obedit->type == OB_FONT) {
+ Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
+ if (ef != NULL) {
+ return obedit;
+ }
+ }
+ return NULL;
}
/** \} */
@@ -324,68 +330,74 @@ static Object *editfont_object_from_context(bContext *C)
* \{ */
typedef struct FontUndoStep {
- UndoStep step;
- /* note: will split out into list for multi-object-editmode. */
- UndoRefID_Object obedit_ref;
- UndoFont data;
+ UndoStep step;
+ /* note: will split out into list for multi-object-editmode. */
+ UndoRefID_Object obedit_ref;
+ UndoFont data;
} FontUndoStep;
static bool font_undosys_poll(bContext *C)
{
- return editfont_object_from_context(C) != NULL;
+ return editfont_object_from_context(C) != NULL;
}
-static bool font_undosys_step_encode(struct bContext *C, struct Main *UNUSED(bmain), UndoStep *us_p)
+static bool font_undosys_step_encode(struct bContext *C,
+ struct Main *UNUSED(bmain),
+ UndoStep *us_p)
{
- FontUndoStep *us = (FontUndoStep *)us_p;
- us->obedit_ref.ptr = editfont_object_from_context(C);
- Curve *cu = us->obedit_ref.ptr->data;
- undofont_from_editfont(&us->data, cu);
- us->step.data_size = us->data.undo_size;
- return true;
+ FontUndoStep *us = (FontUndoStep *)us_p;
+ us->obedit_ref.ptr = editfont_object_from_context(C);
+ Curve *cu = us->obedit_ref.ptr->data;
+ undofont_from_editfont(&us->data, cu);
+ us->step.data_size = us->data.undo_size;
+ return true;
}
-static void font_undosys_step_decode(struct bContext *C, struct Main *UNUSED(bmain), UndoStep *us_p, int UNUSED(dir))
+static void font_undosys_step_decode(struct bContext *C,
+ struct Main *UNUSED(bmain),
+ UndoStep *us_p,
+ int UNUSED(dir))
{
- /* TODO(campbell): undo_system: use low-level API to set mode. */
- ED_object_mode_set(C, OB_MODE_EDIT);
- BLI_assert(font_undosys_poll(C));
-
- FontUndoStep *us = (FontUndoStep *)us_p;
- Object *obedit = us->obedit_ref.ptr;
- Curve *cu = obedit->data;
- undofont_to_editfont(&us->data, cu);
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
+ /* TODO(campbell): undo_system: use low-level API to set mode. */
+ ED_object_mode_set(C, OB_MODE_EDIT);
+ BLI_assert(font_undosys_poll(C));
+
+ FontUndoStep *us = (FontUndoStep *)us_p;
+ Object *obedit = us->obedit_ref.ptr;
+ Curve *cu = obedit->data;
+ undofont_to_editfont(&us->data, cu);
+ DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
static void font_undosys_step_free(UndoStep *us_p)
{
- FontUndoStep *us = (FontUndoStep *)us_p;
- undofont_free_data(&us->data);
+ FontUndoStep *us = (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)
+static void font_undosys_foreach_ID_ref(UndoStep *us_p,
+ UndoTypeForEachIDRefFn foreach_ID_ref_fn,
+ void *user_data)
{
- FontUndoStep *us = (FontUndoStep *)us_p;
- foreach_ID_ref_fn(user_data, ((UndoRefID *)&us->obedit_ref));
+ FontUndoStep *us = (FontUndoStep *)us_p;
+ foreach_ID_ref_fn(user_data, ((UndoRefID *)&us->obedit_ref));
}
/* Export for ED_undo_sys. */
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->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->step_foreach_ID_ref = font_undosys_foreach_ID_ref;
- ut->use_context = true;
+ ut->use_context = true;
- ut->step_size = sizeof(FontUndoStep);
+ ut->step_size = sizeof(FontUndoStep);
}
/** \} */