Blender  V2.93
editmesh_extrude_spin.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2004 by Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "DNA_object_types.h"
25 
26 #include "BLI_math.h"
27 #include "BLI_string.h"
28 
29 #include "BKE_context.h"
30 #include "BKE_editmesh.h"
31 #include "BKE_layer.h"
32 #include "BKE_report.h"
33 
34 #include "RNA_access.h"
35 #include "RNA_define.h"
36 
37 #include "WM_types.h"
38 
39 #include "ED_mesh.h"
40 #include "ED_screen.h"
41 #include "ED_view3d.h"
42 
43 #include "MEM_guardedalloc.h"
44 
45 #include "mesh_intern.h" /* own include */
46 
47 #define USE_GIZMO
48 
49 /* -------------------------------------------------------------------- */
54 {
55  ViewLayer *view_layer = CTX_data_view_layer(C);
56  float cent[3], axis[3];
57  const float d[3] = {0.0f, 0.0f, 0.0f};
58 
59  RNA_float_get_array(op->ptr, "center", cent);
60  RNA_float_get_array(op->ptr, "axis", axis);
61  const int steps = RNA_int_get(op->ptr, "steps");
62  const float angle = RNA_float_get(op->ptr, "angle");
63  const bool use_normal_flip = RNA_boolean_get(op->ptr, "use_normal_flip");
64  const bool dupli = RNA_boolean_get(op->ptr, "dupli");
65  const bool use_auto_merge = (RNA_boolean_get(op->ptr, "use_auto_merge") && (dupli == false) &&
66  (steps >= 3) && fabsf((fabsf(angle) - (float)(M_PI * 2))) <= 1e-6f);
67 
68  if (is_zero_v3(axis)) {
69  BKE_report(op->reports, RPT_ERROR, "Invalid/unset axis");
70  return OPERATOR_CANCELLED;
71  }
72 
73  uint objects_len = 0;
75  view_layer, CTX_wm_view3d(C), &objects_len);
76 
77  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
78  Object *obedit = objects[ob_index];
80  BMesh *bm = em->bm;
81  BMOperator spinop;
82 
83  /* keep the values in worldspace since we're passing the obmat */
84  if (!EDBM_op_init(em,
85  &spinop,
86  op,
87  "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 "
88  "use_normal_flip=%b use_duplicate=%b use_merge=%b",
90  cent,
91  axis,
92  d,
93  steps,
94  -angle,
95  obedit->obmat,
96  use_normal_flip,
97  dupli,
98  use_auto_merge)) {
99  continue;
100  }
101  BMO_op_exec(bm, &spinop);
102  if (use_auto_merge == false) {
105  bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true);
106  }
107  if (!EDBM_op_finish(em, &spinop, op, true)) {
108  continue;
109  }
110 
111  EDBM_update_generic(obedit->data, true, true);
112  }
113 
114  MEM_freeN(objects);
115 
116  return OPERATOR_FINISHED;
117 }
118 
119 /* get center and axis, in global coords */
120 static int edbm_spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
121 {
123  View3D *v3d = CTX_wm_view3d(C);
125 
126  PropertyRNA *prop;
127  prop = RNA_struct_find_property(op->ptr, "center");
128  if (!RNA_property_is_set(op->ptr, prop)) {
130  }
131  if (rv3d) {
132  prop = RNA_struct_find_property(op->ptr, "axis");
133  if (!RNA_property_is_set(op->ptr, prop)) {
134  RNA_property_float_set_array(op->ptr, prop, rv3d->viewinv[2]);
135  }
136  }
137 
138 #ifdef USE_GIZMO
139  /* Start with zero angle, drag out the value. */
140  prop = RNA_struct_find_property(op->ptr, "angle");
141  if (!RNA_property_is_set(op->ptr, prop)) {
142  RNA_property_float_set(op->ptr, prop, 0.0f);
143  }
144 #endif
145 
146  int ret = edbm_spin_exec(C, op);
147 
148 #ifdef USE_GIZMO
149  if (ret & OPERATOR_FINISHED) {
150  /* Setup gizmos */
151  if (v3d && ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0)) {
152  wmGizmoGroupType *gzgt = WM_gizmogrouptype_find("MESH_GGT_spin_redo", false);
153  if (!WM_gizmo_group_type_ensure_ptr(gzgt)) {
154  struct Main *bmain = CTX_data_main(C);
155  WM_gizmo_group_type_reinit_ptr(bmain, gzgt);
156  }
157  }
158  }
159 #endif
160 
161  return ret;
162 }
163 
165  wmOperator *op,
166  const PropertyRNA *prop)
167 {
168  const char *prop_id = RNA_property_identifier(prop);
169  const bool dupli = RNA_boolean_get(op->ptr, "dupli");
170 
171  if (dupli) {
172  if (STR_ELEM(prop_id, "use_auto_merge", "use_normal_flip")) {
173  return false;
174  }
175  }
176  return true;
177 }
178 
180 {
181  PropertyRNA *prop;
182 
183  /* identifiers */
184  ot->name = "Spin";
185  ot->description =
186  "Extrude selected vertices in a circle around the cursor in indicated viewport";
187  ot->idname = "MESH_OT_spin";
188 
189  /* api callbacks */
194 
195  /* flags */
197 
198  /* props */
199  RNA_def_int(ot->srna, "steps", 12, 0, 1000000, "Steps", "Steps", 0, 1000);
200 
201  prop = RNA_def_boolean(ot->srna, "dupli", 0, "Use Duplicates", "");
203 
204  prop = RNA_def_float(ot->srna,
205  "angle",
206  DEG2RADF(90.0f),
207  -1e12f,
208  1e12f,
209  "Angle",
210  "Rotation for each step",
211  DEG2RADF(-360.0f),
212  DEG2RADF(360.0f));
215  "use_auto_merge",
216  true,
217  "Auto Merge",
218  "Merge first/last when the angle is a full revolution");
219  RNA_def_boolean(ot->srna, "use_normal_flip", 0, "Flip Normals", "");
220 
222  "center",
223  3,
224  NULL,
225  -1e12f,
226  1e12f,
227  "Center",
228  "Center in global view space",
229  -1e4f,
230  1e4f);
232  ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -1.0f, 1.0f);
233 
235 #ifdef USE_GIZMO
237 #endif
238 }
239 
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:85
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, v3d, r_len)
Definition: BKE_layer.h:426
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
#define M_PI
Definition: BLI_math_base.h:38
#define DEG2RADF(_deg)
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
#define STR_ELEM(...)
Definition: BLI_string.h:218
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
Object is a sort of wrapper for general info.
@ V3D_GIZMO_HIDE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void EDBM_update_generic(struct Mesh *me, const bool do_tessellation, const bool is_destructive)
void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag)
bool ED_operator_editmesh(struct bContext *C)
Definition: screen_ops.c:404
struct RegionView3D * ED_view3d_context_rv3d(struct bContext *C)
Definition: space_view3d.c:89
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
@ PROP_ANGLE
Definition: RNA_types.h:132
#define C
Definition: RandGen.cpp:39
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define BM_ALL_NOLOOP
Definition: bmesh_class.h:411
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const char hflag, const bool do_flush)
BMO_FLAG_BUFFER.
void BMO_op_exec(BMesh *bm, BMOperator *op)
BMESH OPSTACK EXEC OP.
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
Scene scene
static int edbm_spin_exec(bContext *C, wmOperator *op)
static int edbm_spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static bool edbm_spin_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
void MESH_OT_spin(wmOperatorType *ot)
void MESH_GGT_spin(struct wmGizmoGroupType *gzgt)
void MESH_GGT_spin_redo(struct wmGizmoGroupType *gzgt)
bool EDBM_op_init(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const char *fmt,...)
bool EDBM_op_finish(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const bool do_report)
#define fabsf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
return ret
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1145
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6655
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
Definition: rna_access.c:6378
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
Definition: rna_access.c:3132
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2964
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3825
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
PropertyRNA * RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3851
PropertyRNA * RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3883
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3585
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
Definition: rna_define.c:1563
static const int steps
Definition: sky_nishita.cpp:28
struct BMesh * bm
Definition: BKE_editmesh.h:52
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
Definition: BKE_main.h:116
float obmat[4][4]
void * data
float viewinv[4][4]
View3DCursor cursor
char gizmo_flag
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
bool(* poll_property)(const struct bContext *C, struct wmOperator *op, const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:782
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
struct PointerRNA * ptr
wmOperatorType * ot
Definition: wm_files.c:3156
bool WM_gizmo_group_type_ensure_ptr(wmGizmoGroupType *gzgt)
void WM_gizmo_group_type_reinit_ptr(struct Main *bmain, wmGizmoGroupType *gzgt)
wmGizmoGroupType * WM_gizmogrouptype_find(const char *idname, bool quiet)
wmGizmoGroupType * WM_gizmogrouptype_append(void(*wtfunc)(struct wmGizmoGroupType *))