Blender  V3.3
editmesh_preselect_elem.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "MEM_guardedalloc.h"
8 
9 #include "BLI_math.h"
10 
11 #include "BKE_editmesh.h"
12 
13 #include "GPU_immediate.h"
14 #include "GPU_matrix.h"
15 #include "GPU_state.h"
16 
17 #include "DNA_object_types.h"
18 
19 #include "ED_mesh.h"
20 #include "ED_view3d.h"
21 
22 /* -------------------------------------------------------------------- */
34 static void vcos_get(BMVert *v, float r_co[3], const float (*coords)[3])
35 {
36  if (coords) {
37  copy_v3_v3(r_co, coords[BM_elem_index_get(v)]);
38  }
39  else {
40  copy_v3_v3(r_co, v->co);
41  }
42 }
43 
44 static void vcos_get_pair(BMVert *v[2], float r_cos[2][3], const float (*coords)[3])
45 {
46  if (coords) {
47  for (int j = 0; j < 2; j++) {
48  copy_v3_v3(r_cos[j], coords[BM_elem_index_get(v[j])]);
49  }
50  }
51  else {
52  for (int j = 0; j < 2; j++) {
53  copy_v3_v3(r_cos[j], v[j]->co);
54  }
55  }
56 }
57 
59  float (*edges)[2][3];
60  int edges_len;
61 
62  float (*verts)[3];
63  int verts_len;
64 
65  float (*preview_tris)[3][3];
67  float (*preview_lines)[2][3];
69 
71 };
72 
75 {
76  psel->preview_action = action;
77 }
78 
80 {
81  return psel->preview_action;
82 }
83 
85 {
86  struct EditMesh_PreSelElem *psel = MEM_callocN(sizeof(*psel), __func__);
88  return psel;
89 }
90 
92 {
95  MEM_freeN(psel);
96 }
97 
99 {
101  psel->preview_tris_len = 0;
102 
104  psel->preview_lines_len = 0;
105 }
106 
108 {
109  MEM_SAFE_FREE(psel->edges);
110  psel->edges_len = 0;
111 
112  MEM_SAFE_FREE(psel->verts);
113  psel->verts_len = 0;
114 }
115 
116 void EDBM_preselect_elem_draw(struct EditMesh_PreSelElem *psel, const float matrix[4][4])
117 {
118  if ((psel->edges_len == 0) && (psel->verts_len == 0)) {
119  return;
120  }
121 
123 
124  GPU_matrix_push();
125  GPU_matrix_mul(matrix);
126 
128 
130 
131  immUniformColor4ub(141, 171, 186, 100);
133  if (psel->preview_tris_len > 0) {
135 
136  for (int i = 0; i < psel->preview_tris_len; i++) {
137  immVertex3fv(pos, psel->preview_tris[i][0]);
138  immVertex3fv(pos, psel->preview_tris[i][1]);
139  immVertex3fv(pos, psel->preview_tris[i][2]);
140  }
141  immEnd();
142  }
143 
144  if (psel->preview_lines_len > 0) {
145 
146  immUniformColor4ub(3, 161, 252, 200);
147  GPU_line_width(2.0f);
149  for (int i = 0; i < psel->preview_lines_len; i++) {
150  immVertex3fv(pos, psel->preview_lines[i][0]);
151  immVertex3fv(pos, psel->preview_lines[i][1]);
152  }
153  immEnd();
154  }
155  }
156 
158  immUniformColor4ub(252, 49, 10, 200);
159  }
160  else {
161  immUniformColor4ub(3, 161, 252, 200);
162  }
163 
164  if (psel->edges_len > 0) {
165  GPU_line_width(3.0f);
166  immBegin(GPU_PRIM_LINES, psel->edges_len * 2);
167 
168  for (int i = 0; i < psel->edges_len; i++) {
169  immVertex3fv(pos, psel->edges[i][0]);
170  immVertex3fv(pos, psel->edges[i][1]);
171  }
172 
173  immEnd();
174  }
175 
176  if (psel->verts_len > 0) {
177  GPU_point_size(4.0f);
178 
180 
181  for (int i = 0; i < psel->verts_len; i++) {
182  immVertex3fv(pos, psel->verts[i]);
183  }
184 
185  immEnd();
186  }
187 
189 
190  GPU_matrix_pop();
191 
192  /* Reset default */
194 }
195 
197  BMesh *UNUSED(bm),
198  BMVert *eve,
199  const float (*coords)[3])
200 {
201  float(*verts)[3] = MEM_mallocN(sizeof(*psel->verts), __func__);
202  vcos_get(eve, verts[0], coords);
203  psel->verts = verts;
204  psel->verts_len = 1;
205 }
206 
208  BMesh *UNUSED(bm),
209  BMEdge *eed,
210  const float (*coords)[3])
211 {
212  float(*edges)[2][3] = MEM_mallocN(sizeof(*psel->edges), __func__);
213  vcos_get_pair(&eed->v1, edges[0], coords);
214  psel->edges = edges;
215  psel->edges_len = 1;
216 }
217 
219  ViewContext *vc,
220  BMesh *UNUSED(bm),
221  BMVert *eed,
222  const int mval[2])
223 {
224  BMVert *v_act = eed;
225  BMEdge *e_pair[2] = {NULL};
226  float center[3];
227 
228  if (v_act->e != NULL) {
229  for (uint allow_wire = 0; allow_wire < 2 && (e_pair[1] == NULL); allow_wire++) {
230  int i = 0;
231  BMEdge *e_iter = v_act->e;
232  do {
233  if ((BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == false) &&
234  (allow_wire ? BM_edge_is_wire(e_iter) : BM_edge_is_boundary(e_iter))) {
235  if (i == 2) {
236  e_pair[0] = e_pair[1] = NULL;
237  break;
238  }
239  e_pair[i++] = e_iter;
240  }
241  } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_act)) != v_act->e);
242  }
243  }
244 
245  if (e_pair[1] != NULL) {
246  mul_v3_m4v3(center, vc->obedit->obmat, v_act->co);
247  ED_view3d_win_to_3d_int(vc->v3d, vc->region, center, mval, center);
248  mul_m4_v3(vc->obedit->imat, center);
249 
250  psel->preview_tris = MEM_mallocN(sizeof(*psel->preview_tris) * 2, __func__);
251  psel->preview_lines = MEM_mallocN(sizeof(*psel->preview_lines) * 4, __func__);
252 
253  copy_v3_v3(psel->preview_tris[0][0], e_pair[0]->v1->co);
254  copy_v3_v3(psel->preview_tris[0][1], e_pair[0]->v2->co);
255  copy_v3_v3(psel->preview_tris[0][2], center);
256 
257  copy_v3_v3(psel->preview_tris[1][0], e_pair[1]->v1->co);
258  copy_v3_v3(psel->preview_tris[1][1], e_pair[1]->v2->co);
259  copy_v3_v3(psel->preview_tris[1][2], center);
260 
261  copy_v3_v3(psel->preview_lines[0][0], e_pair[0]->v1->co);
262  copy_v3_v3(psel->preview_lines[0][1], e_pair[0]->v2->co);
263 
264  copy_v3_v3(psel->preview_lines[1][0], e_pair[1]->v1->co);
265  copy_v3_v3(psel->preview_lines[1][1], e_pair[1]->v2->co);
266 
267  copy_v3_v3(psel->preview_lines[2][0], center);
268  if (e_pair[0]->v1 == v_act) {
269  copy_v3_v3(psel->preview_lines[2][1], e_pair[0]->v2->co);
270  }
271  else {
272  copy_v3_v3(psel->preview_lines[2][1], e_pair[0]->v1->co);
273  }
274 
275  copy_v3_v3(psel->preview_lines[3][0], center);
276  if (e_pair[1]->v1 == v_act) {
277  copy_v3_v3(psel->preview_lines[3][1], e_pair[1]->v2->co);
278  }
279  else {
280  copy_v3_v3(psel->preview_lines[3][1], e_pair[1]->v1->co);
281  }
282  psel->preview_tris_len = 2;
283  psel->preview_lines_len = 4;
284  }
285 }
286 
288  ViewContext *UNUSED(vc),
289  BMesh *UNUSED(bm),
290  BMFace *efa,
291  const int UNUSED(mval[2]))
292 {
293  float(*preview_lines)[2][3] = MEM_mallocN(sizeof(*psel->edges) * efa->len, __func__);
294  BMLoop *l_iter, *l_first;
295  l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
296  int i = 0;
297  do {
298  vcos_get_pair(&l_iter->e->v1, preview_lines[i++], NULL);
299  } while ((l_iter = l_iter->next) != l_first);
301  psel->preview_lines_len = efa->len;
302 }
303 
305  ViewContext *vc,
306  BMesh *UNUSED(bm),
307  BMEdge *eed,
308  const int mval[2])
309 {
310  float center[3];
311  psel->preview_tris = MEM_mallocN(sizeof(*psel->preview_tris), __func__);
312  psel->preview_lines = MEM_mallocN(sizeof(*psel->preview_lines) * 3, __func__);
313  mid_v3_v3v3(center, eed->v1->co, eed->v2->co);
314  mul_m4_v3(vc->obedit->obmat, center);
315  ED_view3d_win_to_3d_int(vc->v3d, vc->region, center, mval, center);
316  mul_m4_v3(vc->obedit->imat, center);
317 
318  copy_v3_v3(psel->preview_tris[0][0], eed->v1->co);
319  copy_v3_v3(psel->preview_tris[0][1], eed->v2->co);
320  copy_v3_v3(psel->preview_tris[0][2], center);
321 
322  copy_v3_v3(psel->preview_lines[0][0], eed->v1->co);
323  copy_v3_v3(psel->preview_lines[0][1], eed->v2->co);
324 
325  copy_v3_v3(psel->preview_lines[1][0], eed->v2->co);
326  copy_v3_v3(psel->preview_lines[1][1], center);
327 
328  copy_v3_v3(psel->preview_lines[2][0], center);
329  copy_v3_v3(psel->preview_lines[2][1], eed->v1->co);
330  psel->preview_tris_len = 1;
331  psel->preview_lines_len = 3;
332 }
333 
335  BMesh *UNUSED(bm),
336  BMFace *efa,
337  const float (*coords)[3])
338 {
339  float(*edges)[2][3] = MEM_mallocN(sizeof(*psel->edges) * efa->len, __func__);
340  BMLoop *l_iter, *l_first;
341  l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
342  int i = 0;
343  do {
344  vcos_get_pair(&l_iter->e->v1, edges[i++], coords);
345  } while ((l_iter = l_iter->next) != l_first);
346  psel->edges = edges;
347  psel->edges_len = efa->len;
348 }
349 
351  BMesh *bm,
352  BMElem *ele,
353  const float (*coords)[3])
354 {
356 
357  if (coords) {
359  }
360 
361  switch (ele->head.htype) {
362  case BM_VERT:
364  break;
365  case BM_EDGE:
367  break;
368  case BM_FACE:
370  break;
371  default:
372  BLI_assert(0);
373  }
374 }
375 
377  struct ViewContext *vc,
378  struct BMesh *bm,
379  struct BMElem *ele,
380  const int mval[2])
381 {
383 
384  switch (ele->head.htype) {
385  case BM_VERT:
388  }
389  break;
390  case BM_EDGE:
392  break;
393  case BM_FACE:
395  break;
396  default:
397  BLI_assert(0);
398  }
399 }
400 
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:46
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
MINLINE void copy_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:237
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
Object is a sort of wrapper for general info.
eEditMesh_PreSelPreviewAction
Definition: ED_mesh.h:352
@ PRESELECT_ACTION_CREATE
Definition: ED_mesh.h:354
@ PRESELECT_ACTION_DELETE
Definition: ED_mesh.h:355
@ PRESELECT_ACTION_TRANSFORM
Definition: ED_mesh.h:353
void ED_view3d_win_to_3d_int(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const int mval[2], float r_out[3])
NSNotificationCenter * center
void immUnbindProgram(void)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
GPUVertFormat * immVertexFormat(void)
void immVertex3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
_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
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
#define GPU_matrix_mul(x)
Definition: GPU_matrix.h:224
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_PRIM_POINTS
Definition: GPU_primitive.h:19
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:21
@ GPU_SHADER_3D_UNIFORM_COLOR
Definition: GPU_shader.h:230
void GPU_line_width(float width)
Definition: gpu_state.cc:158
void GPU_point_size(float size)
Definition: gpu_state.cc:164
@ GPU_DEPTH_LESS_EQUAL
Definition: GPU_state.h:86
@ GPU_DEPTH_NONE
Definition: GPU_state.h:83
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:65
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define BM_DISK_EDGE_NEXT(e, v)
Definition: bmesh_class.h:625
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:622
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_HIDDEN
Definition: bmesh_class.h:472
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:110
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.cc:446
BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert * v
void EDBM_preselect_elem_update_preview(struct EditMesh_PreSelElem *psel, struct ViewContext *vc, struct BMesh *bm, struct BMElem *ele, const int mval[2])
void EDBM_preselect_elem_destroy(struct EditMesh_PreSelElem *psel)
void EDBM_preselect_elem_draw(struct EditMesh_PreSelElem *psel, const float matrix[4][4])
void EDBM_preselect_action_set(struct EditMesh_PreSelElem *psel, eEditMesh_PreSelPreviewAction action)
static void view3d_preselect_mesh_elem_update_from_vert(struct EditMesh_PreSelElem *psel, BMesh *UNUSED(bm), BMVert *eve, const float(*coords)[3])
static void view3d_preselect_update_preview_triangle_from_face(struct EditMesh_PreSelElem *psel, ViewContext *UNUSED(vc), BMesh *UNUSED(bm), BMFace *efa, const int UNUSED(mval[2]))
eEditMesh_PreSelPreviewAction EDBM_preselect_action_get(struct EditMesh_PreSelElem *psel)
void EDBM_preselect_elem_update_from_single(struct EditMesh_PreSelElem *psel, BMesh *bm, BMElem *ele, const float(*coords)[3])
void EDBM_preselect_elem_clear(struct EditMesh_PreSelElem *psel)
static void view3d_preselect_mesh_elem_update_from_face(struct EditMesh_PreSelElem *psel, BMesh *UNUSED(bm), BMFace *efa, const float(*coords)[3])
static void view3d_preselect_mesh_elem_update_from_edge(struct EditMesh_PreSelElem *psel, BMesh *UNUSED(bm), BMEdge *eed, const float(*coords)[3])
static void vcos_get_pair(BMVert *v[2], float r_cos[2][3], const float(*coords)[3])
void EDBM_preselect_preview_clear(struct EditMesh_PreSelElem *psel)
struct EditMesh_PreSelElem * EDBM_preselect_elem_create(void)
static void view3d_preselect_update_preview_triangle_from_edge(struct EditMesh_PreSelElem *psel, ViewContext *vc, BMesh *UNUSED(bm), BMEdge *eed, const int mval[2])
static void vcos_get(BMVert *v, float r_co[3], const float(*coords)[3])
static void view3d_preselect_update_preview_triangle_from_vert(struct EditMesh_PreSelElem *psel, ViewContext *vc, BMesh *UNUSED(bm), BMVert *eed, const int mval[2])
static float verts[][3]
uint pos
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
BMVert * v1
Definition: bmesh_class.h:122
BMVert * v2
Definition: bmesh_class.h:122
BMHeader head
Definition: bmesh_class.h:243
int len
Definition: bmesh_class.h:267
char htype
Definition: bmesh_class.h:64
struct BMEdge * e
Definition: bmesh_class.h:164
struct BMLoop * next
Definition: bmesh_class.h:233
float co[3]
Definition: bmesh_class.h:87
struct BMEdge * e
Definition: bmesh_class.h:97
eEditMesh_PreSelPreviewAction preview_action
float imat[4][4]
float obmat[4][4]
struct ARegion * region
Definition: ED_view3d.h:69
struct Object * obedit
Definition: ED_view3d.h:68
struct View3D * v3d
Definition: ED_view3d.h:70