0b1f625dc2c7ca2f5845f56005ed56b942498f15
[blender.git] / source / blender / draw / intern / draw_cache_extract.h
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  * Copyright 2019, Blender Foundation.
17  */
18
19 /** \file
20  * \ingroup draw
21  */
22
23 #ifndef __DRAW_CACHE_EXTRACT_H__
24 #define __DRAW_CACHE_EXTRACT_H__
25
26 struct TaskGraph;
27
28 /* Vertex Group Selection and display options */
29 typedef struct DRW_MeshWeightState {
30   int defgroup_active;
31   int defgroup_len;
32
33   short flags;
34   char alert_mode;
35
36   /* Set of all selected bones for Multipaint. */
37   bool *defgroup_sel; /* [defgroup_len] */
38   int defgroup_sel_count;
39
40   /* Set of all locked and unlocked deform bones for Lock Relative mode. */
41   bool *defgroup_locked;   /* [defgroup_len] */
42   bool *defgroup_unlocked; /* [defgroup_len] */
43 } DRW_MeshWeightState;
44
45 /* DRW_MeshWeightState.flags */
46 enum {
47   DRW_MESH_WEIGHT_STATE_MULTIPAINT = (1 << 0),
48   DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE = (1 << 1),
49   DRW_MESH_WEIGHT_STATE_LOCK_RELATIVE = (1 << 2),
50 };
51
52 typedef struct DRW_MeshCDMask {
53   uint32_t uv : 8;
54   uint32_t tan : 8;
55   uint32_t vcol : 8;
56   uint32_t sculpt_vcol : 8;
57   uint32_t orco : 1;
58   uint32_t tan_orco : 1;
59   /** Edit uv layer is from the base edit mesh as
60    *  modifiers could remove it. (see T68857) */
61   uint32_t edit_uv : 1;
62 } DRW_MeshCDMask;
63
64 typedef enum eMRIterType {
65   MR_ITER_LOOPTRI = 1 << 0,
66   MR_ITER_LOOP = 1 << 1,
67   MR_ITER_LEDGE = 1 << 2,
68   MR_ITER_LVERT = 1 << 3,
69 } eMRIterType;
70
71 typedef enum eMRDataType {
72   MR_DATA_POLY_NOR = 1 << 1,
73   MR_DATA_LOOP_NOR = 1 << 2,
74   MR_DATA_LOOPTRI = 1 << 3,
75   /** Force loop normals calculation.  */
76   MR_DATA_TAN_LOOP_NOR = 1 << 4,
77 } eMRDataType;
78
79 typedef enum eMRExtractType {
80   MR_EXTRACT_BMESH,
81   MR_EXTRACT_MAPPED,
82   MR_EXTRACT_MESH,
83 } eMRExtractType;
84
85 BLI_INLINE int mesh_render_mat_len_get(Mesh *me)
86 {
87   return MAX2(1, me->totcol);
88 }
89
90 typedef struct MeshBufferCache {
91   /* Every VBO below contains at least enough
92    * data for every loops in the mesh (except fdots and skin roots).
93    * For some VBOs, it extends to (in this exact order) :
94    * loops + loose_edges*2 + loose_verts */
95   struct {
96     GPUVertBuf *pos_nor;  /* extend */
97     GPUVertBuf *lnor;     /* extend */
98     GPUVertBuf *edge_fac; /* extend */
99     GPUVertBuf *weights;  /* extend */
100     GPUVertBuf *uv;
101     GPUVertBuf *tan;
102     GPUVertBuf *vcol;
103     GPUVertBuf *orco;
104     /* Only for edit mode. */
105     GPUVertBuf *edit_data; /* extend */
106     GPUVertBuf *edituv_data;
107     GPUVertBuf *stretch_area;
108     GPUVertBuf *stretch_angle;
109     GPUVertBuf *mesh_analysis;
110     GPUVertBuf *fdots_pos;
111     GPUVertBuf *fdots_nor;
112     GPUVertBuf *fdots_uv;
113     // GPUVertBuf *fdots_edit_data; /* inside fdots_nor for now. */
114     GPUVertBuf *fdots_edituv_data;
115     GPUVertBuf *skin_roots;
116     /* Selection */
117     GPUVertBuf *vert_idx; /* extend */
118     GPUVertBuf *edge_idx; /* extend */
119     GPUVertBuf *poly_idx;
120     GPUVertBuf *fdot_idx;
121   } vbo;
122   /* Index Buffers:
123    * Only need to be updated when topology changes. */
124   struct {
125     /* Indices to vloops. */
126     GPUIndexBuf *tris;        /* Ordered per material. */
127     GPUIndexBuf *lines;       /* Loose edges last. */
128     GPUIndexBuf *lines_loose; /* sub buffer of `lines` only containing the loose edges. */
129     GPUIndexBuf *points;
130     GPUIndexBuf *fdots;
131     /* 3D overlays. */
132     GPUIndexBuf *lines_paint_mask; /* no loose edges. */
133     GPUIndexBuf *lines_adjacency;
134     /* Uv overlays. (visibility can differ from 3D view) */
135     GPUIndexBuf *edituv_tris;
136     GPUIndexBuf *edituv_lines;
137     GPUIndexBuf *edituv_points;
138     GPUIndexBuf *edituv_fdots;
139   } ibo;
140 } MeshBufferCache;
141
142 typedef enum DRWBatchFlag {
143   MBC_SURFACE = (1 << 0),
144   MBC_SURFACE_WEIGHTS = (1 << 1),
145   MBC_EDIT_TRIANGLES = (1 << 2),
146   MBC_EDIT_VERTICES = (1 << 3),
147   MBC_EDIT_EDGES = (1 << 4),
148   MBC_EDIT_VNOR = (1 << 5),
149   MBC_EDIT_LNOR = (1 << 6),
150   MBC_EDIT_FACEDOTS = (1 << 7),
151   MBC_EDIT_MESH_ANALYSIS = (1 << 8),
152   MBC_EDITUV_FACES_STRETCH_AREA = (1 << 9),
153   MBC_EDITUV_FACES_STRETCH_ANGLE = (1 << 10),
154   MBC_EDITUV_FACES = (1 << 11),
155   MBC_EDITUV_EDGES = (1 << 12),
156   MBC_EDITUV_VERTS = (1 << 13),
157   MBC_EDITUV_FACEDOTS = (1 << 14),
158   MBC_EDIT_SELECTION_VERTS = (1 << 15),
159   MBC_EDIT_SELECTION_EDGES = (1 << 16),
160   MBC_EDIT_SELECTION_FACES = (1 << 17),
161   MBC_EDIT_SELECTION_FACEDOTS = (1 << 18),
162   MBC_ALL_VERTS = (1 << 19),
163   MBC_ALL_EDGES = (1 << 20),
164   MBC_LOOSE_EDGES = (1 << 21),
165   MBC_EDGE_DETECTION = (1 << 22),
166   MBC_WIRE_EDGES = (1 << 23),
167   MBC_WIRE_LOOPS = (1 << 24),
168   MBC_WIRE_LOOPS_UVS = (1 << 25),
169   MBC_SURF_PER_MAT = (1 << 26),
170   MBC_SKIN_ROOTS = (1 << 27),
171 } DRWBatchFlag;
172
173 #define MBC_EDITUV \
174   (MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE | MBC_EDITUV_FACES | \
175    MBC_EDITUV_EDGES | MBC_EDITUV_VERTS | MBC_EDITUV_FACEDOTS | MBC_WIRE_LOOPS_UVS)
176
177 #define FOREACH_MESH_BUFFER_CACHE(batch_cache, mbc) \
178   for (MeshBufferCache *mbc = &batch_cache->final; \
179        mbc == &batch_cache->final || mbc == &batch_cache->cage || mbc == &batch_cache->uv_cage; \
180        mbc = (mbc == &batch_cache->final) ? \
181                  &batch_cache->cage : \
182                  ((mbc == &batch_cache->cage) ? &batch_cache->uv_cage : NULL))
183
184 typedef struct MeshBatchCache {
185   MeshBufferCache final, cage, uv_cage;
186
187   struct {
188     /* Surfaces / Render */
189     GPUBatch *surface;
190     GPUBatch *surface_weights;
191     /* Edit mode */
192     GPUBatch *edit_triangles;
193     GPUBatch *edit_vertices;
194     GPUBatch *edit_edges;
195     GPUBatch *edit_vnor;
196     GPUBatch *edit_lnor;
197     GPUBatch *edit_fdots;
198     GPUBatch *edit_mesh_analysis;
199     GPUBatch *edit_skin_roots;
200     /* Edit UVs */
201     GPUBatch *edituv_faces_stretch_area;
202     GPUBatch *edituv_faces_stretch_angle;
203     GPUBatch *edituv_faces;
204     GPUBatch *edituv_edges;
205     GPUBatch *edituv_verts;
206     GPUBatch *edituv_fdots;
207     /* Edit selection */
208     GPUBatch *edit_selection_verts;
209     GPUBatch *edit_selection_edges;
210     GPUBatch *edit_selection_faces;
211     GPUBatch *edit_selection_fdots;
212     /* Common display / Other */
213     GPUBatch *all_verts;
214     GPUBatch *all_edges;
215     GPUBatch *loose_edges;
216     GPUBatch *edge_detection;
217     GPUBatch *wire_edges;     /* Individual edges with face normals. */
218     GPUBatch *wire_loops;     /* Loops around faces. no edges between selected faces */
219     GPUBatch *wire_loops_uvs; /* Same as wire_loops but only has uvs. */
220   } batch;
221
222   GPUBatch **surface_per_mat;
223
224   DRWBatchFlag batch_requested;
225   DRWBatchFlag batch_ready;
226
227   /* settings to determine if cache is invalid */
228   int edge_len;
229   int tri_len;
230   int poly_len;
231   int vert_len;
232   int mat_len;
233   bool is_dirty; /* Instantly invalidates cache, skipping mesh check */
234   bool is_editmode;
235   bool is_uvsyncsel;
236
237   struct DRW_MeshWeightState weight_state;
238
239   DRW_MeshCDMask cd_used, cd_needed, cd_used_over_time;
240
241   int lastmatch;
242
243   /* Valid only if edge_detection is up to date. */
244   bool is_manifold;
245
246   /* Total areas for drawing UV Stretching. Contains the summed area in mesh
247    * space (`tot_area`) and the summed area in uv space (`tot_uvarea`).
248    *
249    * Only valid after `DRW_mesh_batch_cache_create_requested` has been called. */
250   float tot_area, tot_uv_area;
251
252   bool no_loose_wire;
253 } MeshBatchCache;
254
255 void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
256                                         MeshBatchCache *cache,
257                                         MeshBufferCache mbc,
258                                         Mesh *me,
259                                         const bool is_editmode,
260                                         const bool is_paint_mode,
261                                         const float obmat[4][4],
262                                         const bool do_final,
263                                         const bool do_uvedit,
264                                         const bool use_subsurf_fdots,
265                                         const DRW_MeshCDMask *cd_layer_used,
266                                         const Scene *scene,
267                                         const ToolSettings *ts,
268                                         const bool use_hide);
269
270 #endif /* __DRAW_CACHE_EXTRACT_H__ */