Blender  V3.3
editmesh_extrude_screw.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2004 Blender Foundation. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "DNA_object_types.h"
11 
12 #include "BLI_math.h"
13 
14 #include "BKE_context.h"
15 #include "BKE_editmesh.h"
16 #include "BKE_layer.h"
17 #include "BKE_report.h"
18 
19 #include "RNA_access.h"
20 #include "RNA_define.h"
21 
22 #include "WM_types.h"
23 
24 #include "ED_mesh.h"
25 #include "ED_screen.h"
26 #include "ED_view3d.h"
27 
28 #include "mesh_intern.h" /* own include */
29 
30 /* -------------------------------------------------------------------- */
35 {
36  BMEdge *eed;
37  BMVert *eve, *v1, *v2;
38  BMIter iter, eiter;
39  float dvec[3], nor[3], cent[3], axis[3], v1_co_global[3], v2_co_global[3];
40  int steps, turns;
41  int valence;
42  uint objects_empty_len = 0;
43  uint failed_axis_len = 0;
44  uint failed_vertices_len = 0;
45 
46  turns = RNA_int_get(op->ptr, "turns");
47  steps = RNA_int_get(op->ptr, "steps");
48  RNA_float_get_array(op->ptr, "center", cent);
49  RNA_float_get_array(op->ptr, "axis", axis);
50 
51  uint objects_len = 0;
52  ViewLayer *view_layer = CTX_data_view_layer(C);
54  view_layer, CTX_wm_view3d(C), &objects_len);
55 
56  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
57  Object *obedit = objects[ob_index];
59  BMesh *bm = em->bm;
60 
61  if (bm->totvertsel < 2) {
62  if (bm->totvertsel == 0) {
63  objects_empty_len++;
64  }
65  continue;
66  }
67 
68  if (is_zero_v3(axis)) {
69  failed_axis_len++;
70  continue;
71  }
72 
73  /* find two vertices with valence count == 1, more or less is wrong */
74  v1 = NULL;
75  v2 = NULL;
76 
77  BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
78  valence = 0;
79  BM_ITER_ELEM (eed, &eiter, eve, BM_EDGES_OF_VERT) {
81  valence++;
82  }
83  }
84 
85  if (valence == 1) {
86  if (v1 == NULL) {
87  v1 = eve;
88  }
89  else if (v2 == NULL) {
90  v2 = eve;
91  }
92  else {
93  v1 = NULL;
94  break;
95  }
96  }
97  }
98 
99  if (v1 == NULL || v2 == NULL) {
100  failed_vertices_len++;
101  continue;
102  }
103 
104  copy_v3_v3(nor, obedit->obmat[2]);
105 
106  /* calculate dvec */
107  mul_v3_m4v3(v1_co_global, obedit->obmat, v1->co);
108  mul_v3_m4v3(v2_co_global, obedit->obmat, v2->co);
109  sub_v3_v3v3(dvec, v1_co_global, v2_co_global);
110  mul_v3_fl(dvec, 1.0f / steps);
111 
112  if (dot_v3v3(nor, dvec) > 0.0f) {
113  negate_v3(dvec);
114  }
115 
116  BMOperator spinop;
117  if (!EDBM_op_init(
118  em,
119  &spinop,
120  op,
121  "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 use_duplicate=%b",
123  cent,
124  axis,
125  dvec,
126  turns * steps,
127  DEG2RADF(360.0f * turns),
128  obedit->obmat,
129  false)) {
130  continue;
131  }
132 
133  BMO_op_exec(bm, &spinop);
136  bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true);
137 
138  if (!EDBM_op_finish(em, &spinop, op, true)) {
139  continue;
140  }
141 
142  EDBM_update(obedit->data,
143  &(const struct EDBMUpdate_Params){
144  .calc_looptri = true,
145  .calc_normals = false,
146  .is_destructive = true,
147  });
148  }
149  MEM_freeN(objects);
150 
151  if (failed_axis_len == objects_len - objects_empty_len) {
152  BKE_report(op->reports, RPT_ERROR, "Invalid/unset axis");
153  }
154  else if (failed_vertices_len == objects_len - objects_empty_len) {
155  BKE_report(op->reports, RPT_ERROR, "You have to select a string of connected vertices too");
156  }
157 
158  return OPERATOR_FINISHED;
159 }
160 
161 /* get center and axis, in global coords */
162 static int edbm_screw_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
163 {
166 
167  PropertyRNA *prop;
168  prop = RNA_struct_find_property(op->ptr, "center");
169  if (!RNA_property_is_set(op->ptr, prop)) {
171  }
172  if (rv3d) {
173  prop = RNA_struct_find_property(op->ptr, "axis");
174  if (!RNA_property_is_set(op->ptr, prop)) {
175  RNA_property_float_set_array(op->ptr, prop, rv3d->viewinv[1]);
176  }
177  }
178 
179  return edbm_screw_exec(C, op);
180 }
181 
183 {
184  /* identifiers */
185  ot->name = "Screw";
186  ot->description =
187  "Extrude selected vertices in screw-shaped rotation around the cursor in indicated viewport";
188  ot->idname = "MESH_OT_screw";
189 
190  /* api callbacks */
194 
195  /* flags */
197 
198  /* props */
199  RNA_def_int(ot->srna, "steps", 9, 1, 100000, "Steps", "Steps", 3, 256);
200  RNA_def_int(ot->srna, "turns", 1, 1, 100000, "Turns", "Turns", 1, 256);
201 
203  "center",
204  3,
205  NULL,
206  -1e12f,
207  1e12f,
208  "Center",
209  "Center in global view space",
210  -1e4f,
211  1e4f);
213  ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -1.0f, 1.0f);
214 }
215 
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:58
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, v3d, r_len)
Definition: BKE_layer.h:542
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
#define DEG2RADF(_deg)
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void negate_v3(float r[3])
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
Object is a sort of wrapper for general info.
@ OPERATOR_FINISHED
void EDBM_update(struct Mesh *me, const struct EDBMUpdate_Params *params)
void EDBM_flag_disable_all(struct BMEditMesh *em, char hflag)
bool ED_operator_editmesh(struct bContext *C)
Definition: screen_ops.c:433
struct RegionView3D * ED_view3d_context_rv3d(struct bContext *C)
Definition: space_view3d.c:82
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define BM_ALL_NOLOOP
Definition: bmesh_class.h:411
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
@ BM_EDGES_OF_VERT
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, char htype, char hflag, bool do_flush)
BMO_FLAG_BUFFER.
void BMO_op_exec(BMesh *bm, BMOperator *op)
BMESH OPSTACK EXEC OP.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
Scene scene
static int edbm_screw_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int edbm_screw_exec(bContext *C, wmOperator *op)
void MESH_OT_screw(wmOperatorType *ot)
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)
uint nor
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5271
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
Definition: rna_access.c:4980
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
Definition: rna_access.c:2978
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:3862
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:3894
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:3597
static const int steps
Definition: sky_nishita.cpp:19
struct BMesh * bm
Definition: BKE_editmesh.h:40
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
float co[3]
Definition: bmesh_class.h:87
int totvertsel
Definition: bmesh_class.h:298
float obmat[4][4]
void * data
float viewinv[4][4]
View3DCursor cursor
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
struct ReportList * reports
struct PointerRNA * ptr
wmOperatorType * ot
Definition: wm_files.c:3479