Added custom face data support in edit mode. The code used to do this is
[blender.git] / source / blender / blenkernel / intern / cdderivedmesh.c
1 /*
2 * $Id$
3 *
4 * ***** BEGIN GPL LICENSE BLOCK *****
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software  Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * The Original Code is Copyright (C) 2006 Blender Foundation.
21 * All rights reserved.
22 *
23 * The Original Code is: all of this file.
24 *
25 * Contributor(s): Ben Batt <benbatt@gmail.com>
26 *
27 * ***** END GPL LICENSE BLOCK *****
28 *
29 * Implementation of CDDerivedMesh.
30 *
31 * BKE_cdderivedmesh.h contains the function prototypes for this file.
32 *
33 */ 
34
35 /* TODO maybe BIF_gl.h should include string.h? */
36 #include <string.h>
37 #include "BIF_gl.h"
38
39 #include "BKE_cdderivedmesh.h"
40 #include "BKE_customdata.h"
41 #include "BKE_DerivedMesh.h"
42 #include "BKE_displist.h"
43 #include "BKE_mesh.h"
44 #include "BKE_utildefines.h"
45
46 #include "BLI_arithb.h"
47 #include "BLI_blenlib.h"
48 #include "BLI_edgehash.h"
49 #include "BLI_editVert.h"
50 #include "BLI_ghash.h"
51
52 #include "DNA_mesh_types.h"
53 #include "DNA_meshdata_types.h"
54
55 #include "MEM_guardedalloc.h"
56
57 #include <string.h>
58 #include <limits.h>
59
60
61 /**************** DerivedMesh interface functions ****************/
62 static int cdDM_getNumVerts(DerivedMesh *dm)
63 {
64         return dm->vertData.numElems;
65 }
66
67 static int cdDM_getNumFaces(DerivedMesh *dm)
68 {
69         return dm->faceData.numElems;
70 }
71
72 static int cdDM_getNumEdges(DerivedMesh *dm)
73 {
74         return dm->edgeData.numElems;
75 }
76
77 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
78 {
79         *vert_r = *CDDM_get_vert(dm, index);
80 }
81
82 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
83 {
84         *edge_r = *CDDM_get_edge(dm, index);
85 }
86
87 static void cdDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
88 {
89         *face_r = *CDDM_get_face(dm, index);
90 }
91
92 static void cdDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
93 {
94         memcpy(vert_r, CDDM_get_verts(dm), sizeof(*vert_r) * dm->getNumVerts(dm));
95 }
96
97 static void cdDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
98 {
99         memcpy(edge_r, CDDM_get_edges(dm), sizeof(*edge_r) * dm->getNumEdges(dm));
100 }
101
102 static void cdDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
103 {
104         memcpy(face_r, CDDM_get_faces(dm), sizeof(*face_r) * dm->getNumFaces(dm));
105 }
106
107 static void cdDM_foreachMappedVert(
108                            DerivedMesh *dm,
109                            void (*func)(void *userData, int index, float *co,
110                                         float *no_f, short *no_s),
111                            void *userData)
112 {
113         int i;
114         int maxVerts = dm->getNumVerts(dm);
115         MVert *mv = CDDM_get_verts(dm);
116         int *index = DM_get_vert_data_layer(dm, LAYERTYPE_ORIGINDEX);
117
118         for(i = 0; i < maxVerts; i++, mv++, index++) {
119                 if(*index == ORIGINDEX_NONE) continue;
120
121                 func(userData, *index, mv->co, NULL, mv->no);
122         }
123 }
124
125 static void cdDM_foreachMappedEdge(
126                            DerivedMesh *dm,
127                            void (*func)(void *userData, int index,
128                                         float *v0co, float *v1co),
129                            void *userData)
130 {
131         int i;
132         int maxEdges = dm->getNumEdges(dm);
133         MEdge *med = CDDM_get_edges(dm);
134         MVert *mv = CDDM_get_verts(dm);
135         int *index = DM_get_edge_data_layer(dm, LAYERTYPE_ORIGINDEX);
136
137         for(i = 0; i < maxEdges; i++, med++, index++) {
138                 if(*index == ORIGINDEX_NONE) continue;
139
140                 func(userData, *index, mv[med->v1].co, mv[med->v2].co);
141         }
142 }
143
144 static void cdDM_foreachMappedFaceCenter(
145                            DerivedMesh *dm,
146                            void (*func)(void *userData, int index,
147                                         float *cent, float *no),
148                            void *userData)
149 {
150         int i;
151         int maxFaces = dm->getNumFaces(dm);
152         MFace *mf = CDDM_get_faces(dm);
153         MVert *mv = CDDM_get_verts(dm);
154         int *index = DM_get_face_data_layer(dm, LAYERTYPE_ORIGINDEX);
155
156         for(i = 0; i < maxFaces; i++, mf++, index++) {
157                 float cent[3];
158                 float no[3];
159
160                 if(*index == ORIGINDEX_NONE) continue;
161
162                 VECCOPY(cent, mv[mf->v1].co);
163                 VecAddf(cent, cent, mv[mf->v2].co);
164                 VecAddf(cent, cent, mv[mf->v3].co);
165
166                 if (mf->v4) {
167                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
168                                        mv[mf->v3].co, mv[mf->v4].co, no);
169                         VecAddf(cent, cent, mv[mf->v4].co);
170                         VecMulf(cent, 0.25f);
171                 } else {
172                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
173                                       mv[mf->v3].co, no);
174                         VecMulf(cent, 0.33333333333f);
175                 }
176
177                 func(userData, *index, cent, no);
178         }
179 }
180
181 static DispListMesh *cdDM_convertToDispListMesh(DerivedMesh *dm,
182                                                 int allowShared)
183 {
184         DispListMesh *dlm = MEM_callocN(sizeof(*dlm),
185                                         "cdDM_convertToDispListMesh dlm");
186
187         dlm->totvert = dm->vertData.numElems;
188         dlm->totedge = dm->edgeData.numElems;
189         dlm->totface = dm->faceData.numElems;
190         dlm->mvert = dm->dupVertArray(dm);
191         dlm->medge = dm->dupEdgeArray(dm);
192         dlm->mface = dm->dupFaceArray(dm);
193
194         dlm->tface = dm->getFaceDataArray(dm, LAYERTYPE_TFACE);
195         if(dlm->tface)
196                 dlm->tface = MEM_dupallocN(dlm->tface);
197
198         dlm->mcol = dm->getFaceDataArray(dm, LAYERTYPE_MCOL);
199         if(dlm->mcol)
200                 dlm->mcol = MEM_dupallocN(dlm->mcol);
201
202         dlm->nors = NULL;
203         dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 0;
204
205         return dlm;
206 }
207
208 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
209 {
210         int i;
211
212         for(i = 0; i < dm->vertData.numElems; i++) {
213                 DO_MINMAX(CDDM_get_vert(dm, i)->co, min_r, max_r);
214         }
215 }
216
217 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
218 {
219         VECCOPY(co_r, CDDM_get_vert(dm, index)->co);
220 }
221
222 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
223 {
224         int i;
225         MVert *mv = CDDM_get_verts(dm);
226
227         for(i = 0; i < dm->vertData.numElems; i++, mv++)
228                 VECCOPY(cos_r[i], mv->co);
229 }
230
231 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
232 {
233         short *no = CDDM_get_vert(dm, index)->no;
234
235         no_r[0] = no[0] / 32767.f;
236         no_r[1] = no[1] / 32767.f;
237         no_r[2] = no[2] / 32767.f;
238 }
239
240 static void cdDM_drawVerts(DerivedMesh *dm)
241 {
242         int i;
243         MVert *mv = CDDM_get_verts(dm);
244
245         glBegin(GL_POINTS);
246         for(i = 0; i < dm->vertData.numElems; i++, mv++)
247                 glVertex3fv(mv->co);
248         glEnd();
249 }
250
251 static void cdDM_drawUVEdges(DerivedMesh *dm)
252 {
253         int i;
254         TFace *tf = DM_get_face_data_layer(dm, LAYERTYPE_TFACE);
255         MFace *mf = CDDM_get_faces(dm);
256
257         if(tf) {
258                 glBegin(GL_LINES);
259                 for(i = 0; i < dm->faceData.numElems; i++, tf++, mf++) {
260                         if(!(tf->flag&TF_HIDE)) {
261                                 glVertex2fv(tf->uv[0]);
262                                 glVertex2fv(tf->uv[1]);
263
264                                 glVertex2fv(tf->uv[1]);
265                                 glVertex2fv(tf->uv[2]);
266
267                                 if(!mf->v4) {
268                                         glVertex2fv(tf->uv[2]);
269                                         glVertex2fv(tf->uv[0]);
270                                 } else {
271                                         glVertex2fv(tf->uv[2]);
272                                         glVertex2fv(tf->uv[3]);
273
274                                         glVertex2fv(tf->uv[3]);
275                                         glVertex2fv(tf->uv[0]);
276                                 }
277                         }
278                 }
279                 glEnd();
280         }
281 }
282
283 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
284 {
285         int i;
286         MEdge *medge = CDDM_get_edges(dm);
287         MVert *mvert = CDDM_get_verts(dm);
288                 
289         glBegin(GL_LINES);
290         for(i = 0; i < dm->edgeData.numElems; i++, medge++) {
291                 if((medge->flag&ME_EDGEDRAW)
292                    && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
293                         glVertex3fv(mvert[medge->v1].co);
294                         glVertex3fv(mvert[medge->v2].co);
295                 }
296         }
297         glEnd();
298 }
299
300 static void cdDM_drawLooseEdges(DerivedMesh *dm)
301 {
302         MEdge *medge = CDDM_get_edges(dm);
303         MVert *mvert = CDDM_get_verts(dm);
304         int i;
305
306         glBegin(GL_LINES);
307         for(i = 0; i < dm->edgeData.numElems; i++, medge++) {
308                 if(medge->flag&ME_LOOSEEDGE) {
309                         glVertex3fv(mvert[medge->v1].co);
310                         glVertex3fv(mvert[medge->v2].co);
311                 }
312         }
313         glEnd();
314 }
315
316 static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
317 {
318         int a;
319         int glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
320         MFace *mface = CDDM_get_faces(dm);
321         MVert *mvert = CDDM_get_verts(dm);
322
323 #define PASSVERT(index) {                                               \
324         if(shademodel == GL_SMOOTH) {                           \
325                 short *no = mvert[index].no;                    \
326                 glNormal3sv(no);                                                \
327         }                                                                                       \
328         glVertex3fv(mvert[index].co);   \
329 }
330
331         glBegin(glmode = GL_QUADS);
332         for(a = 0; a < dm->faceData.numElems; a++, mface++) {
333                 int new_glmode, new_matnr, new_shademodel;
334
335                 new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
336                 new_matnr = mface->mat_nr + 1;
337                 new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
338                 
339                 if(new_glmode != glmode || new_matnr != matnr
340                    || new_shademodel != shademodel) {
341                         glEnd();
342
343                         drawCurrentMat = setMaterial(matnr = new_matnr);
344
345                         glShadeModel(shademodel = new_shademodel);
346                         glBegin(glmode = new_glmode);
347                 } 
348                 
349                 if(drawCurrentMat) {
350                         /* TODO make this better (cache facenormals as layer?) */
351                         if(shademodel == GL_FLAT) {
352                                 float nor[3];
353                                 if(mface->v4) {
354                                         CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
355                                                        mvert[mface->v3].co, mvert[mface->v4].co,
356                                                        nor);
357                                 } else {
358                                         CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
359                                                       mvert[mface->v3].co, nor);
360                                 }
361                                 glNormal3fv(nor);
362                         }
363
364                         PASSVERT(mface->v1);
365                         PASSVERT(mface->v2);
366                         PASSVERT(mface->v3);
367                         if(mface->v4) {
368                                 PASSVERT(mface->v4);
369                         }
370                 }
371         }
372         glEnd();
373
374         glShadeModel(GL_FLAT);
375 #undef PASSVERT
376 }
377
378 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
379 {
380         int a, glmode;
381         unsigned char *cp1, *cp2;
382         MFace *mface = CDDM_get_faces(dm);
383         MVert *mvert = CDDM_get_verts(dm);
384
385         cp1 = col1;
386         if(col2) {
387                 cp2 = col2;
388         } else {
389                 cp2 = NULL;
390                 useTwoSided = 0;
391         }
392
393         /* there's a conflict here... twosided colors versus culling...? */
394         /* defined by history, only texture faces have culling option */
395         /* we need that as mesh option builtin, next to double sided lighting */
396         if(col1 && col2)
397                 glEnable(GL_CULL_FACE);
398         
399         glShadeModel(GL_SMOOTH);
400         glBegin(glmode = GL_QUADS);
401         for(a = 0; a < dm->faceData.numElems; a++, mface++, cp1 += 16) {
402                 int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
403
404                 if(new_glmode != glmode) {
405                         glEnd();
406                         glBegin(glmode = new_glmode);
407                 }
408                         
409                 glColor3ub(cp1[3], cp1[2], cp1[1]);
410                 glVertex3fv(mvert[mface->v1].co);
411                 glColor3ub(cp1[7], cp1[6], cp1[5]);
412                 glVertex3fv(mvert[mface->v2].co);
413                 glColor3ub(cp1[11], cp1[10], cp1[9]);
414                 glVertex3fv(mvert[mface->v3].co);
415                 if(mface->v4) {
416                         glColor3ub(cp1[15], cp1[14], cp1[13]);
417                         glVertex3fv(mvert[mface->v4].co);
418                 }
419                         
420                 if(useTwoSided) {
421                         glColor3ub(cp2[11], cp2[10], cp2[9]);
422                         glVertex3fv(mvert[mface->v3].co );
423                         glColor3ub(cp2[7], cp2[6], cp2[5]);
424                         glVertex3fv(mvert[mface->v2].co );
425                         glColor3ub(cp2[3], cp2[2], cp2[1]);
426                         glVertex3fv(mvert[mface->v1].co );
427                         if(mface->v4) {
428                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
429                                 glVertex3fv(mvert[mface->v4].co );
430                         }
431                 }
432                 if(col2) cp2 += 16;
433         }
434         glEnd();
435
436         glShadeModel(GL_FLAT);
437         glDisable(GL_CULL_FACE);
438 }
439
440 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
441                int (*drawParams)(TFace *tface, int matnr),
442                int (*drawParamsMapped)(void *userData, int index),
443                void *userData) 
444 {
445         int i;
446         MFace *mf = CDDM_get_faces(dm);
447         TFace *tf = DM_get_face_data_layer(dm, LAYERTYPE_TFACE);
448         MVert *mv = CDDM_get_verts(dm);
449         int *index = DM_get_face_data_layer(dm, LAYERTYPE_ORIGINDEX);
450
451         for(i = 0; i < dm->faceData.numElems; i++, mf++, index++) {
452                 MVert *mvert;
453                 int flag;
454                 unsigned char *cp = NULL;
455
456                 if(drawParams)
457                         if(tf) flag = drawParams(&tf[i], mf->mat_nr);
458                         else flag = drawParams(NULL, mf->mat_nr);
459                 else if(*index != ORIGINDEX_NONE)
460                         flag = drawParamsMapped(userData, *index);
461                 else
462                         flag = 0;
463
464                 if(flag == 0) {
465                         continue;
466                 } else if(flag == 1) {
467                         if(tf) {
468                                 cp = (unsigned char *)tf[i].col;
469                         } else {
470                                 cp = DM_get_face_data(dm, i, LAYERTYPE_MCOL);
471                         }
472                 }
473
474                 /* TODO make this better (cache facenormals as layer?) */
475                 if(!(mf->flag&ME_SMOOTH)) {
476                         float nor[3];
477                         if(mf->v4) {
478                                 CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
479                                                            mv[mf->v3].co, mv[mf->v4].co, nor);
480                         } else {
481                                 CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
482                                                           mv[mf->v3].co, nor);
483                         }
484                         glNormal3fv(nor);
485                 }
486
487                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
488                 if(tf) glTexCoord2fv(tf[i].uv[0]);
489                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
490                 mvert = &mv[mf->v1];
491                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
492                 glVertex3fv(mvert->co);
493                         
494                 if(tf) glTexCoord2fv(tf[i].uv[1]);
495                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
496                 mvert = &mv[mf->v2];
497                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
498                 glVertex3fv(mvert->co);
499
500                 if(tf) glTexCoord2fv(tf[i].uv[2]);
501                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
502                 mvert = &mv[mf->v3];
503                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
504                 glVertex3fv(mvert->co);
505
506                 if(mf->v4) {
507                         if(tf) glTexCoord2fv(tf[i].uv[3]);
508                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
509                         mvert = &mv[mf->v4];
510                         if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
511                         glVertex3fv(mvert->co);
512                 }
513                 glEnd();
514         }
515 }
516
517 static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(TFace *tface, int matnr))
518 {
519         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
520 }
521
522 static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
523 {
524         int i;
525         MFace *mf = CDDM_get_faces(dm);
526         MVert *mv = CDDM_get_verts(dm);
527         int *index = DM_get_face_data_layer(dm, LAYERTYPE_ORIGINDEX);
528         TFace *tf = DM_get_face_data_layer(dm, LAYERTYPE_TFACE);
529         MCol *mc = DM_get_face_data_layer(dm, LAYERTYPE_MCOL);
530
531         for(i = 0; i < dm->faceData.numElems; i++, mf++, index++) {
532                 int drawSmooth = (mf->flag & ME_SMOOTH);
533
534                 if(setDrawOptions && *index == ORIGINDEX_NONE) continue;
535
536                 if(!setDrawOptions || setDrawOptions(userData, *index, &drawSmooth)) {
537                         unsigned char *cp = NULL;
538
539                         if(useColors) {
540                                 if(tf) {
541                                         cp = (unsigned char *)tf[i].col;
542                                 } else if(mc) {
543                                         cp = (unsigned char *)&mc[i * 4];
544                                 }
545                         }
546
547                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
548                         glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
549
550                         if(!drawSmooth) {
551                                 /* TODO make this better (cache facenormals as layer?) */
552                                 float nor[3];
553                                 if(mf->v4) {
554                                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
555                                                                    mv[mf->v3].co, mv[mf->v4].co, nor);
556                                 } else {
557                                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
558                                                                   mv[mf->v3].co, nor);
559                                 }
560                                 glNormal3fv(nor);
561
562                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
563                                 glVertex3fv(mv[mf->v1].co);
564                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
565                                 glVertex3fv(mv[mf->v2].co);
566                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
567                                 glVertex3fv(mv[mf->v3].co);
568                                 if(mf->v4) {
569                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
570                                         glVertex3fv(mv[mf->v4].co);
571                                 }
572                         } else {
573                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
574                                 glNormal3sv(mv[mf->v1].no);
575                                 glVertex3fv(mv[mf->v1].co);
576                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
577                                 glNormal3sv(mv[mf->v2].no);
578                                 glVertex3fv(mv[mf->v2].co);
579                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
580                                 glNormal3sv(mv[mf->v3].no);
581                                 glVertex3fv(mv[mf->v3].co);
582                                 if(mf->v4) {
583                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
584                                         glNormal3sv(mv[mf->v4].no);
585                                         glVertex3fv(mv[mf->v4].co);
586                                 }
587                         }
588
589                         glEnd();
590                 }
591         }
592 }
593
594 static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
595 {
596         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
597 }
598
599 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
600 {
601         int i;
602         int *index = DM_get_edge_data_layer(dm, LAYERTYPE_ORIGINDEX);
603         MEdge *edge = CDDM_get_edges(dm);
604         MVert *vert = CDDM_get_verts(dm);
605
606         glBegin(GL_LINES);
607         for(i = 0; i < dm->edgeData.numElems; i++, edge++, index++) {
608
609                 if(setDrawOptions && *index == ORIGINDEX_NONE) continue;
610
611                 if(!setDrawOptions || setDrawOptions(userData, *index)) {
612                         glVertex3fv(vert[edge->v1].co);
613                         glVertex3fv(vert[edge->v2].co);
614                 }
615         }
616         glEnd();
617 }
618
619 static void cdDM_release(DerivedMesh *dm)
620 {
621         CustomData_free(&dm->vertData);
622         CustomData_free(&dm->edgeData);
623         CustomData_free(&dm->faceData);
624
625         MEM_freeN(dm);
626 }
627
628
629 /**************** CDDM interface functions ****************/
630 static DerivedMesh *cdDM_create(const char *desc)
631 {
632         DerivedMesh *dm;
633
634         dm = MEM_callocN(sizeof(*dm), desc);
635
636         dm->getMinMax = cdDM_getMinMax;
637
638         dm->convertToDispListMesh = cdDM_convertToDispListMesh;
639
640         dm->getNumVerts = cdDM_getNumVerts;
641         dm->getNumFaces = cdDM_getNumFaces;
642         dm->getNumEdges = cdDM_getNumEdges;
643
644         dm->getVert = cdDM_getVert;
645         dm->getEdge = cdDM_getEdge;
646         dm->getFace = cdDM_getFace;
647         dm->getVertArray = cdDM_getVertArray;
648         dm->getEdgeArray = cdDM_getEdgeArray;
649         dm->getFaceArray = cdDM_getFaceArray;
650         dm->getVertData = DM_get_vert_data;
651         dm->getEdgeData = DM_get_edge_data;
652         dm->getFaceData = DM_get_face_data;
653         dm->getVertDataArray = DM_get_vert_data_layer;
654         dm->getEdgeDataArray = DM_get_edge_data_layer;
655         dm->getFaceDataArray = DM_get_face_data_layer;
656
657         dm->getVertCos = cdDM_getVertCos;
658         dm->getVertCo = cdDM_getVertCo;
659         dm->getVertNo = cdDM_getVertNo;
660
661         dm->drawVerts = cdDM_drawVerts;
662
663         dm->drawUVEdges = cdDM_drawUVEdges;
664         dm->drawEdges = cdDM_drawEdges;
665         dm->drawLooseEdges = cdDM_drawLooseEdges;
666         dm->drawMappedEdges = cdDM_drawMappedEdges;
667
668         dm->drawFacesSolid = cdDM_drawFacesSolid;
669         dm->drawFacesColored = cdDM_drawFacesColored;
670         dm->drawFacesTex = cdDM_drawFacesTex;
671         dm->drawMappedFaces = cdDM_drawMappedFaces;
672         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
673
674         dm->foreachMappedVert = cdDM_foreachMappedVert;
675         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
676         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
677
678         dm->release = cdDM_release;
679
680         return dm;
681 }
682
683 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces)
684 {
685         DerivedMesh *dm = cdDM_create("CDDM_new dm");
686         DM_init(dm, numVerts, numEdges, numFaces);
687
688         CustomData_add_layer(&dm->vertData, LAYERTYPE_MVERT, LAYERFLAG_NOCOPY,
689                              NULL);
690         CustomData_add_layer(&dm->edgeData, LAYERTYPE_MEDGE, LAYERFLAG_NOCOPY,
691                              NULL);
692         CustomData_add_layer(&dm->faceData, LAYERTYPE_MFACE, LAYERFLAG_NOCOPY,
693                              NULL);
694
695         return dm;
696 }
697
698 DerivedMesh *CDDM_from_mesh(Mesh *mesh)
699 {
700         DerivedMesh *dm = CDDM_new(mesh->totvert, mesh->totedge, mesh->totface);
701         int i;
702
703         if(mesh->msticky)
704                 CustomData_add_layer(&dm->vertData, LAYERTYPE_MSTICKY, 0, NULL);
705         if(mesh->dvert)
706                 CustomData_add_layer(&dm->vertData, LAYERTYPE_MDEFORMVERT, 0, NULL);
707
708         if(mesh->tface)
709                 CustomData_add_layer(&dm->faceData, LAYERTYPE_TFACE, 0, NULL);
710         if(mesh->mcol)
711                 CustomData_add_layer(&dm->faceData, LAYERTYPE_MCOL, 0, NULL);
712
713         for(i = 0; i < mesh->totvert; ++i) {
714                 DM_set_vert_data(dm, i, LAYERTYPE_MVERT, &mesh->mvert[i]);
715                 if(mesh->msticky)
716                         DM_set_vert_data(dm, i, LAYERTYPE_MSTICKY, &mesh->msticky[i]);
717                 if(mesh->dvert)
718                         DM_set_vert_data(dm, i, LAYERTYPE_MDEFORMVERT, &mesh->dvert[i]);
719
720                 DM_set_vert_data(dm, i, LAYERTYPE_ORIGINDEX, &i);
721         }
722
723         for(i = 0; i < mesh->totedge; ++i) {
724                 DM_set_edge_data(dm, i, LAYERTYPE_MEDGE, &mesh->medge[i]);
725
726                 DM_set_edge_data(dm, i, LAYERTYPE_ORIGINDEX, &i);
727         }
728
729         for(i = 0; i < mesh->totface; ++i) {
730                 DM_set_face_data(dm, i, LAYERTYPE_MFACE, &mesh->mface[i]);
731                 if(mesh->tface)
732                         DM_set_face_data(dm, i, LAYERTYPE_TFACE, &mesh->tface[i]);
733                 if(mesh->mcol)
734                         DM_set_face_data(dm, i, LAYERTYPE_MCOL, &mesh->mcol[i * 4]);
735
736                 DM_set_face_data(dm, i, LAYERTYPE_ORIGINDEX, &i);
737         }
738
739         return dm;
740 }
741
742 DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
743 {
744         DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
745                                    BLI_countlist(&em->edges),
746                                    BLI_countlist(&em->faces));
747         EditVert *eve;
748         EditEdge *eed;
749         EditFace *efa;
750         int i;
751         MVert *mvert = CDDM_get_verts(dm);
752         MEdge *medge = CDDM_get_edges(dm);
753         MFace *mface = CDDM_get_faces(dm);
754         int *index;
755         TFace *tf;
756
757         /* set eve->hash to vert index */
758         for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
759                 eve->hash = i;
760
761         if(me->msticky)
762                 CustomData_add_layer(&dm->vertData, LAYERTYPE_MDEFORMVERT, 0, NULL);
763         if(me->dvert)
764                 CustomData_add_layer(&dm->vertData, LAYERTYPE_MDEFORMVERT, 0, NULL);
765
766         if(me->tface)
767                 CustomData_add_layer(&dm->faceData, LAYERTYPE_TFACE, 0, NULL);
768
769         /* Need to be able to mark loose edges */
770         for(eed = em->edges.first; eed; eed = eed->next) {
771                 eed->f2 = 0;
772         }
773         for(efa = em->faces.first; efa; efa = efa->next) {
774                 efa->e1->f2 = 1;
775                 efa->e2->f2 = 1;
776                 efa->e3->f2 = 1;
777                 if(efa->e4) efa->e4->f2 = 1;
778         }
779
780         index = dm->getVertDataArray(dm, LAYERTYPE_ORIGINDEX);
781         for(i = 0, eve = em->verts.first; i < dm->vertData.numElems;
782             i++, eve = eve->next, index++) {
783                 MVert *mv = &mvert[i];
784
785                 VECCOPY(mv->co, eve->co);
786
787                 mv->no[0] = eve->no[0] * 32767.0;
788                 mv->no[1] = eve->no[1] * 32767.0;
789                 mv->no[2] = eve->no[2] * 32767.0;
790
791                 mv->mat_nr = 0;
792                 mv->flag = 0;
793
794                 *index = i;
795
796                 if(me->msticky && eve->keyindex != -1)
797                         DM_set_vert_data(dm, i, LAYERTYPE_MSTICKY,
798                                          &me->msticky[eve->keyindex]);
799                 if(me->dvert && eve->keyindex != -1)
800                         DM_set_vert_data(dm, i, LAYERTYPE_MDEFORMVERT,
801                                          &me->dvert[eve->keyindex]);
802         }
803
804         index = dm->getEdgeDataArray(dm, LAYERTYPE_ORIGINDEX);
805         for(i = 0, eed = em->edges.first; i < dm->edgeData.numElems;
806             i++, eed = eed->next, index++) {
807                 MEdge *med = &medge[i];
808
809                 med->v1 = eed->v1->hash;
810                 med->v2 = eed->v2->hash;
811                 med->crease = (unsigned char) (eed->crease * 255.0f);
812                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
813                 
814                 if(eed->seam) med->flag |= ME_SEAM;
815                 if(eed->sharp) med->flag |= ME_SHARP;
816                 if(!eed->f2) med->flag |= ME_LOOSEEDGE;
817
818                 *index = i;
819         }
820
821         index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
822         for(i = 0, efa = em->faces.first; i < dm->faceData.numElems;
823             i++, efa = efa->next, index++) {
824                 MFace *mf = &mface[i];
825
826                 mf->v1 = efa->v1->hash;
827                 mf->v2 = efa->v2->hash;
828                 mf->v3 = efa->v3->hash;
829                 mf->v4 = efa->v4 ? efa->v4->hash : 0;
830                 mf->mat_nr = efa->mat_nr;
831                 mf->flag = efa->flag;
832                 test_index_face(mf, NULL, NULL, efa->v4?4:3);
833
834                 *index = i;
835
836                 tf = CustomData_em_get(&em->fdata, efa->data, LAYERTYPE_TFACE);
837                 if(tf)
838                         DM_set_face_data(dm, i, LAYERTYPE_TFACE, tf);
839         }
840
841         return dm;
842 }
843
844 DerivedMesh *CDDM_copy(DerivedMesh *source)
845 {
846         DerivedMesh *dest = CDDM_from_template(source,
847                                                source->vertData.numElems,
848                                                source->edgeData.numElems,
849                                                source->faceData.numElems);
850
851         CustomData_copy_data(&source->vertData, &dest->vertData, 0, 0,
852                              source->vertData.numElems);
853         CustomData_copy_data(&source->edgeData, &dest->edgeData, 0, 0,
854                              source->edgeData.numElems);
855         CustomData_copy_data(&source->faceData, &dest->faceData, 0, 0,
856                              source->faceData.numElems);
857
858         /* copy vert/face/edge data from source */
859         source->getVertArray(source, CDDM_get_verts(dest));
860         source->getEdgeArray(source, CDDM_get_edges(dest));
861         source->getFaceArray(source, CDDM_get_faces(dest));
862
863         return dest;
864 }
865
866 DerivedMesh *CDDM_from_template(DerivedMesh *source,
867                                 int numVerts, int numEdges, int numFaces)
868 {
869         DerivedMesh *dest = cdDM_create("CDDM_from_template dest");
870         DM_from_template(dest, source, numVerts, numEdges, numFaces);
871
872         /* if no vert/face/edge layers in custom data, add them */
873         if(!CDDM_get_verts(dest))
874                 CustomData_add_layer(&dest->vertData, LAYERTYPE_MVERT,
875                                      LAYERFLAG_NOCOPY, NULL);
876         if(!CDDM_get_edges(dest))
877                 CustomData_add_layer(&dest->edgeData, LAYERTYPE_MEDGE,
878                                      LAYERFLAG_NOCOPY, NULL);
879         if(!CDDM_get_faces(dest))
880                 CustomData_add_layer(&dest->faceData, LAYERTYPE_MFACE,
881                                      LAYERFLAG_NOCOPY, NULL);
882
883         return dest;
884 }
885
886 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
887 {
888         int i;
889         MVert *vert = CDDM_get_verts(dm);
890
891         for(i = 0; i < dm->vertData.numElems; ++i, ++vert)
892                 VECCOPY(vert->co, vertCoords[i]);
893 }
894
895 /* adapted from mesh_calc_normals */
896 void CDDM_calc_normals(DerivedMesh *dm)
897 {
898         float (*temp_nors)[3];
899         float (*face_nors)[3];
900         int i;
901         int numVerts = dm->getNumVerts(dm);
902         int numFaces = dm->getNumFaces(dm);
903         MFace *mf;
904         MVert *mv = CDDM_get_verts(dm);
905
906         if(!mv) return;
907
908         temp_nors = MEM_callocN(numVerts * sizeof(*temp_nors),
909                                 "CDDM_calc_normals temp_nors");
910         face_nors = MEM_mallocN(numFaces * sizeof(*face_nors),
911                                 "CDDM_calc_normals face_nors");
912
913         mf = CDDM_get_faces(dm);
914         for(i = 0; i < numFaces; i++, mf++) {
915                 float *f_no = face_nors[i];
916
917                 if(mf->v4)
918                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
919                                        mv[mf->v3].co, mv[mf->v4].co, f_no);
920                 else
921                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
922                                       mv[mf->v3].co, f_no);
923                 
924                 VecAddf(temp_nors[mf->v1], temp_nors[mf->v1], f_no);
925                 VecAddf(temp_nors[mf->v2], temp_nors[mf->v2], f_no);
926                 VecAddf(temp_nors[mf->v3], temp_nors[mf->v3], f_no);
927                 if(mf->v4)
928                         VecAddf(temp_nors[mf->v4], temp_nors[mf->v4], f_no);
929         }
930
931         for(i = 0; i < numVerts; i++, mv++) {
932                 float *no = temp_nors[i];
933                 
934                 if (Normalise(no) == 0.0) {
935                         VECCOPY(no, mv->co);
936                         Normalise(no);
937                 }
938
939                 mv->no[0] = (short)(no[0] * 32767.0);
940                 mv->no[1] = (short)(no[1] * 32767.0);
941                 mv->no[2] = (short)(no[2] * 32767.0);
942         }
943         
944         MEM_freeN(temp_nors);
945
946         /* TODO maybe cache face normals here? */
947         MEM_freeN(face_nors);
948 }
949
950 void CDDM_calc_edges(DerivedMesh *dm)
951 {
952         CustomData edgeData;
953         EdgeHash *eh = BLI_edgehash_new();
954         EdgeHashIterator *ehi;
955         int i;
956         int maxFaces = dm->getNumFaces(dm);
957         MFace *mf = CDDM_get_faces(dm);
958         MEdge *med;
959
960         for (i = 0; i < maxFaces; i++, mf++) {
961                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
962                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
963                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
964                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
965                 
966                 if (mf->v4) {
967                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
968                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
969                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
970                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
971                 } else {
972                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
973                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
974                 }
975         }
976
977         CustomData_from_template(&dm->edgeData, &edgeData, 0, BLI_edgehash_size(eh));
978
979         if(!CustomData_get_layer(&edgeData, LAYERTYPE_MEDGE))
980                 CustomData_add_layer(&edgeData, LAYERTYPE_MEDGE,
981                                      LAYERFLAG_NOCOPY, NULL);
982
983         ehi = BLI_edgehashIterator_new(eh);
984         med = CustomData_get_layer(&edgeData, LAYERTYPE_MEDGE);
985         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
986             BLI_edgehashIterator_step(ehi), ++i, ++med) {
987                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
988
989                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
990         }
991         BLI_edgehashIterator_free(ehi);
992
993         CustomData_free(&dm->edgeData);
994         dm->edgeData = edgeData;
995
996         BLI_edgehash_free(eh, NULL);
997 }
998
999 void CDDM_set_num_verts(DerivedMesh *dm, int numVerts)
1000 {
1001         CustomData_set_num_elems(&dm->vertData, numVerts);
1002 }
1003
1004 void CDDM_set_num_edges(DerivedMesh *dm, int numEdges)
1005 {
1006         CustomData_set_num_elems(&dm->edgeData, numEdges);
1007 }
1008
1009 void CDDM_set_num_faces(DerivedMesh *dm, int numFaces)
1010 {
1011         CustomData_set_num_elems(&dm->faceData, numFaces);
1012 }
1013
1014 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
1015 {
1016         return CustomData_get(&dm->vertData, index, LAYERTYPE_MVERT);
1017 }
1018
1019 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
1020 {
1021         return CustomData_get(&dm->edgeData, index, LAYERTYPE_MEDGE);
1022 }
1023
1024 MFace *CDDM_get_face(DerivedMesh *dm, int index)
1025 {
1026         return CustomData_get(&dm->faceData, index, LAYERTYPE_MFACE);
1027 }
1028
1029 MVert *CDDM_get_verts(DerivedMesh *dm)
1030 {
1031         return CustomData_get_layer(&dm->vertData, LAYERTYPE_MVERT);
1032 }
1033
1034 MEdge *CDDM_get_edges(DerivedMesh *dm)
1035 {
1036         return CustomData_get_layer(&dm->edgeData, LAYERTYPE_MEDGE);
1037 }
1038
1039 MFace *CDDM_get_faces(DerivedMesh *dm)
1040 {
1041         return CustomData_get_layer(&dm->faceData, LAYERTYPE_MFACE);
1042 }
1043