Blender  V2.93
drawobject.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) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include "DNA_mesh_types.h"
25 #include "DNA_object_types.h"
26 #include "DNA_scene_types.h"
27 
28 #include "BLI_math.h"
29 
30 #include "BKE_DerivedMesh.h"
31 #include "BKE_editmesh.h"
32 #include "BKE_global.h"
33 #include "BKE_object.h"
34 
35 #include "DEG_depsgraph.h"
36 #include "DEG_depsgraph_query.h"
37 
38 #include "GPU_batch.h"
39 #include "GPU_immediate.h"
40 #include "GPU_shader.h"
41 #include "GPU_state.h"
42 
43 #include "ED_mesh.h"
44 
45 #include "UI_resources.h"
46 
47 #include "DRW_engine.h"
48 
49 #include "view3d_intern.h" /* bad level include */
50 
51 /* OpenGL Circle Drawing - Tables for Optimized Drawing Speed */
52 /* 32 values of sin function (still same result!) */
53 #define CIRCLE_RESOL 32
54 
55 static const float sinval[CIRCLE_RESOL] = {
56  0.00000000, 0.20129852, 0.39435585, 0.57126821, 0.72479278, 0.84864425, 0.93775213,
57  0.98846832, 0.99871650, 0.96807711, 0.89780453, 0.79077573, 0.65137248, 0.48530196,
58  0.29936312, 0.10116832, -0.10116832, -0.29936312, -0.48530196, -0.65137248, -0.79077573,
59  -0.89780453, -0.96807711, -0.99871650, -0.98846832, -0.93775213, -0.84864425, -0.72479278,
60  -0.57126821, -0.39435585, -0.20129852, 0.00000000,
61 };
62 
63 /* 32 values of cos function (still same result!) */
64 static const float cosval[CIRCLE_RESOL] = {
65  1.00000000, 0.97952994, 0.91895781, 0.82076344, 0.68896691, 0.52896401, 0.34730525,
66  0.15142777, -0.05064916, -0.25065253, -0.44039415, -0.61210598, -0.75875812, -0.87434661,
67  -0.95413925, -0.99486932, -0.99486932, -0.95413925, -0.87434661, -0.75875812, -0.61210598,
68  -0.44039415, -0.25065253, -0.05064916, 0.15142777, 0.34730525, 0.52896401, 0.68896691,
69  0.82076344, 0.91895781, 0.97952994, 1.00000000,
70 };
71 
72 static void circball_array_fill(const float verts[CIRCLE_RESOL][3],
73  const float cent[3],
74  float rad,
75  const float tmat[4][4])
76 {
77  float vx[3], vy[3];
78  float *viter = (float *)verts;
79 
80  mul_v3_v3fl(vx, tmat[0], rad);
81  mul_v3_v3fl(vy, tmat[1], rad);
82 
83  for (uint a = 0; a < CIRCLE_RESOL; a++, viter += 3) {
84  viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0];
85  viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1];
86  viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2];
87  }
88 }
89 
90 void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], uint pos)
91 {
92  float verts[CIRCLE_RESOL][3];
93 
94  circball_array_fill(verts, cent, rad, tmat);
95 
97  for (int i = 0; i < CIRCLE_RESOL; i++) {
98  immVertex3fv(pos, verts[i]);
99  }
100  immEnd();
101 }
102 
103 #ifdef VIEW3D_CAMERA_BORDER_HACK
106 #endif
107 
108 /* ***************** BACKBUF SEL (BBS) ********* */
109 
111  Object *ob,
112  const float col[4],
113  const int facemap)
114 {
115  /* happens on undo */
116  if (ob->type != OB_MESH || !ob->data) {
117  return;
118  }
119 
120  Mesh *me = ob->data;
121  {
122  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
123  Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
124  if (me_eval != NULL) {
125  me = me_eval;
126  }
127  }
128 
130 
131  /* Just to create the data to pass to immediate mode! (sigh) */
132  const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
133  if (facemap_data) {
135 
136  const MVert *mvert = me->mvert;
137  const MPoly *mpoly = me->mpoly;
138  const MLoop *mloop = me->mloop;
139 
140  int mpoly_len = me->totpoly;
141  int mloop_len = me->totloop;
142 
143  facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
144 
145  /* Make a batch and free it each time for now. */
146  const int looptris_len = poly_to_tri_count(mpoly_len, mloop_len);
147  const int vbo_len_capacity = looptris_len * 3;
148  int vbo_len_used = 0;
149 
150  GPUVertFormat format_pos = {0};
151  const uint pos_id = GPU_vertformat_attr_add(
152  &format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
153 
154  GPUVertBuf *vbo_pos = GPU_vertbuf_create_with_format(&format_pos);
155  GPU_vertbuf_data_alloc(vbo_pos, vbo_len_capacity);
156 
157  GPUVertBufRaw pos_step;
158  GPU_vertbuf_attr_get_raw_data(vbo_pos, pos_id, &pos_step);
159 
160  const MPoly *mp;
161  int i;
162  if (me->runtime.looptris.array) {
163  MLoopTri *mlt = me->runtime.looptris.array;
164  for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
165  if (facemap_data[i] == facemap) {
166  for (int j = 2; j < mp->totloop; j++) {
167  copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[0]].v].co);
168  copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[1]].v].co);
169  copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[2]].v].co);
170  vbo_len_used += 3;
171  mlt++;
172  }
173  }
174  else {
175  mlt += mp->totloop - 2;
176  }
177  }
178  }
179  else {
180  /* No tessellation data, fan-fill. */
181  for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
182  if (facemap_data[i] == facemap) {
183  const MLoop *ml_start = &mloop[mp->loopstart];
184  const MLoop *ml_a = ml_start + 1;
185  const MLoop *ml_b = ml_start + 2;
186  for (int j = 2; j < mp->totloop; j++) {
187  copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_start->v].co);
188  copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_a->v].co);
189  copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_b->v].co);
190  vbo_len_used += 3;
191 
192  ml_a++;
193  ml_b++;
194  }
195  }
196  }
197  }
198 
199  if (vbo_len_capacity != vbo_len_used) {
200  GPU_vertbuf_data_resize(vbo_pos, vbo_len_used);
201  }
202 
203  GPUBatch *draw_batch = GPU_batch_create(GPU_PRIM_TRIS, vbo_pos, NULL);
205  GPU_batch_uniform_4fv(draw_batch, "color", col);
206  GPU_batch_draw(draw_batch);
207  GPU_batch_discard(draw_batch);
208  GPU_vertbuf_discard(vbo_pos);
209 
211  }
212 }
void * CustomData_get_layer(const struct CustomData *data, int type)
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_evaluated_mesh(struct Object *object)
Definition: object.c:4459
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ CD_FACEMAP
Object is a sort of wrapper for general info.
@ OB_NEG_SCALE
@ OB_MESH
GPUBatch
Definition: GPU_batch.h:93
void GPU_batch_discard(GPUBatch *)
Definition: gpu_batch.cc:127
#define GPU_batch_create(prim, verts, elem)
Definition: GPU_batch.h:107
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
Definition: gpu_batch.cc:299
void GPU_batch_draw(GPUBatch *batch)
Definition: gpu_batch.cc:234
#define GPU_batch_uniform_4fv(batch, name, val)
Definition: GPU_batch.h:142
void immVertex3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
@ GPU_PRIM_LINE_LOOP
Definition: GPU_primitive.h:39
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:37
@ GPU_SHADER_3D_UNIFORM_COLOR
Definition: GPU_shader.h:200
@ GPU_BLEND_NONE
Definition: GPU_state.h:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
void GPU_front_facing(bool invert)
Definition: gpu_state.cc:65
#define GPU_vertbuf_create_with_format(format)
void GPU_vertbuf_discard(GPUVertBuf *)
struct GPUVertBuf GPUVertBuf
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
GPU_INLINE void * GPU_vertbuf_raw_step(GPUVertBufRaw *a)
void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *, uint a_idx, GPUVertBufRaw *access)
void GPU_vertbuf_data_resize(GPUVertBuf *, uint v_len)
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
const int facemap[6][4]
Definition: Projections.cpp:57
const Depsgraph * depsgraph
void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], uint pos)
Definition: drawobject.c:90
void ED_draw_object_facemap(Depsgraph *depsgraph, Object *ob, const float col[4], const int facemap)
Definition: drawobject.c:110
uchar view3d_camera_border_hack_col[3]
Definition: drawobject.c:104
#define CIRCLE_RESOL
Definition: drawobject.c:53
bool view3d_camera_border_hack_test
Definition: drawobject.c:105
static const float sinval[CIRCLE_RESOL]
Definition: drawobject.c:55
static void circball_array_fill(const float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4])
Definition: drawobject.c:72
static const float cosval[CIRCLE_RESOL]
Definition: drawobject.c:64
static float verts[][3]
uint pos
uint col
static unsigned a[3]
Definition: RandGen.cpp:92
struct MLoopTri * array
unsigned int tri[3]
unsigned int v
float co[3]
struct MLoopTri_Store looptris
struct MVert * mvert
struct MLoop * mloop
Mesh_Runtime runtime
int totpoly
int totloop
struct MPoly * mpoly
short transflag
void * data