Blender  V2.93
editmesh_preselect_elem.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 
21 #include "MEM_guardedalloc.h"
22 
23 #include "BLI_math.h"
24 
25 #include "BKE_editmesh.h"
26 
27 #include "GPU_immediate.h"
28 #include "GPU_matrix.h"
29 #include "GPU_state.h"
30 
31 #include "DNA_object_types.h"
32 
33 #include "ED_mesh.h"
34 #include "ED_view3d.h"
35 
36 /* -------------------------------------------------------------------- */
48 static void vcos_get(BMVert *v, float r_co[3], const float (*coords)[3])
49 {
50  if (coords) {
51  copy_v3_v3(r_co, coords[BM_elem_index_get(v)]);
52  }
53  else {
54  copy_v3_v3(r_co, v->co);
55  }
56 }
57 
58 static void vcos_get_pair(BMVert *v[2], float r_cos[2][3], const float (*coords)[3])
59 {
60  if (coords) {
61  for (int j = 0; j < 2; j++) {
62  copy_v3_v3(r_cos[j], coords[BM_elem_index_get(v[j])]);
63  }
64  }
65  else {
66  for (int j = 0; j < 2; j++) {
67  copy_v3_v3(r_cos[j], v[j]->co);
68  }
69  }
70 }
71 
73  float (*edges)[2][3];
74  int edges_len;
75 
76  float (*verts)[3];
77  int verts_len;
78 
79  float (*preview_tris)[3][3];
81  float (*preview_lines)[2][3];
83 
85 };
86 
89 {
90  psel->preview_action = action;
91 }
92 
94 {
95  return psel->preview_action;
96 }
97 
99 {
100  struct EditMesh_PreSelElem *psel = MEM_callocN(sizeof(*psel), __func__);
102  return psel;
103 }
104 
106 {
109  MEM_freeN(psel);
110 }
111 
113 {
115  psel->preview_tris_len = 0;
116 
118  psel->preview_lines_len = 0;
119 }
120 
122 {
123  MEM_SAFE_FREE(psel->edges);
124  psel->edges_len = 0;
125 
126  MEM_SAFE_FREE(psel->verts);
127  psel->verts_len = 0;
128 }
129 
130 void EDBM_preselect_elem_draw(struct EditMesh_PreSelElem *psel, const float matrix[4][4])
131 {
132  if ((psel->edges_len == 0) && (psel->verts_len == 0)) {
133  return;
134  }
135 
137 
138  GPU_matrix_push();
139  GPU_matrix_mul(matrix);
140 
142 
144 
145  immUniformColor4ub(141, 171, 186, 100);
147  if (psel->preview_tris_len > 0) {
149 
150  for (int i = 0; i < psel->preview_tris_len; i++) {
151  immVertex3fv(pos, psel->preview_tris[i][0]);
152  immVertex3fv(pos, psel->preview_tris[i][1]);
153  immVertex3fv(pos, psel->preview_tris[i][2]);
154  }
155  immEnd();
156  }
157 
158  if (psel->preview_lines_len > 0) {
159 
160  immUniformColor4ub(3, 161, 252, 200);
161  GPU_line_width(2.0f);
163  for (int i = 0; i < psel->preview_lines_len; i++) {
164  immVertex3fv(pos, psel->preview_lines[i][0]);
165  immVertex3fv(pos, psel->preview_lines[i][1]);
166  }
167  immEnd();
168  }
169  }
170 
172  immUniformColor4ub(252, 49, 10, 200);
173  }
174  else {
175  immUniformColor4ub(3, 161, 252, 200);
176  }
177 
178  if (psel->edges_len > 0) {
179  GPU_line_width(3.0f);
180  immBegin(GPU_PRIM_LINES, psel->edges_len * 2);
181 
182  for (int i = 0; i < psel->edges_len; i++) {
183  immVertex3fv(pos, psel->edges[i][0]);
184  immVertex3fv(pos, psel->edges[i][1]);
185  }
186 
187  immEnd();
188  }
189 
190  if (psel->verts_len > 0) {
191  GPU_point_size(4.0f);
192 
194 
195  for (int i = 0; i < psel->verts_len; i++) {
196  immVertex3fv(pos, psel->verts[i]);
197  }
198 
199  immEnd();
200  }
201 
203 
204  GPU_matrix_pop();
205 
206  /* Reset default */
208 }
209 
211  BMesh *UNUSED(bm),
212  BMVert *eve,
213  const float (*coords)[3])
214 {
215  float(*verts)[3] = MEM_mallocN(sizeof(*psel->verts), __func__);
216  vcos_get(eve, verts[0], coords);
217  psel->verts = verts;
218  psel->verts_len = 1;
219 }
220 
222  BMesh *UNUSED(bm),
223  BMEdge *eed,
224  const float (*coords)[3])
225 {
226  float(*edges)[2][3] = MEM_mallocN(sizeof(*psel->edges), __func__);
227  vcos_get_pair(&eed->v1, edges[0], coords);
228  psel->edges = edges;
229  psel->edges_len = 1;
230 }
231 
233  ViewContext *vc,
234  BMesh *UNUSED(bm),
235  BMVert *eed,
236  const int mval[2])
237 {
238  BMVert *v_act = eed;
239  BMEdge *e_pair[2] = {NULL};
240  float center[3];
241 
242  if (v_act->e != NULL) {
243  for (uint allow_wire = 0; allow_wire < 2 && (e_pair[1] == NULL); allow_wire++) {
244  int i = 0;
245  BMEdge *e_iter = v_act->e;
246  do {
247  if ((BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == false) &&
248  (allow_wire ? BM_edge_is_wire(e_iter) : BM_edge_is_boundary(e_iter))) {
249  if (i == 2) {
250  e_pair[0] = e_pair[1] = NULL;
251  break;
252  }
253  e_pair[i++] = e_iter;
254  }
255  } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_act)) != v_act->e);
256  }
257  }
258 
259  if (e_pair[1] != NULL) {
260  mul_v3_m4v3(center, vc->obedit->obmat, v_act->co);
261  ED_view3d_win_to_3d_int(vc->v3d, vc->region, center, mval, center);
262  mul_m4_v3(vc->obedit->imat, center);
263 
264  psel->preview_tris = MEM_mallocN(sizeof(*psel->preview_tris) * 2, __func__);
265  psel->preview_lines = MEM_mallocN(sizeof(*psel->preview_lines) * 4, __func__);
266 
267  copy_v3_v3(psel->preview_tris[0][0], e_pair[0]->v1->co);
268  copy_v3_v3(psel->preview_tris[0][1], e_pair[0]->v2->co);
269  copy_v3_v3(psel->preview_tris[0][2], center);
270 
271  copy_v3_v3(psel->preview_tris[1][0], e_pair[1]->v1->co);
272  copy_v3_v3(psel->preview_tris[1][1], e_pair[1]->v2->co);
273  copy_v3_v3(psel->preview_tris[1][2], center);
274 
275  copy_v3_v3(psel->preview_lines[0][0], e_pair[0]->v1->co);
276  copy_v3_v3(psel->preview_lines[0][1], e_pair[0]->v2->co);
277 
278  copy_v3_v3(psel->preview_lines[1][0], e_pair[1]->v1->co);
279  copy_v3_v3(psel->preview_lines[1][1], e_pair[1]->v2->co);
280 
281  copy_v3_v3(psel->preview_lines[2][0], center);
282  if (e_pair[0]->v1 == v_act) {
283  copy_v3_v3(psel->preview_lines[2][1], e_pair[0]->v2->co);
284  }
285  else {
286  copy_v3_v3(psel->preview_lines[2][1], e_pair[0]->v1->co);
287  }
288 
289  copy_v3_v3(psel->preview_lines[3][0], center);
290  if (e_pair[1]->v1 == v_act) {
291  copy_v3_v3(psel->preview_lines[3][1], e_pair[1]->v2->co);
292  }
293  else {
294  copy_v3_v3(psel->preview_lines[3][1], e_pair[1]->v1->co);
295  }
296  psel->preview_tris_len = 2;
297  psel->preview_lines_len = 4;
298  }
299 }
300 
302  ViewContext *UNUSED(vc),
303  BMesh *UNUSED(bm),
304  BMFace *efa,
305  const int UNUSED(mval[2]))
306 {
307  float(*preview_lines)[2][3] = MEM_mallocN(sizeof(*psel->edges) * efa->len, __func__);
308  BMLoop *l_iter, *l_first;
309  l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
310  int i = 0;
311  do {
312  vcos_get_pair(&l_iter->e->v1, preview_lines[i++], NULL);
313  } while ((l_iter = l_iter->next) != l_first);
315  psel->preview_lines_len = efa->len;
316 }
317 
319  ViewContext *vc,
320  BMesh *UNUSED(bm),
321  BMEdge *eed,
322  const int mval[2])
323 {
324  float center[3];
325  psel->preview_tris = MEM_mallocN(sizeof(*psel->preview_tris), __func__);
326  psel->preview_lines = MEM_mallocN(sizeof(*psel->preview_lines) * 3, __func__);
327  mid_v3_v3v3(center, eed->v1->co, eed->v2->co);
328  mul_m4_v3(vc->obedit->obmat, center);
329  ED_view3d_win_to_3d_int(vc->v3d, vc->region, center, mval, center);
330  mul_m4_v3(vc->obedit->imat, center);
331 
332  copy_v3_v3(psel->preview_tris[0][0], eed->v1->co);
333  copy_v3_v3(psel->preview_tris[0][1], eed->v2->co);
334  copy_v3_v3(psel->preview_tris[0][2], center);
335 
336  copy_v3_v3(psel->preview_lines[0][0], eed->v1->co);
337  copy_v3_v3(psel->preview_lines[0][1], eed->v2->co);
338 
339  copy_v3_v3(psel->preview_lines[1][0], eed->v2->co);
340  copy_v3_v3(psel->preview_lines[1][1], center);
341 
342  copy_v3_v3(psel->preview_lines[2][0], center);
343  copy_v3_v3(psel->preview_lines[2][1], eed->v1->co);
344  psel->preview_tris_len = 1;
345  psel->preview_lines_len = 3;
346 }
347 
349  BMesh *UNUSED(bm),
350  BMFace *efa,
351  const float (*coords)[3])
352 {
353  float(*edges)[2][3] = MEM_mallocN(sizeof(*psel->edges) * efa->len, __func__);
354  BMLoop *l_iter, *l_first;
355  l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
356  int i = 0;
357  do {
358  vcos_get_pair(&l_iter->e->v1, edges[i++], coords);
359  } while ((l_iter = l_iter->next) != l_first);
360  psel->edges = edges;
361  psel->edges_len = efa->len;
362 }
363 
365  BMesh *bm,
366  BMElem *ele,
367  const float (*coords)[3])
368 {
370 
371  if (coords) {
373  }
374 
375  switch (ele->head.htype) {
376  case BM_VERT:
378  break;
379  case BM_EDGE:
381  break;
382  case BM_FACE:
384  break;
385  default:
386  BLI_assert(0);
387  }
388 }
389 
391  struct ViewContext *vc,
392  struct BMesh *bm,
393  struct BMElem *ele,
394  const int mval[2])
395 {
397 
398  switch (ele->head.htype) {
399  case BM_VERT:
402  }
403  break;
404  case BM_EDGE:
406  break;
407  case BM_FACE:
409  break;
410  default:
411  BLI_assert(0);
412  }
413 }
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:58
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
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:270
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
Object is a sort of wrapper for general info.
eEditMesh_PreSelPreviewAction
Definition: ED_mesh.h:272
@ PRESELECT_ACTION_CREATE
Definition: ED_mesh.h:274
@ PRESELECT_ACTION_DELETE
Definition: ED_mesh.h:275
@ PRESELECT_ACTION_TRANSFORM
Definition: ED_mesh.h:273
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:142
#define GPU_matrix_mul(x)
Definition: GPU_matrix.h:223
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:135
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:36
@ GPU_PRIM_POINTS
Definition: GPU_primitive.h:35
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:37
@ GPU_SHADER_3D_UNIFORM_COLOR
Definition: GPU_shader.h:200
void GPU_line_width(float width)
Definition: gpu_state.cc:173
void GPU_point_size(float size)
Definition: gpu_state.cc:179
@ GPU_DEPTH_LESS_EQUAL
Definition: GPU_state.h:81
@ GPU_DEPTH_NONE
Definition: GPU_state.h:78
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:75
@ 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:556
@ 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_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:553
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:124
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:26
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.c:2152
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:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
BMVert * v1
Definition: bmesh_class.h:134
BMVert * v2
Definition: bmesh_class.h:134
BMHeader head
Definition: bmesh_class.h:255
int len
Definition: bmesh_class.h:279
char htype
Definition: bmesh_class.h:76
struct BMEdge * e
Definition: bmesh_class.h:176
struct BMLoop * next
Definition: bmesh_class.h:245
float co[3]
Definition: bmesh_class.h:99
struct BMEdge * e
Definition: bmesh_class.h:109
eEditMesh_PreSelPreviewAction preview_action
float imat[4][4]
float obmat[4][4]
struct ARegion * region
Definition: ED_view3d.h:80
struct Object * obedit
Definition: ED_view3d.h:79
struct View3D * v3d
Definition: ED_view3d.h:81