2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2006 Blender Foundation.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): Ben Batt <benbatt@gmail.com>
25 * ***** END GPL LICENSE BLOCK *****
27 * Implementation of CDDerivedMesh.
29 * BKE_cdderivedmesh.h contains the function prototypes for this file.
33 /** \file blender/blenkernel/intern/cdderivedmesh.c
40 #include "BLI_blenlib.h"
41 #include "BLI_edgehash.h"
44 #include "BLI_array.h"
45 #include "BLI_smallhash.h"
46 #include "BLI_utildefines.h"
47 #include "BLI_scanfill.h"
49 #include "BKE_cdderivedmesh.h"
50 #include "BKE_global.h"
52 #include "BKE_paint.h"
53 #include "BKE_utildefines.h"
54 #include "BKE_tessmesh.h"
56 #include "DNA_mesh_types.h"
57 #include "DNA_meshdata_types.h"
58 #include "DNA_object_types.h"
59 #include "DNA_curve_types.h" /* for Curve */
61 #include "MEM_guardedalloc.h"
63 #include "GPU_buffers.h"
65 #include "GPU_extensions.h"
66 #include "GPU_material.h"
75 /* these point to data in the DerivedMesh custom data layers,
76 * they are only here for efficiency and convenience **/
87 /* Mesh connectivity */
92 /**************** DerivedMesh interface functions ****************/
93 static int cdDM_getNumVerts(DerivedMesh *dm)
95 return dm->numVertData;
98 static int cdDM_getNumEdges(DerivedMesh *dm)
100 return dm->numEdgeData;
103 static int cdDM_getNumTessFaces(DerivedMesh *dm)
105 /* uncomment and add a breakpoint on the printf()
106 * to help debug tessfaces issues since BMESH merge. */
108 if (dm->numTessFaceData == 0 && dm->numPolyData != 0) {
109 printf("%s: has no faces!, call DM_ensure_tessface() if you need them\n");
112 return dm->numTessFaceData;
115 static int cdDM_getNumLoops(DerivedMesh *dm)
117 return dm->numLoopData;
120 static int cdDM_getNumPolys(DerivedMesh *dm)
122 return dm->numPolyData;
125 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
127 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
128 *vert_r = cddm->mvert[index];
131 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
133 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
134 *edge_r = cddm->medge[index];
137 static void cdDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
139 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
140 *face_r = cddm->mface[index];
143 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
145 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
146 memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
149 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
151 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
152 memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
155 static void cdDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r)
157 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
158 memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numTessFaceData);
161 static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
163 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
164 memcpy(loop_r, cddm->mloop, sizeof(*loop_r) * dm->numLoopData);
167 static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
169 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
170 memcpy(poly_r, cddm->mpoly, sizeof(*poly_r) * dm->numPolyData);
173 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
175 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
178 if (dm->numVertData) {
179 for (i=0; i<dm->numVertData; i++) {
180 DO_MINMAX(cddm->mvert[i].co, min_r, max_r);
189 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
191 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
193 copy_v3_v3(co_r, cddm->mvert[index].co);
196 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
198 MVert *mv = CDDM_get_verts(dm);
201 for (i = 0; i < dm->numVertData; i++, mv++)
202 copy_v3_v3(cos_r[i], mv->co);
205 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
207 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
208 normal_short_to_float_v3(no_r, cddm->mvert[index].no);
211 static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm)
213 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
215 if (!cddm->pmap && ob->type == OB_MESH) {
218 create_vert_poly_map(&cddm->pmap, &cddm->pmap_mem,
219 me->mpoly, me->mloop,
220 me->totvert, me->totpoly, me->totloop);
226 static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
228 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
232 /* active modifiers means extra deformation, which can't be handled correct
233 * on bith of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
234 * stuff and show final DerivedMesh so user would see actual object shape */
235 deformed|= ob->sculpt->modifiers_active;
237 /* as in case with modifiers, we can't synchronize deformation made against
238 * PBVH and non-locked keyblock, so also use PBVH only for brushes and
239 * final DM to give final result to user */
240 deformed|= ob->sculpt->kb && (ob->shapeflag&OB_SHAPE_LOCK) == 0;
245 return cddm->mvert == me->mvert || ob->sculpt->kb;
248 static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
250 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
259 if (ob->sculpt->pbvh) {
260 cddm->pbvh= ob->sculpt->pbvh;
261 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
264 /* always build pbvh from original mesh, and only use it for drawing if
265 * this derivedmesh is just original mesh. it's the multires subsurf dm
266 * that this is actually for, to support a pbvh on a modified mesh */
267 if (!cddm->pbvh && ob->type == OB_MESH) {
268 SculptSession *ss= ob->sculpt;
270 cddm->pbvh = BLI_pbvh_new();
271 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
273 BKE_mesh_tessface_ensure(me);
275 BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
276 me->totface, me->totvert);
278 if (ss->modifiers_active && ob->derivedDeform) {
279 DerivedMesh *deformdm= ob->derivedDeform;
283 totvert= deformdm->getNumVerts(deformdm);
284 vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getPBVH vertCos");
285 deformdm->getVertCos(deformdm, vertCos);
286 BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
294 /* update vertex normals so that drawing smooth faces works during sculpt
295 * TODO: proper fix is to support the pbvh in all drawing modes */
296 static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
298 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
299 float (*face_nors)[3];
301 if (!cddm->pbvh || !cddm->pbvh_draw || !dm->numTessFaceData)
304 face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
306 BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
309 static void cdDM_drawVerts(DerivedMesh *dm)
311 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
312 MVert *mv = cddm->mvert;
315 if ( GPU_buffer_legacy(dm) ) {
317 for (i = 0; i < dm->numVertData; i++, mv++)
321 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
322 GPU_vertex_setup(dm);
323 if ( !GPU_buffer_legacy(dm) ) {
324 if (dm->drawObject->tot_triangle_point)
325 glDrawArrays(GL_POINTS,0, dm->drawObject->tot_triangle_point);
327 glDrawArrays(GL_POINTS,0, dm->drawObject->tot_loose_point);
333 static void cdDM_drawUVEdges(DerivedMesh *dm)
335 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
336 MFace *mf = cddm->mface;
337 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
341 if ( GPU_buffer_legacy(dm) ) {
343 for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) {
344 if (!(mf->flag&ME_HIDE)) {
345 glVertex2fv(tf->uv[0]);
346 glVertex2fv(tf->uv[1]);
348 glVertex2fv(tf->uv[1]);
349 glVertex2fv(tf->uv[2]);
352 glVertex2fv(tf->uv[2]);
353 glVertex2fv(tf->uv[0]);
356 glVertex2fv(tf->uv[2]);
357 glVertex2fv(tf->uv[3]);
359 glVertex2fv(tf->uv[3]);
360 glVertex2fv(tf->uv[0]);
372 GPU_uvedge_setup(dm);
373 if ( !GPU_buffer_legacy(dm) ) {
374 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
375 if (!(mf->flag&ME_HIDE)) {
381 if ( prevdraw != draw ) {
382 if ( prevdraw > 0 && (curpos-prevstart) > 0) {
383 glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
395 if ( prevdraw > 0 && (curpos-prevstart) > 0 ) {
396 glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
404 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
406 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
407 MVert *mvert = cddm->mvert;
408 MEdge *medge = cddm->medge;
411 if ( GPU_buffer_legacy(dm) ) {
412 DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" );
414 for (i = 0; i < dm->numEdgeData; i++, medge++) {
415 if ((drawAllEdges || (medge->flag&ME_EDGEDRAW))
416 && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
417 glVertex3fv(mvert[medge->v1].co);
418 glVertex3fv(mvert[medge->v2].co);
423 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
429 if ( !GPU_buffer_legacy(dm) ) {
430 for (i = 0; i < dm->numEdgeData; i++, medge++) {
431 if ((drawAllEdges || (medge->flag&ME_EDGEDRAW))
432 && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
438 if ( prevdraw != draw ) {
439 if ( prevdraw > 0 && (i-prevstart) > 0 ) {
440 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
446 if ( prevdraw > 0 && (i-prevstart) > 0 ) {
447 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i-prevstart) * 2);
454 static void cdDM_drawLooseEdges(DerivedMesh *dm)
456 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
457 MVert *mvert = cddm->mvert;
458 MEdge *medge = cddm->medge;
461 if ( GPU_buffer_legacy(dm) ) {
462 DEBUG_VBO( "Using legacy code. cdDM_drawLooseEdges\n" );
464 for (i = 0; i < dm->numEdgeData; i++, medge++) {
465 if (medge->flag&ME_LOOSEEDGE) {
466 glVertex3fv(mvert[medge->v1].co);
467 glVertex3fv(mvert[medge->v2].co);
472 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
478 if ( !GPU_buffer_legacy(dm) ) {
479 for (i = 0; i < dm->numEdgeData; i++, medge++) {
480 if (medge->flag&ME_LOOSEEDGE) {
486 if ( prevdraw != draw ) {
487 if ( prevdraw > 0 && (i-prevstart) > 0) {
488 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
494 if ( prevdraw > 0 && (i-prevstart) > 0 ) {
495 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
502 static void cdDM_drawFacesSolid(DerivedMesh *dm,
503 float (*partial_redraw_planes)[4],
504 int UNUSED(fast), DMSetMaterial setMaterial)
506 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
507 MVert *mvert = cddm->mvert;
508 MFace *mface = cddm->mface;
509 float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
510 int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
512 #define PASSVERT(index) { \
513 if (shademodel == GL_SMOOTH) { \
514 short *no = mvert[index].no; \
517 glVertex3fv(mvert[index].co); \
520 if (cddm->pbvh && cddm->pbvh_draw) {
521 if (dm->numTessFaceData) {
522 float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
524 BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, setMaterial);
525 glShadeModel(GL_FLAT);
531 if ( GPU_buffer_legacy(dm) ) {
532 DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
533 glBegin(glmode = GL_QUADS);
534 for (a = 0; a < dm->numTessFaceData; a++, mface++) {
535 int new_glmode, new_matnr, new_shademodel;
537 new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
538 new_matnr = mface->mat_nr + 1;
539 new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
541 if (new_glmode != glmode || new_matnr != matnr
542 || new_shademodel != shademodel) {
545 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
547 glShadeModel(shademodel = new_shademodel);
548 glBegin(glmode = new_glmode);
551 if (drawCurrentMat) {
552 if (shademodel == GL_FLAT) {
557 /* TODO make this better (cache facenormals as layer?) */
560 normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
563 normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
581 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
582 GPU_vertex_setup( dm );
583 GPU_normal_setup( dm );
584 if ( !GPU_buffer_legacy(dm) ) {
585 glShadeModel(GL_SMOOTH);
586 for (a = 0; a < dm->drawObject->totmaterial; a++) {
587 if (setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
588 glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
589 dm->drawObject->materials[a].totpoint);
593 GPU_buffer_unbind( );
597 glShadeModel(GL_FLAT);
600 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
601 DMSetDrawOptionsTex drawParams,
602 DMSetDrawOptions drawParamsMapped,
603 DMCompareDrawOptions compareDrawOptions,
606 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
607 MVert *mv = cddm->mvert;
608 MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
609 MCol *realcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
610 float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
611 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
612 int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
613 int startFace = 0 /*, lastFlag = 0xdeadbeef */ /* UNUSED */;
614 MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
616 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
618 cdDM_update_normals_from_pbvh(dm);
620 if ( GPU_buffer_legacy(dm) ) {
621 DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
622 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
624 DMDrawOption draw_option;
625 unsigned char *cp = NULL;
628 draw_option = drawParams(tf? &tf[i]: NULL, (mcol != NULL), mf->mat_nr);
633 if (orig == ORIGINDEX_NONE) { if (nors) nors += 3; continue; }
634 if (drawParamsMapped) draw_option = drawParamsMapped(userData, orig);
635 else { if (nors) nors += 3; continue; }
638 if (drawParamsMapped) draw_option = drawParamsMapped(userData, i);
639 else { if (nors) nors += 3; continue; }
642 if (draw_option != DM_DRAW_OPTION_SKIP) {
643 if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol)
644 cp= (unsigned char*) &mcol[i*4];
646 if (!(mf->flag&ME_SMOOTH)) {
653 normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
656 normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
662 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
663 if (tf) glTexCoord2fv(tf[i].uv[0]);
664 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
666 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
667 glVertex3fv(mvert->co);
669 if (tf) glTexCoord2fv(tf[i].uv[1]);
670 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
672 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
673 glVertex3fv(mvert->co);
675 if (tf) glTexCoord2fv(tf[i].uv[2]);
676 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
678 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
679 glVertex3fv(mvert->co);
682 if (tf) glTexCoord2fv(tf[i].uv[3]);
683 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
685 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
686 glVertex3fv(mvert->co);
694 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
699 GPU_vertex_setup( dm );
700 GPU_normal_setup( dm );
703 /*if ( realcol && dm->drawObject->colType == CD_TEXTURE_MCOL ) {
706 else if ( mcol && dm->drawObject->colType == CD_MCOL ) {
711 unsigned char *colors = MEM_mallocN(dm->getNumTessFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
712 for ( i=0; i < dm->getNumTessFaces(dm); i++ ) {
713 for ( j=0; j < 4; j++ ) {
714 /* bgr -> rgb is intentional (and stupid), but how its stored internally */
715 colors[i*12+j*3] = col[i*4+j].b;
716 colors[i*12+j*3+1] = col[i*4+j].g;
717 colors[i*12+j*3+2] = col[i*4+j].r;
720 GPU_color3_upload(dm,colors);
723 dm->drawObject->colType = CD_TEXTURE_MCOL;
725 dm->drawObject->colType = CD_MCOL;
727 GPU_color_setup( dm );
730 if ( !GPU_buffer_legacy(dm) ) {
731 int tottri = dm->drawObject->tot_triangle_point/3;
732 int next_actualFace= dm->drawObject->triangle_to_mface[0];
734 glShadeModel( GL_SMOOTH );
735 /* lastFlag = 0; */ /* UNUSED */
736 for (i = 0; i < tottri; i++) {
737 int actualFace = next_actualFace;
738 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
742 next_actualFace= dm->drawObject->triangle_to_mface[i+1];
745 draw_option = drawParams(tf? &tf[actualFace]: NULL, (mcol != NULL), mf[actualFace].mat_nr);
749 orig = index[actualFace];
750 if (orig == ORIGINDEX_NONE) continue;
751 if (drawParamsMapped)
752 draw_option = drawParamsMapped(userData, orig);
755 if (drawParamsMapped)
756 draw_option = drawParamsMapped(userData, actualFace);
759 /* flush buffer if current triangle isn't drawable or it's last triangle */
760 flush= (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
762 if (!flush && compareDrawOptions) {
763 /* also compare draw options and flush buffer if they're different
764 * need for face selection highlight in edit mode */
765 flush|= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
769 int first= startFace*3;
770 /* Add one to the length if we're drawing at the end of the array */
771 int count= (i-startFace+(draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0))*3;
779 glDrawArrays(GL_TRIANGLES, first, count);
788 glShadeModel( GL_FLAT );
792 static void cdDM_drawFacesTex(DerivedMesh *dm,
793 DMSetDrawOptionsTex setDrawOptions,
794 DMCompareDrawOptions compareDrawOptions,
797 cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
800 static void cdDM_drawMappedFaces(DerivedMesh *dm,
801 DMSetDrawOptions setDrawOptions,
802 DMSetMaterial setMaterial,
803 DMCompareDrawOptions compareDrawOptions,
804 void *userData, DMDrawFlag flag)
806 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
807 MVert *mv = cddm->mvert;
808 MFace *mf = cddm->mface;
810 float *nors= DM_get_tessface_data_layer(dm, CD_NORMAL);
811 int useColors = flag & DM_DRAW_USE_COLORS;
812 int i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
814 mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL);
816 mc = DM_get_tessface_data_layer(dm, CD_PREVIEW_MCOL);
818 mc = DM_get_tessface_data_layer(dm, CD_MCOL);
820 cdDM_update_normals_from_pbvh(dm);
822 /* back-buffer always uses legacy since VBO's would need the
823 * color array temporarily overwritten for drawing, then reset. */
824 if ( GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
825 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
826 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
827 int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH);
828 DMDrawOption draw_option= DM_DRAW_OPTION_NORMAL;
830 orig= (index==NULL) ? i : *index++;
832 if (orig == ORIGINDEX_NONE)
833 draw_option= setMaterial(mf->mat_nr + 1, NULL);
834 else if (setDrawOptions != NULL)
835 draw_option= setDrawOptions(userData, orig);
837 if (draw_option != DM_DRAW_OPTION_SKIP) {
838 unsigned char *cp = NULL;
841 cp = (unsigned char *)&mc[i * 4];
843 /* no need to set shading mode to flat because
844 * normals are already used to change shading */
845 glShadeModel(GL_SMOOTH);
846 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
855 normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
858 normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
863 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
864 glVertex3fv(mv[mf->v1].co);
865 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
866 glVertex3fv(mv[mf->v2].co);
867 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
868 glVertex3fv(mv[mf->v3].co);
870 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
871 glVertex3fv(mv[mf->v4].co);
875 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
876 glNormal3sv(mv[mf->v1].no);
877 glVertex3fv(mv[mf->v1].co);
878 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
879 glNormal3sv(mv[mf->v2].no);
880 glVertex3fv(mv[mf->v2].co);
881 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
882 glNormal3sv(mv[mf->v3].no);
883 glVertex3fv(mv[mf->v3].co);
885 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
886 glNormal3sv(mv[mf->v4].no);
887 glVertex3fv(mv[mf->v4].co);
897 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
899 GPU_vertex_setup(dm);
900 GPU_normal_setup(dm);
901 if ( useColors && mc )
903 if ( !GPU_buffer_legacy(dm) ) {
904 int tottri = dm->drawObject->tot_triangle_point/3;
905 glShadeModel(GL_SMOOTH);
908 /* avoid buffer problems in following code */
910 if (setDrawOptions == NULL) {
911 /* just draw the entire face array */
912 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
915 /* we need to check if the next material changes */
916 int next_actualFace= dm->drawObject->triangle_to_mface[0];
918 for ( i = 0; i < tottri; i++ ) {
919 //int actualFace = dm->drawObject->triangle_to_mface[i];
920 int actualFace = next_actualFace;
921 MFace *mface= mf + actualFace;
922 /*int drawSmooth= (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */
923 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
927 next_actualFace= dm->drawObject->triangle_to_mface[i+1];
929 orig= (index==NULL) ? actualFace : index[actualFace];
931 if (orig == ORIGINDEX_NONE)
932 draw_option= setMaterial(mface->mat_nr + 1, NULL);
933 else if (setDrawOptions != NULL)
934 draw_option= setDrawOptions(userData, orig);
936 /* Goal is to draw as long of a contiguous triangle
937 * array as possible, so draw when we hit either an
938 * invisible triangle or at the end of the array */
940 /* flush buffer if current triangle isn't drawable or it's last triangle... */
941 flush= (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
943 /* ... or when material setting is dissferent */
944 flush|= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
946 if (!flush && compareDrawOptions) {
947 flush|= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
951 int first= prevstart*3;
952 /* Add one to the length if we're drawing at the end of the array */
953 int count= (i-prevstart+(draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0))*3;
956 glDrawArrays(GL_TRIANGLES, first, count);
963 glShadeModel(GL_FLAT);
969 static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
970 DMSetDrawOptions setDrawOptions,
971 DMCompareDrawOptions compareDrawOptions,
974 cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
977 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
981 /* orco texture coordinates */
982 if (attribs->totorco) {
983 if (attribs->orco.glTexco)
984 glTexCoord3fv(attribs->orco.array[index]);
986 glVertexAttrib3fvARB(attribs->orco.glIndex, attribs->orco.array[index]);
989 /* uv texture coordinates */
990 for (b = 0; b < attribs->tottface; b++) {
991 MTFace *tf = &attribs->tface[b].array[a];
993 if (attribs->tface[b].glTexco)
994 glTexCoord2fv(tf->uv[vert]);
996 glVertexAttrib2fvARB(attribs->tface[b].glIndex, tf->uv[vert]);
1000 for (b = 0; b < attribs->totmcol; b++) {
1001 MCol *cp = &attribs->mcol[b].array[a*4 + vert];
1003 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1004 glVertexAttrib4ubvARB(attribs->mcol[b].glIndex, col);
1007 /* tangent for normal mapping */
1008 if (attribs->tottang) {
1009 float *tang = attribs->tang.array[a*4 + vert];
1010 glVertexAttrib4fvARB(attribs->tang.glIndex, tang);
1015 glNormal3sv(mvert[index].no);
1017 /* vertex coordinate */
1018 glVertex3fv(mvert[index].co);
1021 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
1022 DMSetMaterial setMaterial,
1023 DMSetDrawOptions setDrawOptions,
1026 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1027 GPUVertexAttribs gattribs;
1028 DMVertexAttribs attribs;
1029 MVert *mvert = cddm->mvert;
1030 MFace *mface = cddm->mface;
1031 /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1032 float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1033 int a, b, dodraw, matnr, new_matnr;
1034 int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1036 cdDM_update_normals_from_pbvh(dm);
1041 glShadeModel(GL_SMOOTH);
1043 if ( GPU_buffer_legacy(dm) || setDrawOptions != NULL ) {
1044 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
1045 memset(&attribs, 0, sizeof(attribs));
1049 for (a = 0; a < dm->numTessFaceData; a++, mface++) {
1050 const int smoothnormal = (mface->flag & ME_SMOOTH);
1051 new_matnr = mface->mat_nr + 1;
1053 if (new_matnr != matnr) {
1056 dodraw = setMaterial(matnr = new_matnr, &gattribs);
1058 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1066 else if (setDrawOptions) {
1067 orig = (index)? index[a]: a;
1069 if (orig == ORIGINDEX_NONE) {
1070 /* since the material is set by setMaterial(), faces with no
1071 * origin can be assumed to be generated by a modifier */
1075 else if (setDrawOptions(userData, orig) == DM_DRAW_OPTION_SKIP)
1079 if (!smoothnormal) {
1081 glNormal3fv(nors[a]);
1084 /* TODO ideally a normal layer should always be available */
1087 normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1090 normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1096 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1097 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1098 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1101 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1103 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1108 GPUBuffer *buffer = NULL;
1109 char *varray = NULL;
1110 int numdata = 0, elementsize = 0, offset;
1111 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1115 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1116 memset(&attribs, 0, sizeof(attribs));
1118 GPU_vertex_setup(dm);
1119 GPU_normal_setup(dm);
1121 if ( !GPU_buffer_legacy(dm) ) {
1122 for ( i = 0; i < dm->drawObject->tot_triangle_point/3; i++ ) {
1124 a = dm->drawObject->triangle_to_mface[i];
1127 new_matnr = mface->mat_nr + 1;
1129 if (new_matnr != matnr ) {
1130 numfaces = curface - start;
1131 if ( numfaces > 0 ) {
1135 if ( numdata != 0 ) {
1137 GPU_buffer_unlock(buffer);
1139 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1142 glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
1144 if ( numdata != 0 ) {
1146 GPU_buffer_free(buffer);
1155 /* prevdraw = dodraw; */ /* UNUSED */
1156 dodraw = setMaterial(matnr = new_matnr, &gattribs);
1158 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1160 if (attribs.totorco) {
1161 datatypes[numdata].index = attribs.orco.glIndex;
1162 datatypes[numdata].size = 3;
1163 datatypes[numdata].type = GL_FLOAT;
1166 for (b = 0; b < attribs.tottface; b++) {
1167 datatypes[numdata].index = attribs.tface[b].glIndex;
1168 datatypes[numdata].size = 2;
1169 datatypes[numdata].type = GL_FLOAT;
1172 for (b = 0; b < attribs.totmcol; b++) {
1173 datatypes[numdata].index = attribs.mcol[b].glIndex;
1174 datatypes[numdata].size = 4;
1175 datatypes[numdata].type = GL_UNSIGNED_BYTE;
1178 if (attribs.tottang) {
1179 datatypes[numdata].index = attribs.tang.glIndex;
1180 datatypes[numdata].size = 4;
1181 datatypes[numdata].type = GL_FLOAT;
1184 if ( numdata != 0 ) {
1185 elementsize = GPU_attrib_element_size( datatypes, numdata );
1186 buffer = GPU_buffer_alloc( elementsize*dm->drawObject->tot_triangle_point);
1187 if ( buffer == NULL ) {
1188 GPU_buffer_unbind();
1189 dm->drawObject->legacy = 1;
1192 varray = GPU_buffer_lock_stream(buffer);
1193 if ( varray == NULL ) {
1194 GPU_buffer_unbind();
1195 GPU_buffer_free(buffer);
1196 dm->drawObject->legacy = 1;
1201 /* if the buffer was set, don't use it again.
1202 * prevdraw was assumed true but didnt run so set to false - [#21036] */
1203 /* prevdraw= 0; */ /* UNUSED */
1209 if (dodraw && numdata != 0 ) {
1211 if (attribs.totorco) {
1212 copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
1213 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
1214 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
1215 offset += sizeof(float)*3;
1217 for (b = 0; b < attribs.tottface; b++) {
1218 MTFace *tf = &attribs.tface[b].array[a];
1219 copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
1220 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
1222 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
1223 offset += sizeof(float)*2;
1225 for (b = 0; b < attribs.totmcol; b++) {
1226 MCol *cp = &attribs.mcol[b].array[a*4 + 0];
1228 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1229 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1230 cp = &attribs.mcol[b].array[a*4 + 1];
1231 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1232 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1233 cp = &attribs.mcol[b].array[a*4 + 2];
1234 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1235 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1236 offset += sizeof(unsigned char)*4;
1238 if (attribs.tottang) {
1239 float *tang = attribs.tang.array[a*4 + 0];
1240 copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1241 tang = attribs.tang.array[a*4 + 1];
1242 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1243 tang = attribs.tang.array[a*4 + 2];
1244 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1245 offset += sizeof(float)*4;
1251 if (dodraw && numdata != 0 ) {
1253 if (attribs.totorco) {
1254 copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
1255 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
1256 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
1257 offset += sizeof(float)*3;
1259 for (b = 0; b < attribs.tottface; b++) {
1260 MTFace *tf = &attribs.tface[b].array[a];
1261 copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
1262 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
1263 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
1264 offset += sizeof(float)*2;
1266 for (b = 0; b < attribs.totmcol; b++) {
1267 MCol *cp = &attribs.mcol[b].array[a*4 + 2];
1269 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1270 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1271 cp = &attribs.mcol[b].array[a*4 + 3];
1272 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1273 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1274 cp = &attribs.mcol[b].array[a*4 + 0];
1275 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1276 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1277 offset += sizeof(unsigned char)*4;
1279 if (attribs.tottang) {
1280 float *tang = attribs.tang.array[a*4 + 2];
1281 copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1282 tang = attribs.tang.array[a*4 + 3];
1283 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1284 tang = attribs.tang.array[a*4 + 0];
1285 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1286 offset += sizeof(float)*4;
1294 numfaces = curface - start;
1295 if ( numfaces > 0 ) {
1297 if ( numdata != 0 ) {
1298 GPU_buffer_unlock(buffer);
1299 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1301 glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1304 GPU_buffer_unbind();
1306 GPU_buffer_free(buffer);
1309 glShadeModel(GL_FLAT);
1312 static void cdDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
1314 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1317 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1318 void (*setMaterial)(void *userData, int, void *attribs),
1319 int (*setFace)(void *userData, int index), void *userData)
1321 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1322 GPUVertexAttribs gattribs;
1323 DMVertexAttribs attribs;
1324 MVert *mvert = cddm->mvert;
1325 MFace *mf = cddm->mface;
1326 float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1327 int a, matnr, new_matnr;
1328 int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1330 cdDM_update_normals_from_pbvh(dm);
1334 glShadeModel(GL_SMOOTH);
1336 memset(&attribs, 0, sizeof(attribs));
1340 for (a = 0; a < dm->numTessFaceData; a++, mf++) {
1341 const int smoothnormal = (mf->flag & ME_SMOOTH);
1344 new_matnr = mf->mat_nr + 1;
1346 if (new_matnr != matnr) {
1349 setMaterial(userData, matnr = new_matnr, &gattribs);
1350 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1355 /* skipping faces */
1357 orig = (index)? index[a]: a;
1359 if (orig != ORIGINDEX_NONE && !setFace(userData, orig))
1364 if (!smoothnormal) {
1366 glNormal3fv(nors[a]);
1369 /* TODO ideally a normal layer should always be available */
1373 normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1375 normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1382 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1383 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1384 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1387 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1389 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1393 glShadeModel(GL_FLAT);
1396 static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData)
1398 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1399 MVert *vert = cddm->mvert;
1400 MEdge *edge = cddm->medge;
1401 int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1404 for (i = 0; i < dm->numEdgeData; i++, edge++) {
1407 if (setDrawOptions && orig == ORIGINDEX_NONE) continue;
1412 if (!setDrawOptions || (setDrawOptions(userData, orig) != DM_DRAW_OPTION_SKIP)) {
1413 glVertex3fv(vert[edge->v1].co);
1414 glVertex3fv(vert[edge->v2].co);
1420 static void cdDM_foreachMappedVert(
1422 void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
1425 MVert *mv = CDDM_get_verts(dm);
1426 int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1428 for (i = 0; i < dm->numVertData; i++, mv++) {
1431 if (orig == ORIGINDEX_NONE) continue;
1432 func(userData, orig, mv->co, NULL, mv->no);
1435 func(userData, i, mv->co, NULL, mv->no);
1439 static void cdDM_foreachMappedEdge(
1441 void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
1444 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1445 MVert *mv = cddm->mvert;
1446 MEdge *med = cddm->medge;
1447 int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1449 for (i = 0; i < dm->numEdgeData; i++, med++) {
1452 if (orig == ORIGINDEX_NONE) continue;
1453 func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1456 func(userData, i, mv[med->v1].co, mv[med->v2].co);
1460 static void cdDM_foreachMappedFaceCenter(
1462 void (*func)(void *userData, int index, const float cent[3], const float no[3]),
1465 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1466 MVert *mv = cddm->mvert;
1467 MPoly *mp = cddm->mpoly;
1468 MLoop *ml = cddm->mloop;
1469 int i, j, orig, *index;
1471 index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1473 for (i = 0; i < dm->numPolyData; i++, mp++) {
1479 if (orig == ORIGINDEX_NONE) continue;
1484 ml = &cddm->mloop[mp->loopstart];
1485 cent[0] = cent[1] = cent[2] = 0.0f;
1486 for (j=0; j<mp->totloop; j++, ml++) {
1487 add_v3_v3v3(cent, cent, mv[ml->v].co);
1489 mul_v3_fl(cent, 1.0f / (float)j);
1491 ml = &cddm->mloop[mp->loopstart];
1497 mv[(ml + 3)->v].co);
1503 mv[(ml + 2)->v].co);
1506 func(userData, orig, cent, no);
1511 void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const int do_face_nor_cpy)
1513 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1515 dm->numTessFaceData = mesh_recalcTessellation(&dm->faceData, &dm->loopData, &dm->polyData,
1517 dm->numTessFaceData, dm->numLoopData, dm->numPolyData,
1520 if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) {
1521 int *polyIndex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1522 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyIndex, dm->numTessFaceData);
1525 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1527 /* Tessellation recreated faceData, and the active layer indices need to get re-propagated
1528 * from loops and polys to faces */
1529 CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
1532 void CDDM_recalc_tessellation(DerivedMesh *dm)
1534 CDDM_recalc_tessellation_ex(dm, TRUE);
1537 static void cdDM_free_internal(CDDerivedMesh *cddm)
1539 if (cddm->pmap) MEM_freeN(cddm->pmap);
1540 if (cddm->pmap_mem) MEM_freeN(cddm->pmap_mem);
1543 static void cdDM_release(DerivedMesh *dm)
1545 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1547 if (DM_release(dm)) {
1548 cdDM_free_internal(cddm);
1553 int CDDM_Check(DerivedMesh *dm)
1555 return dm && dm->getMinMax == cdDM_getMinMax;
1558 /**************** CDDM interface functions ****************/
1559 static CDDerivedMesh *cdDM_create(const char *desc)
1561 CDDerivedMesh *cddm;
1564 cddm = MEM_callocN(sizeof(*cddm), desc);
1567 dm->getMinMax = cdDM_getMinMax;
1569 dm->getNumVerts = cdDM_getNumVerts;
1570 dm->getNumEdges = cdDM_getNumEdges;
1571 dm->getNumTessFaces = cdDM_getNumTessFaces;
1572 dm->getNumLoops = cdDM_getNumLoops;
1573 dm->getNumPolys = cdDM_getNumPolys;
1575 dm->getVert = cdDM_getVert;
1576 dm->getEdge = cdDM_getEdge;
1577 dm->getTessFace = cdDM_getTessFace;
1579 dm->copyVertArray = cdDM_copyVertArray;
1580 dm->copyEdgeArray = cdDM_copyEdgeArray;
1581 dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1582 dm->copyLoopArray = cdDM_copyLoopArray;
1583 dm->copyPolyArray = cdDM_copyPolyArray;
1585 dm->getVertData = DM_get_vert_data;
1586 dm->getEdgeData = DM_get_edge_data;
1587 dm->getTessFaceData = DM_get_tessface_data;
1588 dm->getVertDataArray = DM_get_vert_data_layer;
1589 dm->getEdgeDataArray = DM_get_edge_data_layer;
1590 dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1592 dm->calcNormals = CDDM_calc_normals_mapping;
1593 dm->recalcTessellation = CDDM_recalc_tessellation;
1595 dm->getVertCos = cdDM_getVertCos;
1596 dm->getVertCo = cdDM_getVertCo;
1597 dm->getVertNo = cdDM_getVertNo;
1599 dm->getPBVH = cdDM_getPBVH;
1600 dm->getPolyMap = cdDM_getPolyMap;
1602 dm->drawVerts = cdDM_drawVerts;
1604 dm->drawUVEdges = cdDM_drawUVEdges;
1605 dm->drawEdges = cdDM_drawEdges;
1606 dm->drawLooseEdges = cdDM_drawLooseEdges;
1607 dm->drawMappedEdges = cdDM_drawMappedEdges;
1609 dm->drawFacesSolid = cdDM_drawFacesSolid;
1610 dm->drawFacesTex = cdDM_drawFacesTex;
1611 dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1612 dm->drawMappedFaces = cdDM_drawMappedFaces;
1613 dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1614 dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1615 dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1617 dm->foreachMappedVert = cdDM_foreachMappedVert;
1618 dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1619 dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1621 dm->release = cdDM_release;
1626 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
1628 CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1629 DerivedMesh *dm = &cddm->dm;
1631 DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
1633 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1634 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1635 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
1636 CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces);
1637 CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1639 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1640 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1641 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
1642 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1643 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1645 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1646 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1647 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1648 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1649 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1654 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1656 CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1657 DerivedMesh *dm = &cddm->dm;
1658 CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1660 int *polyindex = NULL;
1662 /* this does a referenced copy, with an exception for fluidsim */
1664 DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1665 mesh->totloop, mesh->totpoly);
1667 dm->deformedOnly = 1;
1669 alloctype= CD_REFERENCE;
1671 CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1673 CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1675 CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_POLYINDEX, alloctype,
1677 CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1679 CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1682 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1683 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1684 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1685 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1686 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1688 /* commented since even when CD_POLYINDEX was first added this line fails
1689 * on the default cube, (after editmode toggle too) - campbell */
1691 BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_POLYINDEX));
1694 polyindex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1695 if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) {
1696 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyindex, mesh->totface);
1702 DerivedMesh *CDDM_from_curve(Object *ob)
1704 return CDDM_from_curve_customDB(ob, &ob->disp);
1707 DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
1710 CDDerivedMesh *cddm;
1715 int totvert, totedge, totloop, totpoly;
1717 if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
1718 &totedge, &allloop, &allpoly, &totloop, &totpoly) != 0) {
1719 /* Error initializing mdata. This often happens when curve is empty */
1720 return CDDM_new(0, 0, 0, 0, 0);
1723 dm = CDDM_new(totvert, totedge, 0, totloop, totpoly);
1724 dm->deformedOnly = 1;
1726 cddm = (CDDerivedMesh*)dm;
1728 memcpy(cddm->mvert, allvert, totvert*sizeof(MVert));
1729 memcpy(cddm->medge, alledge, totedge*sizeof(MEdge));
1730 memcpy(cddm->mloop, allloop, totloop*sizeof(MLoop));
1731 memcpy(cddm->mpoly, allpoly, totpoly*sizeof(MPoly));
1738 CDDM_calc_edges(dm);
1743 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1744 int cdindex, BMLoop *l3[3],
1745 int numCol, int numTex)
1748 BMFace *f = l3[0]->f;
1754 int i, j, hasPCol = CustomData_has_layer(&bm->ldata, CD_PREVIEW_MLOOPCOL);
1756 for (i=0; i < numTex; i++) {
1757 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1758 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1760 ME_MTEXFACE_CPY(texface, texpoly);
1762 for (j=0; j<3; j++) {
1764 mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1765 copy_v2_v2(texface->uv[j], mloopuv->uv);
1769 for (i=0; i < numCol; i++) {
1770 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1772 for (j=0; j<3; j++) {
1774 mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1775 MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1780 mcol = CustomData_get(facedata, cdindex, CD_PREVIEW_MCOL);
1782 for (j=0; j<3; j++) {
1784 mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PREVIEW_MLOOPCOL);
1785 MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1790 DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdisps, int use_tessface)
1794 DerivedMesh *dm = CDDM_new(bm->totvert,
1796 use_tessface ? em->tottri : 0,
1800 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1805 MVert *mvert = cddm->mvert;
1806 MEdge *medge = cddm->medge;
1807 MFace *mface = cddm->mface;
1808 MLoop *mloop = cddm->mloop;
1809 MPoly *mpoly = cddm->mpoly;
1810 int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
1811 int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
1812 int *index, add_orig;
1813 int has_crease, has_edge_bweight, has_vert_bweight;
1814 CustomDataMask mask;
1817 has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1818 has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
1819 has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1821 dm->deformedOnly = 1;
1823 /*don't add origindex layer if one already exists*/
1824 add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
1826 mask = use_mdisps ? CD_MASK_DERIVEDMESH|CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1828 /* don't process shapekeys, we only feed them through the modifier stack as needed,
1829 * e.g. for applying modifiers or the like*/
1830 mask &= ~CD_MASK_SHAPEKEY;
1831 CustomData_merge(&bm->vdata, &dm->vertData, mask,
1832 CD_CALLOC, dm->numVertData);
1833 CustomData_merge(&bm->edata, &dm->edgeData, mask,
1834 CD_CALLOC, dm->numEdgeData);
1835 CustomData_merge(&bm->ldata, &dm->loopData, mask,
1836 CD_CALLOC, dm->numLoopData);
1837 CustomData_merge(&bm->pdata, &dm->polyData, mask,
1838 CD_CALLOC, dm->numPolyData);
1840 /*add tessellation mface layers*/
1842 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri);
1845 index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1847 eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1848 for (i=0; eve; eve=BM_iter_step(&iter), i++, index++) {
1849 MVert *mv = &mvert[i];
1851 copy_v3_v3(mv->co, eve->co);
1853 BM_elem_index_set(eve, i); /* set_inline */
1855 normal_float_to_short_v3(mv->no, eve->no);
1857 mv->flag = BM_vert_flag_to_mflag(eve);
1859 if (has_vert_bweight)
1860 mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT)*255.0f);
1862 if (add_orig) *index = i;
1864 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
1866 bm->elem_index_dirty &= ~BM_VERT;
1868 index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1869 eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1870 for (i=0; eed; eed=BM_iter_step(&iter), i++, index++) {
1871 MEdge *med = &medge[i];
1873 BM_elem_index_set(eed, i); /* set_inline */
1875 med->v1 = BM_elem_index_get(eed->v1);
1876 med->v2 = BM_elem_index_get(eed->v2);
1879 med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE)*255.0f);
1880 if (has_edge_bweight)
1881 med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT)*255.0f);
1883 med->flag = BM_edge_flag_to_mflag(eed);
1885 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
1886 if (add_orig) *index = i;
1888 bm->elem_index_dirty &= ~BM_EDGE;
1890 /* avoid this where possiblem, takes extra memory */
1894 BM_mesh_elem_index_ensure(bm, BM_FACE);
1896 polyindex = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
1897 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1898 for (i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) {
1899 MFace *mf = &mface[i];
1900 BMLoop **l = em->looptris[i];
1903 mf->v1 = BM_elem_index_get(l[0]->v);
1904 mf->v2 = BM_elem_index_get(l[1]->v);
1905 mf->v3 = BM_elem_index_get(l[2]->v);
1907 mf->mat_nr = efa->mat_nr;
1908 mf->flag = BM_face_flag_to_mflag(efa);
1910 *index = add_orig ? BM_elem_index_get(efa) : *(int*)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
1911 *polyindex = BM_elem_index_get(efa);
1913 loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
1914 test_index_face(mf, &dm->faceData, i, 3);
1918 index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1920 efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
1921 for (i=0; efa; i++, efa=BM_iter_step(&iter), index++) {
1923 MPoly *mp = &mpoly[i];
1925 BM_elem_index_set(efa, i); /* set_inline */
1927 mp->totloop = efa->len;
1928 mp->flag = BM_face_flag_to_mflag(efa);
1930 mp->mat_nr = efa->mat_nr;
1932 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
1933 mloop->v = BM_elem_index_get(l->v);
1934 mloop->e = BM_elem_index_get(l->e);
1935 CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
1941 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
1943 if (add_orig) *index = i;
1945 bm->elem_index_dirty &= ~BM_FACE;
1950 static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
1952 CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
1953 DerivedMesh *dm = &cddm->dm;
1954 int numVerts = source->numVertData;
1955 int numEdges = source->numEdgeData;
1956 int numTessFaces = source->numTessFaceData;
1957 int numLoops = source->numLoopData;
1958 int numPolys = source->numPolyData;
1960 /* ensure these are created if they are made on demand */
1961 source->getVertDataArray(source, CD_ORIGINDEX);
1962 source->getEdgeDataArray(source, CD_ORIGINDEX);
1963 source->getTessFaceDataArray(source, CD_ORIGINDEX);
1965 /* this initializes dm, and copies all non mvert/medge/mface layers */
1966 DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
1967 numLoops, numPolys);
1968 dm->deformedOnly = source->deformedOnly;
1969 dm->dirty = source->dirty;
1971 CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
1972 CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
1973 CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
1975 /* now add mvert/medge/mface layers */
1976 cddm->mvert = source->dupVertArray(source);
1977 cddm->medge = source->dupEdgeArray(source);
1978 cddm->mface = source->dupTessFaceArray(source);
1980 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
1981 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
1982 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
1984 if (!faces_from_tessfaces)
1985 DM_DupPolys(source, dm);
1987 CDDM_tessfaces_to_faces(dm);
1989 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1990 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1995 DerivedMesh *CDDM_copy(DerivedMesh *source)
1997 return cddm_copy_ex(source, 0);
2000 DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
2002 return cddm_copy_ex(source, 1);
2005 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2006 * relationship between mesh data this needs to be set by the caller. */
2007 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2008 int numVerts, int numEdges, int numTessFaces,
2009 int numLoops, int numPolys)
2011 CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2012 DerivedMesh *dm = &cddm->dm;
2014 /* ensure these are created if they are made on demand */
2015 source->getVertDataArray(source, CD_ORIGINDEX);
2016 source->getEdgeDataArray(source, CD_ORIGINDEX);
2017 source->getTessFaceDataArray(source, CD_ORIGINDEX);
2019 /* this does a copy of all non mvert/medge/mface layers */
2020 DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
2022 /* now add mvert/medge/mface layers */
2023 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2024 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2025 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2026 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2027 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2029 if (!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2030 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2031 if (!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2032 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2033 if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2034 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2035 if (!CustomData_get_layer(&dm->faceData, CD_POLYINDEX))
2036 CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces);
2038 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2039 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2040 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2041 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2042 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2047 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2049 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2053 /* this will just return the pointer if it wasn't a referenced layer */
2054 vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2057 for (i = 0; i < dm->numVertData; ++i, ++vert)
2058 copy_v3_v3(vert->co, vertCoords[i]);
2061 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2063 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2067 /* this will just return the pointer if it wasn't a referenced layer */
2068 vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2071 for (i = 0; i < dm->numVertData; ++i, ++vert)
2072 copy_v3_v3_short(vert->no, vertNormals[i]);
2075 void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals)
2077 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2078 float (*face_nors)[3] = NULL;
2080 if (dm->numVertData == 0) return;
2082 /* now we skip calculating vertex normals for referenced layer,
2083 * no need to duplicate verts.
2084 * WATCH THIS, bmesh only change!,
2085 * need to take care of the side effects here - campbell */
2087 /* we don't want to overwrite any referenced layers */
2088 cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2092 if (dm->numTessFaceData == 0) {
2093 /* No tessellation on this mesh yet, need to calculate one.
2095 * Important not to update face normals from polys since it
2096 * interfears with assigning the new normal layer in the following code.
2098 CDDM_recalc_tessellation_ex(dm, FALSE);
2101 /* A tessellation already exists, it should always have a CD_POLYINDEX */
2102 BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX));
2103 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
2107 face_nors = MEM_mallocN(sizeof(float)*3*dm->numTessFaceData, "face_nors");
2109 /* calculate face normals */
2110 mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2111 dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData,
2112 CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors,
2115 CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN,
2116 face_nors, dm->numTessFaceData);
2120 void CDDM_calc_normals_mapping(DerivedMesh *dm)
2122 /* use this to skip calculating normals on original vert's, this may need to be changed */
2123 const short only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
2125 CDDM_calc_normals_mapping_ex(dm, only_face_normals);
2128 /* bmesh note: this matches what we have in trunk */
2129 void CDDM_calc_normals(DerivedMesh *dm)
2131 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2132 float (*poly_nors)[3];
2134 if (dm->numVertData == 0) return;
2136 /* we don't want to overwrite any referenced layers */
2137 cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2139 /* fill in if it exists */
2140 poly_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
2142 poly_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
2145 mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2146 dm->numLoopData, dm->numPolyData, poly_nors);
2149 void CDDM_calc_normals_tessface(DerivedMesh *dm)
2151 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2152 float (*face_nors)[3];
2154 if (dm->numVertData == 0) return;
2156 /* we don't want to overwrite any referenced layers */
2157 cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2159 /* fill in if it exists */
2160 face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
2162 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numTessFaceData);
2165 mesh_calc_normals_tessface(cddm->mvert, dm->numVertData,
2166 cddm->mface, dm->numTessFaceData, face_nors);
2172 * vtargetmap is a table that maps vertices to target vertices. a value of -1
2173 * indicates a vertex is a target, and is to be kept.
2175 * this frees dm, and returns a new one.
2177 * this is a really horribly written function. ger. - joeedh
2179 * note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
2181 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
2183 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2184 CDDerivedMesh *cddm2 = NULL;
2185 MVert *mv, *mvert = NULL;
2186 BLI_array_declare(mvert);
2187 MEdge *med, *medge = NULL;
2188 BLI_array_declare(medge);
2189 MPoly *mp, *mpoly = NULL;
2190 BLI_array_declare(mpoly);
2191 MLoop *ml, *mloop = NULL;
2192 BLI_array_declare(mloop);
2193 EdgeHash *ehash = BLI_edgehash_new();
2194 int *newv = NULL, *newe = NULL, *newl = NULL;
2195 int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2196 BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2197 int i, j, c, totloop, totpoly;
2199 totloop = dm->numLoopData;
2200 totpoly = dm->numPolyData;
2202 newv = MEM_callocN(sizeof(int)*dm->numVertData, "newv vtable CDDM_merge_verts");
2203 newe = MEM_callocN(sizeof(int)*dm->numEdgeData, "newv etable CDDM_merge_verts");
2204 newl = MEM_callocN(sizeof(int)*totloop, "newv ltable CDDM_merge_verts");
2206 /*fill newl with destination vertex indices*/
2209 for (i=0; i<dm->numVertData; i++, mv++) {
2210 if (vtargetmap[i] == -1) {
2211 BLI_array_append(oldv, i);
2213 BLI_array_append(mvert, *mv);
2217 /*now link target vertices to destination indices*/
2218 for (i=0; i<dm->numVertData; i++) {
2219 if (vtargetmap[i] != -1) {
2220 newv[i] = newv[vtargetmap[i]];
2224 /*find-replace merged vertices with target vertices*/
2226 for (i=0; i<totloop; i++, ml++) {
2227 if (vtargetmap[ml->v] != -1) {
2228 ml->v = vtargetmap[ml->v];
2232 /*now go through and fix edges and faces*/
2235 for (i=0; i<dm->numEdgeData; i++, med++) {
2237 if (LIKELY(med->v1 != med->v2)) {
2238 const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
2239 const unsigned int v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
2240 void **eh_p= BLI_edgehash_lookup_p(ehash, v1, v2);
2243 newe[i] = GET_INT_FROM_POINTER(*eh_p);
2246 BLI_array_append(olde, i);
2248 BLI_array_append(medge, *med);
2249 BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
2259 for (i=0; i<totpoly; i++, mp++) {
2262 ml = cddm->mloop + mp->loopstart;
2265 for (j=0; j<mp->totloop; j++, ml++) {
2266 med = cddm->medge + ml->e;
2267 if (LIKELY(med->v1 != med->v2)) {
2268 newl[j+mp->loopstart] = BLI_array_count(mloop);
2269 BLI_array_append(oldl, j+mp->loopstart);
2270 BLI_array_append(mloop, *ml);
2275 if (UNLIKELY(c == 0)) {
2279 mp2 = BLI_array_append_r(mpoly, *mp);
2281 mp2->loopstart = BLI_array_count(mloop) - c;
2283 BLI_array_append(oldp, i);
2287 cddm2 = (CDDerivedMesh*) CDDM_from_template((DerivedMesh*)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
2289 /*update edge indices and copy customdata*/
2291 for (i=0; i<cddm2->dm.numEdgeData; i++, med++) {
2292 if (newv[med->v1] != -1)
2293 med->v1 = newv[med->v1];
2294 if (newv[med->v2] != -1)
2295 med->v2 = newv[med->v2];
2297 CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
2300 /*update loop indices and copy customdata*/
2302 for (i=0; i<cddm2->dm.numLoopData; i++, ml++) {
2303 if (newe[ml->e] != -1)
2304 ml->e = newe[ml->e];
2305 if (newv[ml->v] != -1)
2306 ml->v = newv[ml->v];
2308 CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
2311 /*copy vertex customdata*/
2313 for (i=0; i<cddm2->dm.numVertData; i++, mv++) {
2314 CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
2317 /*copy poly customdata*/
2319 for (i=0; i<cddm2->dm.numPolyData; i++, mp++) {
2320 CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
2323 /*copy over data. CustomData_add_layer can do this, need to look it up.*/
2324 memcpy(cddm2->mvert, mvert, sizeof(MVert)*BLI_array_count(mvert));
2325 memcpy(cddm2->medge, medge, sizeof(MEdge)*BLI_array_count(medge));
2326 memcpy(cddm2->mloop, mloop, sizeof(MLoop)*BLI_array_count(mloop));
2327 memcpy(cddm2->mpoly, mpoly, sizeof(MPoly)*BLI_array_count(mpoly));
2328 BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
2345 BLI_edgehash_free(ehash, NULL);
2347 /*free old derivedmesh*/
2351 return (DerivedMesh*)cddm2;
2355 void CDDM_calc_edges_tessface(DerivedMesh *dm)
2357 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2358 CustomData edgeData;
2359 EdgeHashIterator *ehi;
2360 MFace *mf = cddm->mface;
2362 EdgeHash *eh = BLI_edgehash_new();
2363 int i, *index, numEdges, maxFaces = dm->numTessFaceData;
2365 for (i = 0; i < maxFaces; i++, mf++) {
2366 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2367 BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2368 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2369 BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2372 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2373 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2374 if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2375 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2378 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2379 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2383 numEdges = BLI_edgehash_size(eh);
2385 /* write new edges into a temporary CustomData */
2386 memset(&edgeData, 0, sizeof(edgeData));
2387 CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2388 CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2390 ehi = BLI_edgehashIterator_new(eh);
2391 med = CustomData_get_layer(&edgeData, CD_MEDGE);
2392 index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2393 for (i = 0; !BLI_edgehashIterator_isDone(ehi);
2394 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2395 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2397 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2398 *index = ORIGINDEX_NONE;
2400 BLI_edgehashIterator_free(ehi);
2402 /* free old CustomData and assign new one */
2403 CustomData_free(&dm->edgeData, dm->numEdgeData);
2404 dm->edgeData = edgeData;
2405 dm->numEdgeData = numEdges;
2407 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2409 BLI_edgehash_free(eh, NULL);
2412 /* warning, this uses existing edges but CDDM_calc_edges_tessface() doesn't */
2413 void CDDM_calc_edges(DerivedMesh *dm)
2415 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2416 CustomData edgeData;
2417 EdgeHashIterator *ehi;
2418 MPoly *mp = cddm->mpoly;
2421 EdgeHash *eh = BLI_edgehash_new();
2424 int i, j, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2426 eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2430 for (i=0; i < numEdges; i++, med++) {
2431 BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i+1));
2435 for (i=0; i < maxFaces; i++, mp++) {
2436 ml = cddm->mloop + mp->loopstart;
2437 for (j=0; j<mp->totloop; j++, ml++) {
2439 v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2440 if (!BLI_edgehash_haskey(eh, v1, v2)) {
2441 BLI_edgehash_insert(eh, v1, v2, NULL);
2446 numEdges = BLI_edgehash_size(eh);
2448 /* write new edges into a temporary CustomData */
2449 memset(&edgeData, 0, sizeof(edgeData));
2450 CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2451 CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2453 ehi = BLI_edgehashIterator_new(eh);
2454 med = CustomData_get_layer(&edgeData, CD_MEDGE);
2455 index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2456 for (i = 0; !BLI_edgehashIterator_isDone(ehi);
2457 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2458 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2459 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2461 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2462 *index = j==0 ? ORIGINDEX_NONE : eindex[j-1];
2464 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2466 BLI_edgehashIterator_free(ehi);
2468 /* free old CustomData and assign new one */
2469 CustomData_free(&dm->edgeData, dm->numEdgeData);
2470 dm->edgeData = edgeData;
2471 dm->numEdgeData = numEdges;
2473 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2476 for (i=0; i < maxFaces; i++, mp++) {
2477 ml = cddm->mloop + mp->loopstart;
2478 for (j=0; j<mp->totloop; j++, ml++) {
2480 v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2481 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2485 BLI_edgehash_free(eh, NULL);
2488 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2490 if (numVerts < dm->numVertData)
2491 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
2493 dm->numVertData = numVerts;
2496 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2498 if (numEdges < dm->numEdgeData)
2499 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
2501 dm->numEdgeData = numEdges;
2504 void CDDM_lower_num_tessfaces(DerivedMesh *dm, int numTessFaces)
2506 if (numTessFaces < dm->numTessFaceData)
2507 CustomData_free_elem(&dm->faceData, numTessFaces, dm->numTessFaceData-numTessFaces);
2509 dm->numTessFaceData = numTessFaces;
2512 void CDDM_lower_num_polys(DerivedMesh *dm, int numPolys)
2514 if (numPolys < dm->numPolyData)
2515 CustomData_free_elem(&dm->polyData, numPolys, dm->numPolyData-numPolys);
2517 dm->numPolyData = numPolys;
2520 /* mesh element access functions */
2522 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2524 return &((CDDerivedMesh*)dm)->mvert[index];
2527 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2529 return &((CDDerivedMesh*)dm)->medge[index];
2532 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2534 return &((CDDerivedMesh*)dm)->mface[index];
2537 MLoop *CDDM_get_loop(DerivedMesh *dm, int index)
2539 return &((CDDerivedMesh*)dm)->mloop[index];
2542 MPoly *CDDM_get_poly(DerivedMesh *dm, int index)
2544 return &((CDDerivedMesh*)dm)->mpoly[index];
2547 /* array access functions */
2549 MVert *CDDM_get_verts(DerivedMesh *dm)
2551 return ((CDDerivedMesh*)dm)->mvert;
2554 MEdge *CDDM_get_edges(DerivedMesh *dm)
2556 return ((CDDerivedMesh*)dm)->medge;
2559 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2561 return ((CDDerivedMesh*)dm)->mface;
2564 MLoop *CDDM_get_loops(DerivedMesh *dm)
2566 return ((CDDerivedMesh*)dm)->mloop;
2569 MPoly *CDDM_get_polys(DerivedMesh *dm)
2571 return ((CDDerivedMesh*)dm)->mpoly;
2574 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2576 /*converts mfaces to mpolys/mloops*/
2577 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2580 EdgeHash *eh = BLI_edgehash_new();
2583 /* ... on second thaughts, better comment this and assume caller knows edge state. */
2585 /* ensure we have all the edges we need */
2586 CDDM_calc_edges_tessface(dm);
2590 /* ensure we have correct edges on non release builds */
2591 i = cddm->dm.numEdgeData;
2592 CDDM_calc_edges_tessface(dm);
2593 BLI_assert(cddm->dm.numEdgeData == i);
2600 for (i=0; i<cddm->dm.numEdgeData; i++, me++) {
2601 BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i));
2606 for (i=0; i<cddm->dm.numTessFaceData; i++, mf++) {
2607 totloop += mf->v4 ? 4 : 3;
2610 CustomData_free(&cddm->dm.polyData, cddm->dm.numPolyData);
2611 CustomData_free(&cddm->dm.loopData, cddm->dm.numLoopData);
2613 cddm->dm.numLoopData = totloop;
2614 cddm->dm.numPolyData = cddm->dm.numTessFaceData;
2621 cddm->mloop = MEM_callocN(sizeof(MLoop)*totloop, "cddm->mloop in CDDM_tessfaces_to_faces");
2622 cddm->mpoly = MEM_callocN(sizeof(MPoly)*cddm->dm.numTessFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces");
2624 CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, cddm->mloop, totloop);
2625 CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, cddm->mpoly, cddm->dm.numPolyData);
2626 CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData,
2627 CD_MASK_ORIGINDEX, CD_DUPLICATE, cddm->dm.numTessFaceData);
2629 polyindex = CustomData_get_layer(&cddm->dm.faceData, CD_POLYINDEX);
2635 for (i=0; i<cddm->dm.numTessFaceData; i++, mf++, mp++, polyindex++) {
2636 mp->flag = mf->flag;
2638 mp->mat_nr = mf->mat_nr;
2639 mp->totloop = mf->v4 ? 4 : 3;
2642 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2));
2646 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v2, mf->v3));
2650 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v3, mf->v4?mf->v4:mf->v1));
2655 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v4, mf->v1));
2663 BLI_edgehash_free(eh, NULL);
2666 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2668 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2670 if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
2671 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
2673 cddm->mvert = mvert;
2676 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2678 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2680 if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
2681 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
2683 cddm->medge = medge;
2686 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2688 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2690 if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
2691 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numTessFaceData);
2693 cddm->mface = mface;
2696 void CDDM_set_mloop(DerivedMesh *dm, MLoop *mloop)
2698 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2700 if (!CustomData_has_layer(&dm->loopData, CD_MLOOP))
2701 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_ASSIGN, mloop, dm->numLoopData);
2703 cddm->mloop = mloop;
2706 void CDDM_set_mpoly(DerivedMesh *dm, MPoly *mpoly)
2708 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2710 if (!CustomData_has_layer(&dm->polyData, CD_MPOLY))
2711 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_ASSIGN, mpoly, dm->numPolyData);
2713 cddm->mpoly = mpoly;