Blender V2.61 - r43446

editderivedmesh.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2005 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00032 #include "GL/glew.h"
00033 
00034 #include "BLI_utildefines.h"
00035 #include "BLI_blenlib.h"
00036 #include "BLI_edgehash.h"
00037 #include "BLI_editVert.h"
00038 #include "BLI_math.h"
00039 #include "BLI_pbvh.h"
00040 
00041 #include "BKE_cdderivedmesh.h"
00042 #include "BKE_global.h"
00043 #include "BKE_mesh.h"
00044 #include "BKE_paint.h"
00045 
00046 
00047 #include "DNA_meshdata_types.h"
00048 #include "DNA_object_types.h"
00049 #include "DNA_curve_types.h" /* for Curve */
00050 
00051 #include "MEM_guardedalloc.h"
00052 
00053 #include "GPU_buffers.h"
00054 #include "GPU_draw.h"
00055 #include "GPU_extensions.h"
00056 #include "GPU_material.h"
00057 
00058 #include <string.h>
00059 #include <limits.h>
00060 #include <math.h>
00061 
00062 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
00063 
00064 static void emDM_foreachMappedVert(
00065         DerivedMesh *dm,
00066         void (*func)(void *userData, int index, float *co, float *no_f, short *no_s),
00067         void *userData)
00068 {
00069     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00070     EditVert *eve;
00071     int i;
00072 
00073     for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
00074         if (emdm->vertexCos) {
00075             func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL);
00076         }
00077         else {
00078             func(userData, i, eve->co, eve->no, NULL);
00079         }
00080     }
00081 }
00082 static void emDM_foreachMappedEdge(
00083         DerivedMesh *dm,
00084         void (*func)(void *userData, int index, float *v0co, float *v1co),
00085         void *userData)
00086 {
00087     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00088     EditEdge *eed;
00089     int i;
00090 
00091     if (emdm->vertexCos) {
00092         EditVert *eve;
00093 
00094         for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
00095             eve->tmp.l = (intptr_t) i++;
00096         for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
00097             func(userData, i, emdm->vertexCos[(int) eed->v1->tmp.l], emdm->vertexCos[(int) eed->v2->tmp.l]);
00098     }
00099     else {
00100         for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
00101             func(userData, i, eed->v1->co, eed->v2->co);
00102     }
00103 }
00104 
00105 static void emDM_drawMappedEdges(
00106         DerivedMesh *dm,
00107         int (*setDrawOptions)(void *userData, int index),
00108         void *userData)
00109 {
00110     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00111     EditEdge *eed;
00112     int i;
00113 
00114     if (emdm->vertexCos) {
00115         EditVert *eve;
00116 
00117         for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
00118             eve->tmp.l = (intptr_t) i++;
00119 
00120         glBegin(GL_LINES);
00121         for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
00122             if (!setDrawOptions || setDrawOptions(userData, i)) {
00123                 glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]);
00124                 glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]);
00125             }
00126         }
00127         glEnd();
00128     }
00129     else {
00130         glBegin(GL_LINES);
00131         for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
00132             if (!setDrawOptions || setDrawOptions(userData, i)) {
00133                 glVertex3fv(eed->v1->co);
00134                 glVertex3fv(eed->v2->co);
00135             }
00136         }
00137         glEnd();
00138     }
00139 }
00140 static void emDM_drawEdges(
00141         DerivedMesh *dm,
00142         int UNUSED(drawLooseEdges),
00143         int UNUSED(drawAllEdges))
00144 {
00145     emDM_drawMappedEdges(dm, NULL, NULL);
00146 }
00147 
00148 static void emDM_drawMappedEdgesInterp(
00149         DerivedMesh *dm,
00150         int (*setDrawOptions)(void *userData, int index),
00151         void (*setDrawInterpOptions)(void *userData, int index, float t),
00152         void *userData)
00153 {
00154     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00155     EditEdge *eed;
00156     int i;
00157 
00158     if (emdm->vertexCos) {
00159         EditVert *eve;
00160 
00161         for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
00162             eve->tmp.l = (intptr_t) i++;
00163 
00164         glBegin(GL_LINES);
00165         for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
00166             if (!setDrawOptions || setDrawOptions(userData, i)) {
00167                 setDrawInterpOptions(userData, i, 0.0);
00168                 glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]);
00169                 setDrawInterpOptions(userData, i, 1.0);
00170                 glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]);
00171             }
00172         }
00173         glEnd();
00174     }
00175     else {
00176         glBegin(GL_LINES);
00177         for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
00178             if (!setDrawOptions || setDrawOptions(userData, i)) {
00179                 setDrawInterpOptions(userData, i, 0.0);
00180                 glVertex3fv(eed->v1->co);
00181                 setDrawInterpOptions(userData, i, 1.0);
00182                 glVertex3fv(eed->v2->co);
00183             }
00184         }
00185         glEnd();
00186     }
00187 }
00188 
00189 static void emDM_drawUVEdges(DerivedMesh *dm)
00190 {
00191     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00192     EditFace *efa;
00193     MTFace *tf;
00194 
00195     glBegin(GL_LINES);
00196     for (efa= emdm->em->faces.first; efa; efa= efa->next) {
00197         tf = CustomData_em_get(&emdm->em->fdata, efa->data, CD_MTFACE);
00198 
00199         if (tf && !(efa->h)) {
00200             glVertex2fv(tf->uv[0]);
00201             glVertex2fv(tf->uv[1]);
00202 
00203             glVertex2fv(tf->uv[1]);
00204             glVertex2fv(tf->uv[2]);
00205 
00206             if (!efa->v4) {
00207                 glVertex2fv(tf->uv[2]);
00208                 glVertex2fv(tf->uv[0]);
00209             }
00210             else {
00211                 glVertex2fv(tf->uv[2]);
00212                 glVertex2fv(tf->uv[3]);
00213                 glVertex2fv(tf->uv[3]);
00214                 glVertex2fv(tf->uv[0]);
00215             }
00216         }
00217     }
00218     glEnd();
00219 }
00220 
00221 static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3])
00222 {
00223     if (vertexCos) {
00224         copy_v3_v3(cent, vertexCos[(int) efa->v1->tmp.l]);
00225         add_v3_v3(cent, vertexCos[(int) efa->v2->tmp.l]);
00226         add_v3_v3(cent, vertexCos[(int) efa->v3->tmp.l]);
00227         if (efa->v4) add_v3_v3(cent, vertexCos[(int) efa->v4->tmp.l]);
00228     }
00229     else {
00230         copy_v3_v3(cent, efa->v1->co);
00231         add_v3_v3(cent, efa->v2->co);
00232         add_v3_v3(cent, efa->v3->co);
00233         if (efa->v4) add_v3_v3(cent, efa->v4->co);
00234     }
00235 
00236     if (efa->v4) {
00237         mul_v3_fl(cent, 0.25f);
00238     }
00239     else {
00240         mul_v3_fl(cent, 0.33333333333f);
00241     }
00242 }
00243 
00244 static void emDM_foreachMappedFaceCenter(
00245         DerivedMesh *dm,
00246         void (*func)(void *userData, int index, float *co, float *no),
00247         void *userData)
00248 {
00249     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00250     EditVert *eve;
00251     EditFace *efa;
00252     float cent[3];
00253     int i;
00254 
00255     if (emdm->vertexCos) {
00256         for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
00257             eve->tmp.l = (intptr_t) i++;
00258     }
00259 
00260     for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
00261         emDM__calcFaceCent(efa, cent, emdm->vertexCos);
00262         func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n);
00263     }
00264 }
00265 
00266 /* note, material function is ignored for now. */
00267 static void emDM_drawMappedFaces(
00268         DerivedMesh *dm,
00269         int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
00270         int (*setMaterial)(int, void *attribs),
00271         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
00272         void *userData, int UNUSED(useColors))
00273 {
00274     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00275     EditFace *efa;
00276     int i, draw, flush;
00277     const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
00278 
00279     /* GL_ZERO is used to detect if drawing has started or not */
00280     GLenum poly_prev= GL_ZERO;
00281     GLenum shade_prev= GL_ZERO;
00282 
00283     (void)setMaterial; /* UNUSED */
00284 
00285     /* currently unused -- each original face is handled separately */
00286     (void)compareDrawOptions;
00287 
00288     if (emdm->vertexCos) {
00289         /* add direct access */
00290         float (*vertexCos)[3]= emdm->vertexCos;
00291         float (*vertexNos)[3]= emdm->vertexNos;
00292         float (*faceNos)[3]=   emdm->faceNos;
00293         EditVert *eve;
00294 
00295         for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
00296             eve->tmp.l = (intptr_t) i++;
00297 
00298         for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
00299             int drawSmooth = (efa->flag & ME_SMOOTH);
00300             draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
00301             if (draw) {
00302                 const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
00303                 if (draw==2) { /* enabled with stipple */
00304 
00305                     if (poly_prev != GL_ZERO) glEnd();
00306                     poly_prev= GL_ZERO; /* force glBegin */
00307 
00308                     glEnable(GL_POLYGON_STIPPLE);
00309                     glPolygonStipple(stipple_quarttone);
00310                 }
00311 
00312                 if (skip_normals) {
00313                     if (poly_type != poly_prev) {
00314                         if (poly_prev != GL_ZERO) glEnd();
00315                         glBegin((poly_prev= poly_type));
00316                     }
00317                     glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
00318                     glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
00319                     glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
00320                     if (poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
00321                 }
00322                 else {
00323                     const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
00324                     if (shade_type != shade_prev) {
00325                         if (poly_prev != GL_ZERO) glEnd();
00326                         glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
00327                         glBegin((poly_prev= poly_type));
00328                     }
00329                     else if (poly_type != poly_prev) {
00330                         if (poly_prev != GL_ZERO) glEnd();
00331                         glBegin((poly_prev= poly_type));
00332                     }
00333 
00334                     if (!drawSmooth) {
00335                         glNormal3fv(faceNos[i]);
00336                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
00337                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
00338                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
00339                         if (poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
00340                     }
00341                     else {
00342                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
00343                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
00344                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
00345                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
00346                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
00347                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
00348                         if (poly_type == GL_QUADS) {
00349                             glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
00350                             glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
00351                         }
00352                     }
00353                 }
00354 
00355                 flush= (draw==2);
00356                 if (!skip_normals && !flush && efa->next)
00357                     flush|= efa->mat_nr != efa->next->mat_nr;
00358 
00359                 if (flush) {
00360                     glEnd();
00361                     poly_prev= GL_ZERO; /* force glBegin */
00362 
00363                     glDisable(GL_POLYGON_STIPPLE);
00364                 }
00365             }
00366         }
00367     }
00368     else {
00369         for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
00370             int drawSmooth = (efa->flag & ME_SMOOTH);
00371             draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
00372             if (draw) {
00373                 const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
00374                 if (draw==2) { /* enabled with stipple */
00375 
00376                     if (poly_prev != GL_ZERO) glEnd();
00377                     poly_prev= GL_ZERO; /* force glBegin */
00378 
00379                     glEnable(GL_POLYGON_STIPPLE);
00380                     glPolygonStipple(stipple_quarttone);
00381                 }
00382 
00383                 if (skip_normals) {
00384                     if (poly_type != poly_prev) {
00385                         if (poly_prev != GL_ZERO) glEnd();
00386                         glBegin((poly_prev= poly_type));
00387                     }
00388                     glVertex3fv(efa->v1->co);
00389                     glVertex3fv(efa->v2->co);
00390                     glVertex3fv(efa->v3->co);
00391                     if (poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
00392                 }
00393                 else {
00394                     const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
00395                     if (shade_type != shade_prev) {
00396                         if (poly_prev != GL_ZERO) glEnd();
00397                         glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
00398                         glBegin((poly_prev= poly_type));
00399                     }
00400                     else if (poly_type != poly_prev) {
00401                         if (poly_prev != GL_ZERO) glEnd();
00402                         glBegin((poly_prev= poly_type));
00403                     }
00404 
00405                     if (!drawSmooth) {
00406                         glNormal3fv(efa->n);
00407                         glVertex3fv(efa->v1->co);
00408                         glVertex3fv(efa->v2->co);
00409                         glVertex3fv(efa->v3->co);
00410                         if (poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
00411                     }
00412                     else {
00413                         glNormal3fv(efa->v1->no);
00414                         glVertex3fv(efa->v1->co);
00415                         glNormal3fv(efa->v2->no);
00416                         glVertex3fv(efa->v2->co);
00417                         glNormal3fv(efa->v3->no);
00418                         glVertex3fv(efa->v3->co);
00419                         if (poly_type == GL_QUADS) {
00420                             glNormal3fv(efa->v4->no);
00421                             glVertex3fv(efa->v4->co);
00422                         }
00423                     }
00424                 }
00425 
00426                 flush= (draw==2);
00427                 if (!skip_normals && !flush && efa->next)
00428                     flush|= efa->mat_nr != efa->next->mat_nr;
00429 
00430                 if (flush) {
00431                     glEnd();
00432                     poly_prev= GL_ZERO; /* force glBegin */
00433 
00434                     glDisable(GL_POLYGON_STIPPLE);
00435                 }
00436             }
00437         }
00438     }
00439 
00440     /* if non zero we know a face was rendered */
00441     if (poly_prev != GL_ZERO) glEnd();
00442 }
00443 
00444 static void emDM_drawFacesTex_common(
00445         DerivedMesh *dm,
00446         int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
00447         int (*drawParamsMapped)(void *userData, int index),
00448         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
00449         void *userData)
00450 {
00451     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00452     EditMesh *em= emdm->em;
00453     float (*vertexCos)[3]= emdm->vertexCos;
00454     float (*vertexNos)[3]= emdm->vertexNos;
00455     EditFace *efa;
00456     int i;
00457 
00458     (void) compareDrawOptions;
00459 
00460     /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
00461     glShadeModel(GL_SMOOTH);
00462 
00463     if (vertexCos) {
00464         EditVert *eve;
00465 
00466         for (i=0,eve=em->verts.first; eve; eve= eve->next)
00467             eve->tmp.l = (intptr_t) i++;
00468 
00469         for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
00470             MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
00471             MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
00472             unsigned char *cp= NULL;
00473             int drawSmooth= (efa->flag & ME_SMOOTH);
00474             int flag;
00475 
00476             if (drawParams)
00477                 flag= drawParams(tf, (mcol != NULL), efa->mat_nr);
00478             else if (drawParamsMapped)
00479                 flag= drawParamsMapped(userData, i);
00480             else
00481                 flag= 1;
00482 
00483             if (flag != 0) { /* flag 0 == the face is hidden or invisible */
00484 
00485                 /* we always want smooth here since otherwise vertex colors dont interpolate */
00486                 if (mcol) {
00487                     if (flag==1) {
00488                         cp= (unsigned char*)mcol;
00489                     }
00490                 }
00491                 else {
00492                     glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
00493                 }
00494 
00495                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
00496                 if (!drawSmooth) {
00497                     glNormal3fv(emdm->faceNos[i]);
00498 
00499                     if (tf) glTexCoord2fv(tf->uv[0]);
00500                     if (cp) glColor3ub(cp[3], cp[2], cp[1]);
00501                     glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
00502 
00503                     if (tf) glTexCoord2fv(tf->uv[1]);
00504                     if (cp) glColor3ub(cp[7], cp[6], cp[5]);
00505                     glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
00506 
00507                     if (tf) glTexCoord2fv(tf->uv[2]);
00508                     if (cp) glColor3ub(cp[11], cp[10], cp[9]);
00509                     glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
00510 
00511                     if (efa->v4) {
00512                         if (tf) glTexCoord2fv(tf->uv[3]);
00513                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
00514                         glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
00515                     }
00516                 }
00517                 else {
00518                     if (tf) glTexCoord2fv(tf->uv[0]);
00519                     if (cp) glColor3ub(cp[3], cp[2], cp[1]);
00520                     glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
00521                     glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
00522 
00523                     if (tf) glTexCoord2fv(tf->uv[1]);
00524                     if (cp) glColor3ub(cp[7], cp[6], cp[5]);
00525                     glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
00526                     glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
00527 
00528                     if (tf) glTexCoord2fv(tf->uv[2]);
00529                     if (cp) glColor3ub(cp[11], cp[10], cp[9]);
00530                     glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
00531                     glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
00532 
00533                     if (efa->v4) {
00534                         if (tf) glTexCoord2fv(tf->uv[3]);
00535                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
00536                         glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
00537                         glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
00538                     }
00539                 }
00540                 glEnd();
00541             }
00542         }
00543     }
00544     else {
00545         for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
00546             MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
00547             MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
00548             unsigned char *cp= NULL;
00549             int drawSmooth= (efa->flag & ME_SMOOTH);
00550             int flag;
00551 
00552             if (drawParams)
00553                 flag= drawParams(tf, (mcol != NULL), efa->mat_nr);
00554             else if (drawParamsMapped)
00555                 flag= drawParamsMapped(userData, i);
00556             else
00557                 flag= 1;
00558 
00559             if (flag != 0) { /* flag 0 == the face is hidden or invisible */
00560 
00561                 /* we always want smooth here since otherwise vertex colors dont interpolate */
00562                 if (mcol) {
00563                     if (flag==1) {
00564                         cp= (unsigned char*)mcol;
00565                     }
00566                 }
00567                 else {
00568                     glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
00569                 }
00570 
00571                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
00572                 if (!drawSmooth) {
00573                     glNormal3fv(efa->n);
00574 
00575                     if (tf) glTexCoord2fv(tf->uv[0]);
00576                     if (cp) glColor3ub(cp[3], cp[2], cp[1]);
00577                     glVertex3fv(efa->v1->co);
00578 
00579                     if (tf) glTexCoord2fv(tf->uv[1]);
00580                     if (cp) glColor3ub(cp[7], cp[6], cp[5]);
00581                     glVertex3fv(efa->v2->co);
00582 
00583                     if (tf) glTexCoord2fv(tf->uv[2]);
00584                     if (cp) glColor3ub(cp[11], cp[10], cp[9]);
00585                     glVertex3fv(efa->v3->co);
00586 
00587                     if (efa->v4) {
00588                         if (tf) glTexCoord2fv(tf->uv[3]);
00589                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
00590                         glVertex3fv(efa->v4->co);
00591                     }
00592                 }
00593                 else {
00594                     if (tf) glTexCoord2fv(tf->uv[0]);
00595                     if (cp) glColor3ub(cp[3], cp[2], cp[1]);
00596                     glNormal3fv(efa->v1->no);
00597                     glVertex3fv(efa->v1->co);
00598 
00599                     if (tf) glTexCoord2fv(tf->uv[1]);
00600                     if (cp) glColor3ub(cp[7], cp[6], cp[5]);
00601                     glNormal3fv(efa->v2->no);
00602                     glVertex3fv(efa->v2->co);
00603 
00604                     if (tf) glTexCoord2fv(tf->uv[2]);
00605                     if (cp) glColor3ub(cp[11], cp[10], cp[9]);
00606                     glNormal3fv(efa->v3->no);
00607                     glVertex3fv(efa->v3->co);
00608 
00609                     if (efa->v4) {
00610                         if (tf) glTexCoord2fv(tf->uv[3]);
00611                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
00612                         glNormal3fv(efa->v4->no);
00613                         glVertex3fv(efa->v4->co);
00614                     }
00615                 }
00616                 glEnd();
00617             }
00618         }
00619     }
00620 }
00621 
00622 static void emDM_drawFacesTex(
00623         DerivedMesh *dm,
00624         int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr),
00625         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
00626         void *userData)
00627 {
00628     emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
00629 }
00630 
00631 static void emDM_drawMappedFacesTex(
00632         DerivedMesh *dm,
00633         int (*setDrawOptions)(void *userData, int index),
00634         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
00635         void *userData)
00636 {
00637     emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
00638 }
00639 
00640 static void emDM_drawMappedFacesGLSL(
00641         DerivedMesh *dm,
00642         int (*setMaterial)(int, void *attribs),
00643         int (*setDrawOptions)(void *userData, int index),
00644         void *userData)
00645 {
00646     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00647     EditMesh *em= emdm->em;
00648     float (*vertexCos)[3]= emdm->vertexCos;
00649     float (*vertexNos)[3]= emdm->vertexNos;
00650     EditVert *eve;
00651     EditFace *efa;
00652     DMVertexAttribs attribs= {{{0}}};
00653     GPUVertexAttribs gattribs;
00654     /* int tfoffset; */ /* UNUSED */
00655     int i, b, matnr, new_matnr, dodraw /* , layer */ /* UNUSED */;
00656 
00657     dodraw = 0;
00658     matnr = -1;
00659 
00660     /* layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE); */ /* UNUSED */
00661     /* tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset; */ /* UNUSED */
00662 
00663     /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
00664     glShadeModel(GL_SMOOTH);
00665 
00666     for (i=0,eve=em->verts.first; eve; eve= eve->next)
00667         eve->tmp.l = (intptr_t) i++;
00668 
00669 #define PASSATTRIB(efa, eve, vert) {                                            \
00670     if (attribs.totorco) {                                                      \
00671         float *orco = attribs.orco.array[eve->tmp.l];                           \
00672         glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                       \
00673     }                                                                           \
00674     for (b = 0; b < attribs.tottface; b++) {                                    \
00675         MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset);  \
00676         glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);          \
00677     }                                                                           \
00678     for (b = 0; b < attribs.totmcol; b++) {                                     \
00679         MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset);        \
00680         GLubyte col[4];                                                         \
00681         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;             \
00682         glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                    \
00683     }                                                                           \
00684     if (attribs.tottang) {                                                      \
00685         float *tang = attribs.tang.array[i*4 + vert];                           \
00686         glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                       \
00687     }                                                                           \
00688 }
00689 
00690     for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
00691         int drawSmooth= (efa->flag & ME_SMOOTH);
00692 
00693         if (setDrawOptions && !setDrawOptions(userData, i))
00694             continue;
00695 
00696         new_matnr = efa->mat_nr + 1;
00697         if (new_matnr != matnr) {
00698             dodraw = setMaterial(matnr = new_matnr, &gattribs);
00699             if (dodraw)
00700                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
00701         }
00702 
00703         if (dodraw) {
00704             glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
00705             if (!drawSmooth) {
00706                 if (vertexCos) glNormal3fv(emdm->faceNos[i]);
00707                 else glNormal3fv(efa->n);
00708 
00709                 PASSATTRIB(efa, efa->v1, 0);
00710                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
00711                 else glVertex3fv(efa->v1->co);
00712 
00713                 PASSATTRIB(efa, efa->v2, 1);
00714                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
00715                 else glVertex3fv(efa->v2->co);
00716 
00717                 PASSATTRIB(efa, efa->v3, 2);
00718                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
00719                 else glVertex3fv(efa->v3->co);
00720 
00721                 if (efa->v4) {
00722                     PASSATTRIB(efa, efa->v4, 3);
00723                     if (vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
00724                     else glVertex3fv(efa->v4->co);
00725                 }
00726             }
00727             else {
00728                 PASSATTRIB(efa, efa->v1, 0);
00729                 if (vertexCos) {
00730                     glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
00731                     glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
00732                 }
00733                 else {
00734                     glNormal3fv(efa->v1->no);
00735                     glVertex3fv(efa->v1->co);
00736                 }
00737 
00738                 PASSATTRIB(efa, efa->v2, 1);
00739                 if (vertexCos) {
00740                     glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
00741                     glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
00742                 }
00743                 else {
00744                     glNormal3fv(efa->v2->no);
00745                     glVertex3fv(efa->v2->co);
00746                 }
00747 
00748                 PASSATTRIB(efa, efa->v3, 2);
00749                 if (vertexCos) {
00750                     glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
00751                     glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
00752                 }
00753                 else {
00754                     glNormal3fv(efa->v3->no);
00755                     glVertex3fv(efa->v3->co);
00756                 }
00757 
00758                 if (efa->v4) {
00759                     PASSATTRIB(efa, efa->v4, 3);
00760                     if (vertexCos) {
00761                         glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
00762                         glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
00763                     }
00764                     else {
00765                         glNormal3fv(efa->v4->no);
00766                         glVertex3fv(efa->v4->co);
00767                     }
00768                 }
00769             }
00770             glEnd();
00771         }
00772     }
00773 #undef PASSATTRIB
00774 }
00775 
00776 static void emDM_drawFacesGLSL(
00777         DerivedMesh *dm,
00778         int (*setMaterial)(int, void *attribs))
00779 {
00780     dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
00781 }
00782 
00783 static void emDM_drawMappedFacesMat(
00784         DerivedMesh *dm,
00785         void (*setMaterial)(void *userData, int, void *attribs),
00786         int (*setFace)(void *userData, int index), void *userData)
00787 {
00788     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00789     EditMesh *em= emdm->em;
00790     float (*vertexCos)[3]= emdm->vertexCos;
00791     float (*vertexNos)[3]= emdm->vertexNos;
00792     EditVert *eve;
00793     EditFace *efa;
00794     DMVertexAttribs attribs= {{{0}}};
00795     GPUVertexAttribs gattribs;
00796     int i, b, matnr, new_matnr;
00797 
00798     matnr = -1;
00799 
00800     /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
00801     glShadeModel(GL_SMOOTH);
00802 
00803     for (i=0,eve=em->verts.first; eve; eve= eve->next)
00804         eve->tmp.l = (intptr_t) i++;
00805 
00806 #define PASSATTRIB(efa, eve, vert) {                                            \
00807     if (attribs.totorco) {                                                      \
00808         float *orco = attribs.orco.array[eve->tmp.l];                           \
00809         if (attribs.orco.glTexco)                                               \
00810             glTexCoord3fv(orco);                                                \
00811         else                                                                    \
00812             glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                   \
00813     }                                                                           \
00814     for (b = 0; b < attribs.tottface; b++) {                                    \
00815         MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset);  \
00816         if (attribs.tface[b].glTexco)                                           \
00817             glTexCoord2fv(_tf->uv[vert]);                                       \
00818         else                                                                    \
00819             glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);      \
00820     }                                                                           \
00821     for (b = 0; b < attribs.totmcol; b++) {                                     \
00822         MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset);        \
00823         GLubyte col[4];                                                         \
00824         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;             \
00825         glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                    \
00826     }                                                                           \
00827     if (attribs.tottang) {                                                      \
00828         float *tang = attribs.tang.array[i*4 + vert];                           \
00829         glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                       \
00830     }                                                                           \
00831 }
00832 
00833     for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
00834         int drawSmooth= (efa->flag & ME_SMOOTH);
00835 
00836         /* face hiding */
00837         if (setFace && !setFace(userData, i))
00838             continue;
00839 
00840         /* material */
00841         new_matnr = efa->mat_nr + 1;
00842         if (new_matnr != matnr) {
00843             setMaterial(userData, matnr = new_matnr, &gattribs);
00844             DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
00845         }
00846 
00847         /* face */
00848         glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
00849         if (!drawSmooth) {
00850             if (vertexCos) glNormal3fv(emdm->faceNos[i]);
00851             else glNormal3fv(efa->n);
00852 
00853             PASSATTRIB(efa, efa->v1, 0);
00854             if (vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
00855             else glVertex3fv(efa->v1->co);
00856 
00857             PASSATTRIB(efa, efa->v2, 1);
00858             if (vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
00859             else glVertex3fv(efa->v2->co);
00860 
00861             PASSATTRIB(efa, efa->v3, 2);
00862             if (vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
00863             else glVertex3fv(efa->v3->co);
00864 
00865             if (efa->v4) {
00866                 PASSATTRIB(efa, efa->v4, 3);
00867                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
00868                 else glVertex3fv(efa->v4->co);
00869             }
00870         }
00871         else {
00872             PASSATTRIB(efa, efa->v1, 0);
00873             if (vertexCos) {
00874                 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
00875                 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
00876             }
00877             else {
00878                 glNormal3fv(efa->v1->no);
00879                 glVertex3fv(efa->v1->co);
00880             }
00881 
00882             PASSATTRIB(efa, efa->v2, 1);
00883             if (vertexCos) {
00884                 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
00885                 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
00886             }
00887             else {
00888                 glNormal3fv(efa->v2->no);
00889                 glVertex3fv(efa->v2->co);
00890             }
00891 
00892             PASSATTRIB(efa, efa->v3, 2);
00893             if (vertexCos) {
00894                 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
00895                 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
00896             }
00897             else {
00898                 glNormal3fv(efa->v3->no);
00899                 glVertex3fv(efa->v3->co);
00900             }
00901 
00902             if (efa->v4) {
00903                 PASSATTRIB(efa, efa->v4, 3);
00904                 if (vertexCos) {
00905                     glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
00906                     glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
00907                 }
00908                 else {
00909                     glNormal3fv(efa->v4->no);
00910                     glVertex3fv(efa->v4->co);
00911                 }
00912             }
00913         }
00914         glEnd();
00915     }
00916 #undef PASSATTRIB
00917 }
00918 
00919 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
00920 {
00921     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00922     EditVert *eve;
00923     int i;
00924 
00925     if (emdm->em->verts.first) {
00926         for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
00927             if (emdm->vertexCos) {
00928                 DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
00929             }
00930             else {
00931                 DO_MINMAX(eve->co, min_r, max_r);
00932             }
00933         }
00934     }
00935     else {
00936         min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
00937     }
00938 }
00939 static int emDM_getNumVerts(DerivedMesh *dm)
00940 {
00941     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00942 
00943     return BLI_countlist(&emdm->em->verts);
00944 }
00945 
00946 static int emDM_getNumEdges(DerivedMesh *dm)
00947 {
00948     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00949 
00950     return BLI_countlist(&emdm->em->edges);
00951 }
00952 
00953 static int emDM_getNumFaces(DerivedMesh *dm)
00954 {
00955     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00956 
00957     return BLI_countlist(&emdm->em->faces);
00958 }
00959 
00960 static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
00961 {
00962     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
00963     EditVert *eve;
00964     int i;
00965 
00966     for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
00967         if (emdm->vertexCos) {
00968             copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
00969         }
00970         else {
00971             copy_v3_v3(cos_r[i], eve->co);
00972         }
00973     }
00974 }
00975 
00976 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
00977 {
00978     EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
00979     int i;
00980 
00981     for (i = 0; i < index; ++i) ev = ev->next;
00982 
00983     copy_v3_v3(vert_r->co, ev->co);
00984 
00985     normal_float_to_short_v3(vert_r->no, ev->no);
00986 
00987     /* TODO what to do with vert_r->flag? */
00988     vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
00989 }
00990 
00991 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
00992 {
00993     EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
00994     EditEdge *ee = em->edges.first;
00995     EditVert *ev, *v1, *v2;
00996     int i;
00997 
00998     for (i = 0; i < index; ++i) ee = ee->next;
00999 
01000     edge_r->crease = (unsigned char) (ee->crease*255.0f);
01001     edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
01002     /* TODO what to do with edge_r->flag? */
01003     edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
01004     if (ee->seam) edge_r->flag |= ME_SEAM;
01005     if (ee->sharp) edge_r->flag |= ME_SHARP;
01006 #if 0
01007     /* this needs setup of f2 field */
01008     if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
01009 #endif
01010 
01011     /* goddamn, we have to search all verts to find indices */
01012     v1 = ee->v1;
01013     v2 = ee->v2;
01014     for (i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) {
01015         if (ev == v1) {
01016             edge_r->v1 = i;
01017             v1 = NULL;
01018         }
01019         if (ev == v2) {
01020             edge_r->v2 = i;
01021             v2 = NULL;
01022         }
01023     }
01024 }
01025 
01026 static void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
01027 {
01028     EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
01029     EditFace *ef = em->faces.first;
01030     EditVert *ev, *v1, *v2, *v3, *v4;
01031     int i;
01032 
01033     for (i = 0; i < index; ++i) ef = ef->next;
01034 
01035     face_r->mat_nr = ef->mat_nr;
01036     face_r->flag = ef->flag;
01037 
01038     /* goddamn, we have to search all verts to find indices */
01039     v1 = ef->v1;
01040     v2 = ef->v2;
01041     v3 = ef->v3;
01042     v4 = ef->v4;
01043     if (!v4) face_r->v4 = 0;
01044 
01045     for (i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
01046         i++, ev = ev->next) {
01047         if (ev == v1) {
01048             face_r->v1 = i;
01049             v1 = NULL;
01050         }
01051         if (ev == v2) {
01052             face_r->v2 = i;
01053             v2 = NULL;
01054         }
01055         if (ev == v3) {
01056             face_r->v3 = i;
01057             v3 = NULL;
01058         }
01059         if (ev == v4) {
01060             face_r->v4 = i;
01061             v4 = NULL;
01062         }
01063     }
01064 
01065     test_index_face(face_r, NULL, 0, ef->v4?4:3);
01066 }
01067 
01068 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
01069 {
01070     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
01071     EditVert *ev = emdm->em->verts.first;
01072     int i;
01073 
01074     for (i=0; ev; ev = ev->next, ++vert_r, ++i) {
01075         if (emdm->vertexCos)
01076             copy_v3_v3(vert_r->co, emdm->vertexCos[i]);
01077         else
01078             copy_v3_v3(vert_r->co, ev->co);
01079 
01080         normal_float_to_short_v3(vert_r->no, ev->no);
01081 
01082         /* TODO what to do with vert_r->flag? */
01083         vert_r->flag = 0;
01084         vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
01085     }
01086 }
01087 
01088 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
01089 {
01090     EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
01091     EditEdge *ee = em->edges.first;
01092     EditVert *ev;
01093     int i;
01094 
01095     /* store vertex indices in tmp union */
01096     for (ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
01097         ev->tmp.l = (intptr_t) i;
01098 
01099     for ( ; ee; ee = ee->next, ++edge_r) {
01100         edge_r->crease = (unsigned char) (ee->crease*255.0f);
01101         edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
01102         /* TODO what to do with edge_r->flag? */
01103         edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
01104         if (ee->seam) edge_r->flag |= ME_SEAM;
01105         if (ee->sharp) edge_r->flag |= ME_SHARP;
01106 #if 0
01107         /* this needs setup of f2 field */
01108         if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
01109 #endif
01110 
01111         edge_r->v1 = (int)ee->v1->tmp.l;
01112         edge_r->v2 = (int)ee->v2->tmp.l;
01113     }
01114 }
01115 
01116 static void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
01117 {
01118     EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
01119     EditFace *ef = em->faces.first;
01120     EditVert *ev;
01121     int i;
01122 
01123     /* store vertexes indices in tmp union */
01124     for (ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
01125         ev->tmp.l = (intptr_t) i;
01126 
01127     for ( ; ef; ef = ef->next, ++face_r) {
01128         face_r->mat_nr = ef->mat_nr;
01129         face_r->flag = ef->flag;
01130 
01131         face_r->v1 = (int)ef->v1->tmp.l;
01132         face_r->v2 = (int)ef->v2->tmp.l;
01133         face_r->v3 = (int)ef->v3->tmp.l;
01134         if (ef->v4) face_r->v4 = (int)ef->v4->tmp.l;
01135         else face_r->v4 = 0;
01136 
01137         test_index_face(face_r, NULL, 0, ef->v4?4:3);
01138     }
01139 }
01140 
01141 static void *emDM_getFaceDataArray(DerivedMesh *dm, int type)
01142 {
01143     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
01144     EditMesh *em= emdm->em;
01145     EditFace *efa;
01146     char *data, *emdata;
01147     void *datalayer;
01148     int index, size;
01149 
01150     datalayer = DM_get_face_data_layer(dm, type);
01151     if (datalayer)
01152         return datalayer;
01153 
01154     /* layers are store per face for editmesh, we convert to a temporary
01155      * data layer array in the derivedmesh when these are requested */
01156     if (type == CD_MTFACE || type == CD_MCOL) {
01157         index = CustomData_get_layer_index(&em->fdata, type);
01158 
01159         if (index != -1) {
01160             /* int offset = em->fdata.layers[index].offset; */ /* UNUSED */
01161             size = CustomData_sizeof(type);
01162 
01163             DM_add_face_layer(dm, type, CD_CALLOC, NULL);
01164             index = CustomData_get_layer_index(&dm->faceData, type);
01165             dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
01166 
01167             data = datalayer = DM_get_face_data_layer(dm, type);
01168             for (efa=em->faces.first; efa; efa=efa->next, data+=size) {
01169                 emdata = CustomData_em_get(&em->fdata, efa->data, type);
01170                 memcpy(data, emdata, size);
01171             }
01172         }
01173     }
01174 
01175     return datalayer;
01176 }
01177 
01178 static void emDM_release(DerivedMesh *dm)
01179 {
01180     EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
01181 
01182     if (DM_release(dm)) {
01183         if (emdm->vertexCos) {
01184             MEM_freeN(emdm->vertexCos);
01185             MEM_freeN(emdm->vertexNos);
01186             MEM_freeN(emdm->faceNos);
01187         }
01188 
01189         MEM_freeN(emdm);
01190     }
01191 }
01192 
01193 DerivedMesh *editmesh_get_derived(
01194         EditMesh *em,
01195         float (*vertexCos)[3])
01196 {
01197     EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
01198 
01199     DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
01200                      BLI_countlist(&em->edges), BLI_countlist(&em->faces));
01201 
01202     emdm->dm.getMinMax = emDM_getMinMax;
01203 
01204     emdm->dm.getNumVerts = emDM_getNumVerts;
01205     emdm->dm.getNumEdges = emDM_getNumEdges;
01206     emdm->dm.getNumFaces = emDM_getNumFaces;
01207 
01208     emdm->dm.getVertCos = emDM_getVertCos;
01209 
01210     emdm->dm.getVert = emDM_getVert;
01211     emdm->dm.getEdge = emDM_getEdge;
01212     emdm->dm.getFace = emDM_getFace;
01213     emdm->dm.copyVertArray = emDM_copyVertArray;
01214     emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
01215     emdm->dm.copyFaceArray = emDM_copyFaceArray;
01216     emdm->dm.getFaceDataArray = emDM_getFaceDataArray;
01217 
01218     emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
01219     emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
01220     emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
01221 
01222     emdm->dm.drawEdges = emDM_drawEdges;
01223     emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
01224     emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
01225     emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
01226     emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
01227     emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
01228     emdm->dm.drawFacesTex = emDM_drawFacesTex;
01229     emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
01230     emdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
01231     emdm->dm.drawUVEdges = emDM_drawUVEdges;
01232 
01233     emdm->dm.release = emDM_release;
01234 
01235     emdm->em = em;
01236     emdm->vertexCos = vertexCos;
01237 
01238     if (CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
01239         EditVert *eve;
01240         int i;
01241 
01242         DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
01243 
01244         for (eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
01245             DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
01246                              CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
01247     }
01248 
01249     if (vertexCos) {
01250         EditVert *eve;
01251         EditFace *efa;
01252         int totface = BLI_countlist(&em->faces);
01253         int i;
01254 
01255         for (i=0,eve=em->verts.first; eve; eve= eve->next)
01256             eve->tmp.l = (intptr_t) i++;
01257 
01258         emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
01259         emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
01260 
01261         for (i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
01262             float *v1 = vertexCos[(int) efa->v1->tmp.l];
01263             float *v2 = vertexCos[(int) efa->v2->tmp.l];
01264             float *v3 = vertexCos[(int) efa->v3->tmp.l];
01265             float *no = emdm->faceNos[i];
01266 
01267             if (efa->v4) {
01268                 float *v4 = vertexCos[(int) efa->v4->tmp.l];
01269 
01270                 normal_quad_v3( no,v1, v2, v3, v4);
01271                 add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no);
01272             }
01273             else {
01274                 normal_tri_v3( no,v1, v2, v3);
01275             }
01276 
01277             add_v3_v3(emdm->vertexNos[(int) efa->v1->tmp.l], no);
01278             add_v3_v3(emdm->vertexNos[(int) efa->v2->tmp.l], no);
01279             add_v3_v3(emdm->vertexNos[(int) efa->v3->tmp.l], no);
01280         }
01281 
01282         for (i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
01283             float *no = emdm->vertexNos[i];
01284             /* following Mesh convention; we use vertex coordinate itself
01285              * for normal in this case */
01286             if (normalize_v3(no) == 0.0f) {
01287                 normalize_v3_v3(no, vertexCos[i]);
01288             }
01289         }
01290     }
01291 
01292     return (DerivedMesh*) emdm;
01293 }
01294