fixes scale on derivative maps
[blender.git] / source / blender / blenkernel / BKE_DerivedMesh.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #ifndef BKE_DERIVEDMESH_H
29 #define BKE_DERIVEDMESH_H
30
31 /** \file BKE_DerivedMesh.h
32  *  \ingroup bke
33  *
34  *  \todo
35  *  - Make drawMapped* functions take a predicate function that
36  *    determines whether to draw the edge (this predicate can
37  *    also set color, etc). This will be slightly more general 
38  *    and allow some of the functions to be collapsed.
39  *  - Once accessor functions are added then single element draw
40  *    functions can be implemented using primitive accessors.
41  *  - Add function to dispatch to renderer instead of using
42  *    conversion to DLM.
43  */
44
45 #include "DNA_customdata_types.h"
46 #include "BKE_customdata.h"
47 #include "BKE_bvhutils.h"
48
49 struct MVert;
50 struct MEdge;
51 struct MFace;
52 struct MTFace;
53 struct Object;
54 struct Scene;
55 struct Mesh;
56 struct EditMesh;
57 struct KeyBlock;
58 struct ModifierData;
59 struct MCol;
60 struct ColorBand;
61 struct GPUVertexAttribs;
62 struct GPUDrawObject;
63 struct ListBase;
64 struct PBVH;
65
66 /* number of sub-elements each mesh element has (for interpolation) */
67 #define SUB_ELEMS_VERT 0
68 #define SUB_ELEMS_EDGE 2
69 #define SUB_ELEMS_FACE 4
70
71 typedef struct DMGridData {
72         float co[3];
73         float no[3];
74 } DMGridData;
75
76 typedef struct DMGridAdjacency {
77         int index[4];
78         int rotation[4];
79 } DMGridAdjacency;
80
81 typedef enum DerivedMeshType {
82         DM_TYPE_CDDM,
83         DM_TYPE_EDITMESH,
84         DM_TYPE_CCGDM
85 } DerivedMeshType;
86
87 typedef struct DerivedMesh DerivedMesh;
88 struct DerivedMesh {
89         /* Private DerivedMesh data, only for internal DerivedMesh use */
90         CustomData vertData, edgeData, faceData;
91         int numVertData, numEdgeData, numFaceData;
92         int needsFree; /* checked on ->release, is set to 0 for cached results */
93         int deformedOnly; /* set by modifier stack if only deformed from original */
94         BVHCache bvhCache;
95         struct GPUDrawObject *drawObject;
96         DerivedMeshType type;
97         float auto_bump_scale;
98
99         /* Misc. Queries */
100
101         /* Also called in Editmode */
102         int (*getNumVerts)(DerivedMesh *dm);
103         /* Also called in Editmode */
104         int (*getNumFaces)(DerivedMesh *dm);
105
106         int (*getNumEdges)(DerivedMesh *dm);
107
108         /* copy a single vert/edge/face from the derived mesh into
109          * *{vert/edge/face}_r. note that the current implementation
110          * of this function can be quite slow, iterating over all
111          * elements (editmesh)
112          */
113         void (*getVert)(DerivedMesh *dm, int index, struct MVert *vert_r);
114         void (*getEdge)(DerivedMesh *dm, int index, struct MEdge *edge_r);
115         void (*getFace)(DerivedMesh *dm, int index, struct MFace *face_r);
116
117         /* return a pointer to the entire array of verts/edges/face from the
118          * derived mesh. if such an array does not exist yet, it will be created,
119          * and freed on the next ->release(). consider using getVert/Edge/Face if
120          * you are only interested in a few verts/edges/faces.
121          */
122         struct MVert *(*getVertArray)(DerivedMesh *dm);
123         struct MEdge *(*getEdgeArray)(DerivedMesh *dm);
124         struct MFace *(*getFaceArray)(DerivedMesh *dm);
125
126         /* copy all verts/edges/faces from the derived mesh into
127          * *{vert/edge/face}_r (must point to a buffer large enough)
128          */
129         void (*copyVertArray)(DerivedMesh *dm, struct MVert *vert_r);
130         void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *edge_r);
131         void (*copyFaceArray)(DerivedMesh *dm, struct MFace *face_r);
132
133         /* return a copy of all verts/edges/faces from the derived mesh
134          * it is the caller's responsibility to free the returned pointer
135          */
136         struct MVert *(*dupVertArray)(DerivedMesh *dm);
137         struct MEdge *(*dupEdgeArray)(DerivedMesh *dm);
138         struct MFace *(*dupFaceArray)(DerivedMesh *dm);
139
140         /* return a pointer to a single element of vert/edge/face custom data
141          * from the derived mesh (this gives a pointer to the actual data, not
142          * a copy)
143          */
144         void *(*getVertData)(DerivedMesh *dm, int index, int type);
145         void *(*getEdgeData)(DerivedMesh *dm, int index, int type);
146         void *(*getFaceData)(DerivedMesh *dm, int index, int type);
147
148         /* return a pointer to the entire array of vert/edge/face custom data
149          * from the derived mesh (this gives a pointer to the actual data, not
150          * a copy)
151          */
152         void *(*getVertDataArray)(DerivedMesh *dm, int type);
153         void *(*getEdgeDataArray)(DerivedMesh *dm, int type);
154         void *(*getFaceDataArray)(DerivedMesh *dm, int type);
155
156         /* optional grid access for subsurf */
157         int (*getNumGrids)(DerivedMesh *dm);
158         int (*getGridSize)(DerivedMesh *dm);
159         DMGridData **(*getGridData)(DerivedMesh *dm);
160         DMGridAdjacency *(*getGridAdjacency)(DerivedMesh *dm);
161         int *(*getGridOffset)(DerivedMesh *dm);
162
163         /* Iterate over each mapped vertex in the derived mesh, calling the
164          * given function with the original vert and the mapped vert's new
165          * coordinate and normal. For historical reasons the normal can be
166          * passed as a float or short array, only one should be non-NULL.
167          */
168         void (*foreachMappedVert)(
169                                                   DerivedMesh *dm,
170                                                   void (*func)(void *userData, int index, float *co,
171                                                                            float *no_f, short *no_s),
172                                                   void *userData);
173
174         /* Iterate over each mapped edge in the derived mesh, calling the
175          * given function with the original edge and the mapped edge's new
176          * coordinates.
177          */
178         void (*foreachMappedEdge)(DerivedMesh *dm,
179                                                           void (*func)(void *userData, int index,
180                                                                                    float *v0co, float *v1co),
181                                                           void *userData);
182
183         /* Iterate over each mapped face in the derived mesh, calling the
184          * given function with the original face and the mapped face's (or
185          * faces') center and normal.
186          */
187         void (*foreachMappedFaceCenter)(DerivedMesh *dm,
188                                                                         void (*func)(void *userData, int index,
189                                                                                                  float *cent, float *no),
190                                                                         void *userData);
191
192         /* Iterate over all vertex points, calling DO_MINMAX with given args.
193          *
194          * Also called in Editmode
195          */
196         void (*getMinMax)(DerivedMesh *dm, float min_r[3], float max_r[3]);
197
198         /* Direct Access Operations */
199         /*  o Can be undefined */
200         /*  o Must be defined for modifiers that only deform however */
201
202         /* Get vertex location, undefined if index is not valid */
203         void (*getVertCo)(DerivedMesh *dm, int index, float co_r[3]);
204
205         /* Fill the array (of length .getNumVerts()) with all vertex locations */
206         void (*getVertCos)(DerivedMesh *dm, float (*cos_r)[3]);
207
208         /* Get smooth vertex normal, undefined if index is not valid */
209         void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]);
210
211         /* Get a map of vertices to faces
212          */
213         struct ListBase *(*getFaceMap)(struct Object *ob, DerivedMesh *dm);
214
215         /* Get the BVH used for paint modes
216          */
217         struct PBVH *(*getPBVH)(struct Object *ob, DerivedMesh *dm);
218
219         /* Drawing Operations */
220
221         /* Draw all vertices as bgl points (no options) */
222         void (*drawVerts)(DerivedMesh *dm);
223
224         /* Draw edges in the UV mesh (if exists) */
225         void (*drawUVEdges)(DerivedMesh *dm);
226
227         /* Draw all edges as lines (no options) 
228          *
229          * Also called for *final* editmode DerivedMeshes
230          */
231         void (*drawEdges)(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges);
232         
233         /* Draw all loose edges (edges w/ no adjoining faces) */
234         void (*drawLooseEdges)(DerivedMesh *dm);
235
236         /* Draw all faces
237          *  o Set face normal or vertex normal based on inherited face flag
238          *  o Use inherited face material index to call setMaterial
239          *  o Only if setMaterial returns true
240          *
241          * Also called for *final* editmode DerivedMeshes
242          */
243         void (*drawFacesSolid)(DerivedMesh *dm, float (*partial_redraw_planes)[4],
244                                                    int fast, int (*setMaterial)(int, void *attribs));
245
246         /* Draw all faces
247          *  o If useTwoSided, draw front and back using col arrays
248          *  o col1,col2 are arrays of length numFace*4 of 4 component colors
249          *    in ABGR format, and should be passed as per-face vertex color.
250          */
251         void (*drawFacesColored)(DerivedMesh *dm, int useTwoSided,
252                                                          unsigned char *col1, unsigned char *col2);
253
254         /* Draw all faces using MTFace 
255          *  o Drawing options too complicated to enumerate, look at code.
256          */
257         void (*drawFacesTex)(DerivedMesh *dm,
258                                                  int (*setDrawOptions)(struct MTFace *tface,
259                                                          int has_mcol, int matnr),
260                                                 int (*compareDrawOptions)(void *userData,
261                                                          int cur_index,
262                                                          int next_index),
263                                                 void *userData);
264
265         /* Draw all faces with GLSL materials
266          *  o setMaterial is called for every different material nr
267          *  o Only if setMaterial returns true
268          */
269         void (*drawFacesGLSL)(DerivedMesh *dm,
270                 int (*setMaterial)(int, void *attribs));
271
272         /* Draw mapped faces (no color, or texture)
273          *  o Only if !setDrawOptions or
274          *    setDrawOptions(userData, mapped-face-index, drawSmooth_r)
275          *    returns true
276          *
277          * If drawSmooth is set to true then vertex normals should be set and
278          * glShadeModel called with GL_SMOOTH. Otherwise the face normal should
279          * be set and glShadeModel called with GL_FLAT.
280          *
281          * The setDrawOptions is allowed to not set drawSmooth (for example, when
282          * lighting is disabled), in which case the implementation should draw as
283          * smooth shaded.
284          */
285         void (*drawMappedFaces)(DerivedMesh *dm,
286                                                         int (*setDrawOptions)(void *userData, int index,
287                                                                                                   int *drawSmooth_r),
288                                                         int (*setMaterial)(int, void *attribs),
289                                                         int (*compareDrawOptions)(void *userData,
290                                                                                   int cur_index,
291                                                                                   int next_index),
292                                                         void *userData, int useColors);
293
294         /* Draw mapped faces using MTFace 
295          *  o Drawing options too complicated to enumerate, look at code.
296          */
297         void (*drawMappedFacesTex)(DerivedMesh *dm,
298                                                            int (*setDrawOptions)(void *userData,
299                                                                                                          int index),
300                                                            int (*compareDrawOptions)(void *userData,
301                                                                                      int cur_index,
302                                                                                      int next_index),
303                                                            void *userData);
304
305         /* Draw mapped faces with GLSL materials
306          *  o setMaterial is called for every different material nr
307          *  o setDrawOptions is called for every face
308          *  o Only if setMaterial and setDrawOptions return true
309          */
310         void (*drawMappedFacesGLSL)(DerivedMesh *dm,
311                 int (*setMaterial)(int, void *attribs),
312                 int (*setDrawOptions)(void *userData, int index),
313                 void *userData);
314
315         /* Draw mapped edges as lines
316          *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge)
317          *    returns true
318          */
319         void (*drawMappedEdges)(DerivedMesh *dm,
320                                                         int (*setDrawOptions)(void *userData, int index),
321                                                         void *userData);
322
323         /* Draw mapped edges as lines with interpolation values
324          *  o Only if !setDrawOptions or
325          *    setDrawOptions(userData, mapped-edge, mapped-v0, mapped-v1, t)
326          *    returns true
327          *
328          * NOTE: This routine is optional!
329          */
330         void (*drawMappedEdgesInterp)(DerivedMesh *dm, 
331                                                                   int (*setDrawOptions)(void *userData,
332                                                                                                                 int index), 
333                                                                   void (*setDrawInterpOptions)(void *userData,
334                                                                                                                            int index,
335                                                                                                                            float t),
336                                                                   void *userData);
337
338         /* Draw all faces with materials
339          *  o setMaterial is called for every different material nr
340          *  o setFace is called to verify if a face must be hidden
341          */
342         void (*drawMappedFacesMat)(DerivedMesh *dm,
343                 void (*setMaterial)(void *userData, int, void *attribs),
344                 int (*setFace)(void *userData, int index), void *userData);
345
346         /* Release reference to the DerivedMesh. This function decides internally
347          * if the DerivedMesh will be freed, or cached for later use. */
348         void (*release)(DerivedMesh *dm);
349 };
350
351 /* utility function to initialise a DerivedMesh's function pointers to
352  * the default implementation (for those functions which have a default)
353  */
354 void DM_init_funcs(DerivedMesh *dm);
355
356 /* utility function to initialise a DerivedMesh for the desired number
357  * of vertices, edges and faces (doesn't allocate memory for them, just
358  * sets up the custom data layers)
359  */
360 void DM_init(DerivedMesh *dm, DerivedMeshType type,
361              int numVerts, int numEdges, int numFaces);
362
363 /* utility function to initialise a DerivedMesh for the desired number
364  * of vertices, edges and faces, with a layer setup copied from source
365  */
366 void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
367                                           DerivedMeshType type,
368                                           int numVerts, int numEdges, int numFaces);
369
370 /* utility function to release a DerivedMesh's layers
371  * returns 1 if DerivedMesh has to be released by the backend, 0 otherwise
372  */
373 int DM_release(DerivedMesh *dm);
374
375 /* utility function to convert a DerivedMesh to a Mesh
376  */
377 void DM_to_mesh(DerivedMesh *dm, struct Mesh *me);
378
379 /* utility function to convert a DerivedMesh to a shape key block 
380  */
381 void DM_to_meshkey(DerivedMesh *dm, struct Mesh *me, struct KeyBlock *kb);
382
383 /* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
384  * zero for the layer type, so only layer types specified by the mask
385  * will be copied
386  */
387 void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask);
388
389 /* adds a vertex/edge/face custom data layer to a DerivedMesh, optionally
390  * backed by an external data array
391  * alloctype defines how the layer is allocated or copied, and how it is
392  * freed, see BKE_customdata.h for the different options
393  */
394 void DM_add_vert_layer(struct DerivedMesh *dm, int type, int alloctype,
395                                            void *layer);
396 void DM_add_edge_layer(struct DerivedMesh *dm, int type, int alloctype,
397                                            void *layer);
398 void DM_add_face_layer(struct DerivedMesh *dm, int type, int alloctype,
399                                            void *layer);
400
401 /* custom data access functions
402  * return pointer to data from first layer which matches type
403  * if they return NULL for valid indices, data doesn't exist
404  * note these return pointers - any change modifies the internals of the mesh
405  */
406 void *DM_get_vert_data(struct DerivedMesh *dm, int index, int type);
407 void *DM_get_edge_data(struct DerivedMesh *dm, int index, int type);
408 void *DM_get_face_data(struct DerivedMesh *dm, int index, int type);
409
410 /* custom data layer access functions
411  * return pointer to first data layer which matches type (a flat array)
412  * if they return NULL, data doesn't exist
413  * note these return pointers - any change modifies the internals of the mesh
414  */
415 void *DM_get_vert_data_layer(struct DerivedMesh *dm, int type);
416 void *DM_get_edge_data_layer(struct DerivedMesh *dm, int type);
417 void *DM_get_face_data_layer(struct DerivedMesh *dm, int type);
418
419 /* custom data setting functions
420  * copy supplied data into first layer of type using layer's copy function
421  * (deep copy if appropriate)
422  */
423 void DM_set_vert_data(struct DerivedMesh *dm, int index, int type, void *data);
424 void DM_set_edge_data(struct DerivedMesh *dm, int index, int type, void *data);
425 void DM_set_face_data(struct DerivedMesh *dm, int index, int type, void *data);
426
427 /* custom data copy functions
428  * copy count elements from source_index in source to dest_index in dest
429  * these copy all layers for which the CD_FLAG_NOCOPY flag is not set
430  */
431 void DM_copy_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest,
432                                            int source_index, int dest_index, int count);
433 void DM_copy_edge_data(struct DerivedMesh *source, struct DerivedMesh *dest,
434                                            int source_index, int dest_index, int count);
435 void DM_copy_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
436                                            int source_index, int dest_index, int count);
437
438 /* custom data free functions
439  * free count elements, starting at index
440  * they free all layers for which the CD_FLAG_NOCOPY flag is not set
441  */
442 void DM_free_vert_data(struct DerivedMesh *dm, int index, int count);
443 void DM_free_edge_data(struct DerivedMesh *dm, int index, int count);
444 void DM_free_face_data(struct DerivedMesh *dm, int index, int count);
445
446 /* interpolates vertex data from the vertices indexed by src_indices in the
447  * source mesh using the given weights and stores the result in the vertex
448  * indexed by dest_index in the dest mesh
449  */
450 void DM_interp_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest,
451                                                  int *src_indices, float *weights,
452                                                  int count, int dest_index);
453
454 /* interpolates edge data from the edges indexed by src_indices in the
455  * source mesh using the given weights and stores the result in the edge indexed
456  * by dest_index in the dest mesh.
457  * if weights is NULL, all weights default to 1.
458  * if vert_weights is non-NULL, any per-vertex edge data is interpolated using
459  * vert_weights[i] multiplied by weights[i].
460  */
461 typedef float EdgeVertWeight[SUB_ELEMS_EDGE][SUB_ELEMS_EDGE];
462 void DM_interp_edge_data(struct DerivedMesh *source, struct DerivedMesh *dest,
463                                                  int *src_indices,
464                                                  float *weights, EdgeVertWeight *vert_weights,
465                                                  int count, int dest_index);
466
467 /* interpolates face data from the faces indexed by src_indices in the
468  * source mesh using the given weights and stores the result in the face indexed
469  * by dest_index in the dest mesh.
470  * if weights is NULL, all weights default to 1.
471  * if vert_weights is non-NULL, any per-vertex face data is interpolated using
472  * vert_weights[i] multiplied by weights[i].
473  */
474 typedef float FaceVertWeight[SUB_ELEMS_FACE][SUB_ELEMS_FACE];
475 void DM_interp_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
476                                                  int *src_indices,
477                                                  float *weights, FaceVertWeight *vert_weights,
478                                                  int count, int dest_index);
479
480 void DM_swap_face_data(struct DerivedMesh *dm, int index, const int *corner_indices);
481
482 /* Temporary? A function to give a colorband to derivedmesh for vertexcolor ranges */
483 void vDM_ColorBand_store(struct ColorBand *coba);
484
485 /* Simple function to get me->totvert amount of vertices/normals,
486    correctly deformed and subsurfered. Needed especially when vertexgroups are involved.
487    In use now by vertex/weigt paint and particles */
488 float *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob);
489
490         /* */
491 DerivedMesh *mesh_get_derived_final(struct Scene *scene, struct Object *ob,
492                                                                         CustomDataMask dataMask);
493 DerivedMesh *mesh_get_derived_deform(struct Scene *scene, struct Object *ob,
494                                                                          CustomDataMask dataMask);
495
496 DerivedMesh *mesh_create_derived_for_modifier(struct Scene *scene, struct Object *ob, struct ModifierData *md);
497
498 DerivedMesh *mesh_create_derived_render(struct Scene *scene, struct Object *ob,
499                                                                                 CustomDataMask dataMask);
500
501 DerivedMesh *mesh_create_derived_index_render(struct Scene *scene, struct Object *ob, CustomDataMask dataMask, int index);
502
503                 /* same as above but wont use render settings */
504 DerivedMesh *mesh_create_derived(struct Mesh *me, struct Object *ob, float (*vertCos)[3]);
505 DerivedMesh *mesh_create_derived_view(struct Scene *scene, struct Object *ob,
506                                                                           CustomDataMask dataMask);
507 DerivedMesh *mesh_create_derived_no_deform(struct Scene *scene, struct Object *ob,
508                                                                                    float (*vertCos)[3],
509                                                                                    CustomDataMask dataMask);
510 DerivedMesh *mesh_create_derived_no_deform_render(struct Scene *scene, struct Object *ob,
511                                                                                                   float (*vertCos)[3],
512                                                                                                   CustomDataMask dataMask);
513 /* for gameengine */
514 DerivedMesh *mesh_create_derived_no_virtual(struct Scene *scene, struct Object *ob, float (*vertCos)[3],
515                                                                                         CustomDataMask dataMask);
516 DerivedMesh *mesh_create_derived_physics(struct Scene *scene, struct Object *ob, float (*vertCos)[3],
517                                                                                         CustomDataMask dataMask);
518
519 DerivedMesh *editmesh_get_derived(struct EditMesh *em, float (*vertexCos)[3]);
520 DerivedMesh *editmesh_get_derived_base(struct Object *, struct EditMesh *em);
521 DerivedMesh *editmesh_get_derived_cage(struct Scene *scene, struct Object *, 
522                                                                            struct EditMesh *em, CustomDataMask dataMask);
523 DerivedMesh *editmesh_get_derived_cage_and_final(struct Scene *scene, struct Object *, 
524                                                                                                  struct EditMesh *em, DerivedMesh **final_r,
525                                                                                                  CustomDataMask dataMask);
526 float (*editmesh_get_vertex_cos(struct EditMesh *em, int *numVerts_r))[3];
527 int editmesh_modifier_is_enabled(struct Scene *scene, struct ModifierData *md, DerivedMesh *dm);
528 void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct EditMesh *em, CustomDataMask dataMask);
529
530 /* returns an array of deform matrices for crazyspace correction, and the
531    number of modifiers left */
532 int editmesh_get_first_deform_matrices(struct Scene *, struct Object *, struct EditMesh *em,
533                                                                            float (**deformmats)[3][3], float (**deformcos)[3]);
534
535 /* returns an array of deform matrices for crazyspace correction when sculpting,
536    and the number of modifiers left */
537 int sculpt_get_deform_matrices(struct Scene *scene, struct Object *ob,
538                                                                 float (**deformmats)[3][3], float (**deformcos)[3]);
539
540 void weight_to_rgb(float r_rgb[3], const float weight);
541
542 /* convert layers requested by a GLSL material to actually available layers in
543  * the DerivedMesh, with both a pointer for arrays and an offset for editmesh */
544 typedef struct DMVertexAttribs {
545         struct {
546                 struct MTFace *array;
547                 int emOffset, glIndex, glTexco;
548         } tface[MAX_MTFACE];
549
550         struct {
551                 struct MCol *array;
552                 int emOffset, glIndex;
553         } mcol[MAX_MCOL];
554
555         struct {
556                 float (*array)[4];
557                 int emOffset, glIndex;
558         } tang;
559
560         struct {
561                 float (*array)[3];
562                 int emOffset, glIndex, glTexco;
563         } orco;
564
565         int tottface, totmcol, tottang, totorco;
566 } DMVertexAttribs;
567
568 /* should be local, bmesh replaces this */
569 typedef struct {
570         DerivedMesh dm;
571
572         struct EditMesh *em;
573         float (*vertexCos)[3];
574         float (*vertexNos)[3];
575         float (*faceNos)[3];
576 } EditMeshDerivedMesh;
577
578 void DM_vertex_attributes_from_gpu(DerivedMesh *dm,
579         struct GPUVertexAttribs *gattribs, DMVertexAttribs *attribs);
580
581 void DM_add_tangent_layer(DerivedMesh *dm);
582 void DM_calc_auto_bump_scale(DerivedMesh *dm);
583
584 /* Set object's bounding box based on DerivedMesh min/max data */
585 void DM_set_object_boundbox(struct Object *ob, DerivedMesh *dm);
586
587 #endif
588