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 minmax_v3v3_v3(min_r, max_r, cddm->mvert[i].co);
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 birth 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 PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
250 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
260 if (ob->sculpt->pbvh) {
261 cddm->pbvh = ob->sculpt->pbvh;
262 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
265 /* always build pbvh from original mesh, and only use it for drawing if
266 * this derivedmesh is just original mesh. it's the multires subsurf dm
267 * that this is actually for, to support a pbvh on a modified mesh */
268 if (!cddm->pbvh && ob->type == OB_MESH) {
269 SculptSession *ss = ob->sculpt;
273 cddm->pbvh = BLI_pbvh_new();
274 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
276 BKE_mesh_tessface_ensure(me);
278 BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
279 me->totface, me->totvert, &me->vdata);
281 deformed = ss->modifiers_active || me->key;
283 if (deformed && ob->derivedDeform) {
284 DerivedMesh *deformdm = ob->derivedDeform;
288 totvert = deformdm->getNumVerts(deformdm);
289 vertCos = MEM_callocN(3 * totvert * sizeof(float), "cdDM_getPBVH vertCos");
290 deformdm->getVertCos(deformdm, vertCos);
291 BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
299 /* update vertex normals so that drawing smooth faces works during sculpt
300 * TODO: proper fix is to support the pbvh in all drawing modes */
301 static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
303 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
304 float (*face_nors)[3];
306 if (!cddm->pbvh || !cddm->pbvh_draw || !dm->numTessFaceData)
309 face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
311 BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
314 static void cdDM_drawVerts(DerivedMesh *dm)
316 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
317 MVert *mv = cddm->mvert;
320 if (GPU_buffer_legacy(dm)) {
322 for (i = 0; i < dm->numVertData; i++, mv++)
326 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
327 GPU_vertex_setup(dm);
328 if (!GPU_buffer_legacy(dm)) {
329 if (dm->drawObject->tot_triangle_point)
330 glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point);
332 glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point);
338 static void cdDM_drawUVEdges(DerivedMesh *dm)
340 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
341 MFace *mf = cddm->mface;
342 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
346 if (GPU_buffer_legacy(dm)) {
348 for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) {
349 if (!(mf->flag & ME_HIDE)) {
350 glVertex2fv(tf->uv[0]);
351 glVertex2fv(tf->uv[1]);
353 glVertex2fv(tf->uv[1]);
354 glVertex2fv(tf->uv[2]);
357 glVertex2fv(tf->uv[2]);
358 glVertex2fv(tf->uv[0]);
361 glVertex2fv(tf->uv[2]);
362 glVertex2fv(tf->uv[3]);
364 glVertex2fv(tf->uv[3]);
365 glVertex2fv(tf->uv[0]);
377 GPU_uvedge_setup(dm);
378 if (!GPU_buffer_legacy(dm)) {
379 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
380 if (!(mf->flag & ME_HIDE)) {
386 if (prevdraw != draw) {
387 if (prevdraw > 0 && (curpos - prevstart) > 0) {
388 glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
400 if (prevdraw > 0 && (curpos - prevstart) > 0) {
401 glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
409 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
411 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
412 MVert *mvert = cddm->mvert;
413 MEdge *medge = cddm->medge;
416 if (GPU_buffer_legacy(dm)) {
417 DEBUG_VBO("Using legacy code. cdDM_drawEdges\n");
419 for (i = 0; i < dm->numEdgeData; i++, medge++) {
420 if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
421 (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
423 glVertex3fv(mvert[medge->v1].co);
424 glVertex3fv(mvert[medge->v2].co);
429 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
435 if (!GPU_buffer_legacy(dm)) {
436 for (i = 0; i < dm->numEdgeData; i++, medge++) {
437 if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
438 (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
445 if (prevdraw != draw) {
446 if (prevdraw > 0 && (i - prevstart) > 0) {
447 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
453 if (prevdraw > 0 && (i - prevstart) > 0) {
454 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
461 static void cdDM_drawLooseEdges(DerivedMesh *dm)
463 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
464 MVert *mvert = cddm->mvert;
465 MEdge *medge = cddm->medge;
468 if (GPU_buffer_legacy(dm)) {
469 DEBUG_VBO("Using legacy code. cdDM_drawLooseEdges\n");
471 for (i = 0; i < dm->numEdgeData; i++, medge++) {
472 if (medge->flag & ME_LOOSEEDGE) {
473 glVertex3fv(mvert[medge->v1].co);
474 glVertex3fv(mvert[medge->v2].co);
479 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
485 if (!GPU_buffer_legacy(dm)) {
486 for (i = 0; i < dm->numEdgeData; i++, medge++) {
487 if (medge->flag & ME_LOOSEEDGE) {
493 if (prevdraw != draw) {
494 if (prevdraw > 0 && (i - prevstart) > 0) {
495 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
501 if (prevdraw > 0 && (i - prevstart) > 0) {
502 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
509 static void cdDM_drawFacesSolid(DerivedMesh *dm,
510 float (*partial_redraw_planes)[4],
511 int UNUSED(fast), DMSetMaterial setMaterial)
513 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
514 MVert *mvert = cddm->mvert;
515 MFace *mface = cddm->mface;
516 float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
517 int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
519 #define PASSVERT(index) { \
520 if (shademodel == GL_SMOOTH) { \
521 short *no = mvert[index].no; \
524 glVertex3fv(mvert[index].co); \
527 if (cddm->pbvh && cddm->pbvh_draw) {
528 if (dm->numTessFaceData) {
529 float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
531 BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, setMaterial);
532 glShadeModel(GL_FLAT);
538 if (GPU_buffer_legacy(dm)) {
539 DEBUG_VBO("Using legacy code. cdDM_drawFacesSolid\n");
540 glBegin(glmode = GL_QUADS);
541 for (a = 0; a < dm->numTessFaceData; a++, mface++) {
542 int new_glmode, new_matnr, new_shademodel;
544 new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES;
545 new_matnr = mface->mat_nr + 1;
546 new_shademodel = (mface->flag & ME_SMOOTH) ? GL_SMOOTH : GL_FLAT;
548 if (new_glmode != glmode || new_matnr != matnr || new_shademodel != shademodel) {
551 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
553 glShadeModel(shademodel = new_shademodel);
554 glBegin(glmode = new_glmode);
557 if (drawCurrentMat) {
558 if (shademodel == GL_FLAT) {
563 /* TODO make this better (cache facenormals as layer?) */
566 normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
569 normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
587 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
588 GPU_vertex_setup(dm);
589 GPU_normal_setup(dm);
590 if (!GPU_buffer_legacy(dm)) {
591 glShadeModel(GL_SMOOTH);
592 for (a = 0; a < dm->drawObject->totmaterial; a++) {
593 if (setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
594 glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
595 dm->drawObject->materials[a].totpoint);
603 glShadeModel(GL_FLAT);
606 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
607 DMSetDrawOptionsTex drawParams,
608 DMSetDrawOptions drawParamsMapped,
609 DMCompareDrawOptions compareDrawOptions,
612 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
613 MVert *mv = cddm->mvert;
614 MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
615 MCol *realcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
616 float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
617 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
618 int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
619 int startFace = 0 /*, lastFlag = 0xdeadbeef */ /* UNUSED */;
620 MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
622 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
624 cdDM_update_normals_from_pbvh(dm);
626 if (GPU_buffer_legacy(dm)) {
627 DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n");
628 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
630 DMDrawOption draw_option;
631 unsigned char *cp = NULL;
634 draw_option = drawParams(tf ? &tf[i] : NULL, (mcol != NULL), mf->mat_nr);
639 if (orig == ORIGINDEX_NONE) { if (nors) nors += 3; continue; }
640 if (drawParamsMapped) { draw_option = drawParamsMapped(userData, orig); }
641 else { if (nors) nors += 3; continue; }
643 else if (drawParamsMapped) { draw_option = drawParamsMapped(userData, i); }
644 else { if (nors) nors += 3; continue; }
647 if (draw_option != DM_DRAW_OPTION_SKIP) {
648 if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol)
649 cp = (unsigned char *) &mcol[i * 4];
651 if (!(mf->flag & ME_SMOOTH)) {
658 normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
661 normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
667 glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
668 if (tf) glTexCoord2fv(tf[i].uv[0]);
669 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
671 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
672 glVertex3fv(mvert->co);
674 if (tf) glTexCoord2fv(tf[i].uv[1]);
675 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
677 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
678 glVertex3fv(mvert->co);
680 if (tf) glTexCoord2fv(tf[i].uv[2]);
681 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
683 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
684 glVertex3fv(mvert->co);
687 if (tf) glTexCoord2fv(tf[i].uv[3]);
688 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
690 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
691 glVertex3fv(mvert->co);
699 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
704 GPU_vertex_setup(dm);
705 GPU_normal_setup(dm);
709 if (realcol && dm->drawObject->colType == CD_TEXTURE_MCOL) {
712 else if (mcol && dm->drawObject->colType == CD_MCOL) {
719 unsigned char *colors = MEM_mallocN(dm->getNumTessFaces(dm) * 4 * 3 * sizeof(unsigned char), "cdDM_drawFacesTex_common");
720 for (i = 0; i < dm->getNumTessFaces(dm); i++) {
721 for (j = 0; j < 4; j++) {
722 /* bgr -> rgb is intentional (and stupid), but how its stored internally */
723 colors[i * 12 + j * 3] = col[i * 4 + j].b;
724 colors[i * 12 + j * 3 + 1] = col[i * 4 + j].g;
725 colors[i * 12 + j * 3 + 2] = col[i * 4 + j].r;
728 GPU_color3_upload(dm, colors);
731 dm->drawObject->colType = CD_TEXTURE_MCOL;
733 dm->drawObject->colType = CD_MCOL;
738 if (!GPU_buffer_legacy(dm)) {
739 int tottri = dm->drawObject->tot_triangle_point / 3;
740 int next_actualFace = dm->drawObject->triangle_to_mface[0];
742 glShadeModel(GL_SMOOTH);
743 /* lastFlag = 0; */ /* UNUSED */
744 for (i = 0; i < tottri; i++) {
745 int actualFace = next_actualFace;
746 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
750 next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
753 draw_option = drawParams(tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr);
757 orig = index[actualFace];
758 if (orig == ORIGINDEX_NONE) continue;
759 if (drawParamsMapped)
760 draw_option = drawParamsMapped(userData, orig);
763 if (drawParamsMapped)
764 draw_option = drawParamsMapped(userData, actualFace);
767 /* flush buffer if current triangle isn't drawable or it's last triangle */
768 flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
770 if (!flush && compareDrawOptions) {
771 /* also compare draw options and flush buffer if they're different
772 * need for face selection highlight in edit mode */
773 flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
777 int first = startFace * 3;
778 /* Add one to the length if we're drawing at the end of the array */
779 int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
787 glDrawArrays(GL_TRIANGLES, first, count);
796 glShadeModel(GL_FLAT);
800 static void cdDM_drawFacesTex(DerivedMesh *dm,
801 DMSetDrawOptionsTex setDrawOptions,
802 DMCompareDrawOptions compareDrawOptions,
805 cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
808 static void cdDM_drawMappedFaces(DerivedMesh *dm,
809 DMSetDrawOptions setDrawOptions,
810 DMSetMaterial setMaterial,
811 DMCompareDrawOptions compareDrawOptions,
812 void *userData, DMDrawFlag flag)
814 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
815 MVert *mv = cddm->mvert;
816 MFace *mf = cddm->mface;
818 float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL);
819 int useColors = flag & DM_DRAW_USE_COLORS;
820 int i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
822 mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL);
824 mc = DM_get_tessface_data_layer(dm, CD_PREVIEW_MCOL);
826 mc = DM_get_tessface_data_layer(dm, CD_MCOL);
828 cdDM_update_normals_from_pbvh(dm);
830 /* back-buffer always uses legacy since VBO's would need the
831 * color array temporarily overwritten for drawing, then reset. */
832 if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
833 DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n");
834 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
835 int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH);
836 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
838 orig = (index == NULL) ? i : *index++;
840 if (orig == ORIGINDEX_NONE)
841 draw_option = setMaterial(mf->mat_nr + 1, NULL);
842 else if (setDrawOptions != NULL)
843 draw_option = setDrawOptions(userData, orig);
845 if (draw_option != DM_DRAW_OPTION_SKIP) {
846 unsigned char *cp = NULL;
849 cp = (unsigned char *)&mc[i * 4];
851 /* no need to set shading mode to flat because
852 * normals are already used to change shading */
853 glShadeModel(GL_SMOOTH);
854 glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
863 normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
866 normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
871 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
872 glVertex3fv(mv[mf->v1].co);
873 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
874 glVertex3fv(mv[mf->v2].co);
875 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
876 glVertex3fv(mv[mf->v3].co);
878 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
879 glVertex3fv(mv[mf->v4].co);
883 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
884 glNormal3sv(mv[mf->v1].no);
885 glVertex3fv(mv[mf->v1].co);
886 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
887 glNormal3sv(mv[mf->v2].no);
888 glVertex3fv(mv[mf->v2].co);
889 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
890 glNormal3sv(mv[mf->v3].no);
891 glVertex3fv(mv[mf->v3].co);
893 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
894 glNormal3sv(mv[mf->v4].no);
895 glVertex3fv(mv[mf->v4].co);
905 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
907 GPU_vertex_setup(dm);
908 GPU_normal_setup(dm);
911 if (!GPU_buffer_legacy(dm)) {
912 int tottri = dm->drawObject->tot_triangle_point / 3;
913 glShadeModel(GL_SMOOTH);
916 /* avoid buffer problems in following code */
918 if (setDrawOptions == NULL) {
919 /* just draw the entire face array */
920 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
923 /* we need to check if the next material changes */
924 int next_actualFace = dm->drawObject->triangle_to_mface[0];
926 for (i = 0; i < tottri; i++) {
927 //int actualFace = dm->drawObject->triangle_to_mface[i];
928 int actualFace = next_actualFace;
929 MFace *mface = mf + actualFace;
930 /*int drawSmooth= (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */
931 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
935 next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
937 orig = (index == NULL) ? actualFace : index[actualFace];
939 if (orig == ORIGINDEX_NONE)
940 draw_option = setMaterial(mface->mat_nr + 1, NULL);
941 else if (setDrawOptions != NULL)
942 draw_option = setDrawOptions(userData, orig);
944 /* Goal is to draw as long of a contiguous triangle
945 * array as possible, so draw when we hit either an
946 * invisible triangle or at the end of the array */
948 /* flush buffer if current triangle isn't drawable or it's last triangle... */
949 flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
951 /* ... or when material setting is dissferent */
952 flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
954 if (!flush && compareDrawOptions) {
955 flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
959 int first = prevstart * 3;
960 /* Add one to the length if we're drawing at the end of the array */
961 int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
964 glDrawArrays(GL_TRIANGLES, first, count);
971 glShadeModel(GL_FLAT);
977 static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
978 DMSetDrawOptions setDrawOptions,
979 DMCompareDrawOptions compareDrawOptions,
982 cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
985 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
989 /* orco texture coordinates */
990 if (attribs->totorco) {
991 if (attribs->orco.gl_texco)
992 glTexCoord3fv(attribs->orco.array[index]);
994 glVertexAttrib3fvARB(attribs->orco.gl_index, attribs->orco.array[index]);
997 /* uv texture coordinates */
998 for (b = 0; b < attribs->tottface; b++) {
999 MTFace *tf = &attribs->tface[b].array[a];
1001 if (attribs->tface[b].gl_texco)
1002 glTexCoord2fv(tf->uv[vert]);
1004 glVertexAttrib2fvARB(attribs->tface[b].gl_index, tf->uv[vert]);
1008 for (b = 0; b < attribs->totmcol; b++) {
1009 MCol *cp = &attribs->mcol[b].array[a * 4 + vert];
1011 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1012 glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col);
1015 /* tangent for normal mapping */
1016 if (attribs->tottang) {
1017 float *tang = attribs->tang.array[a * 4 + vert];
1018 glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
1023 glNormal3sv(mvert[index].no);
1025 /* vertex coordinate */
1026 glVertex3fv(mvert[index].co);
1029 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
1030 DMSetMaterial setMaterial,
1031 DMSetDrawOptions setDrawOptions,
1034 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1035 GPUVertexAttribs gattribs;
1036 DMVertexAttribs attribs;
1037 MVert *mvert = cddm->mvert;
1038 MFace *mface = cddm->mface;
1039 /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1040 float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1041 int a, b, do_draw, matnr, new_matnr;
1042 int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1044 cdDM_update_normals_from_pbvh(dm);
1049 glShadeModel(GL_SMOOTH);
1051 if (GPU_buffer_legacy(dm) || setDrawOptions != NULL) {
1052 DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n");
1053 memset(&attribs, 0, sizeof(attribs));
1057 for (a = 0; a < dm->numTessFaceData; a++, mface++) {
1058 const int smoothnormal = (mface->flag & ME_SMOOTH);
1059 new_matnr = mface->mat_nr + 1;
1061 if (new_matnr != matnr) {
1064 do_draw = setMaterial(matnr = new_matnr, &gattribs);
1066 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1074 else if (setDrawOptions) {
1075 orig = (index) ? index[a] : a;
1077 if (orig == ORIGINDEX_NONE) {
1078 /* since the material is set by setMaterial(), faces with no
1079 * origin can be assumed to be generated by a modifier */
1083 else if (setDrawOptions(userData, orig) == DM_DRAW_OPTION_SKIP)
1087 if (!smoothnormal) {
1089 glNormal3fv(nors[a]);
1092 /* TODO ideally a normal layer should always be available */
1095 normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1098 normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1104 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1105 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1106 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1109 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1111 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1116 GPUBuffer *buffer = NULL;
1117 char *varray = NULL;
1118 int numdata = 0, elementsize = 0, offset;
1119 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1123 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1124 memset(&attribs, 0, sizeof(attribs));
1126 GPU_vertex_setup(dm);
1127 GPU_normal_setup(dm);
1129 if (!GPU_buffer_legacy(dm)) {
1130 for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) {
1132 a = dm->drawObject->triangle_to_mface[i];
1135 new_matnr = mface->mat_nr + 1;
1137 if (new_matnr != matnr) {
1138 numfaces = curface - start;
1145 GPU_buffer_unlock(buffer);
1147 GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
1150 glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3);
1154 GPU_buffer_free(buffer);
1163 /* prevdraw = do_draw; */ /* UNUSED */
1164 do_draw = setMaterial(matnr = new_matnr, &gattribs);
1166 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1168 if (attribs.totorco) {
1169 datatypes[numdata].index = attribs.orco.gl_index;
1170 datatypes[numdata].size = 3;
1171 datatypes[numdata].type = GL_FLOAT;
1174 for (b = 0; b < attribs.tottface; b++) {
1175 datatypes[numdata].index = attribs.tface[b].gl_index;
1176 datatypes[numdata].size = 2;
1177 datatypes[numdata].type = GL_FLOAT;
1180 for (b = 0; b < attribs.totmcol; b++) {
1181 datatypes[numdata].index = attribs.mcol[b].gl_index;
1182 datatypes[numdata].size = 4;
1183 datatypes[numdata].type = GL_UNSIGNED_BYTE;
1186 if (attribs.tottang) {
1187 datatypes[numdata].index = attribs.tang.gl_index;
1188 datatypes[numdata].size = 4;
1189 datatypes[numdata].type = GL_FLOAT;
1193 elementsize = GPU_attrib_element_size(datatypes, numdata);
1194 buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point);
1195 if (buffer == NULL) {
1196 GPU_buffer_unbind();
1197 dm->drawObject->legacy = 1;
1200 varray = GPU_buffer_lock_stream(buffer);
1201 if (varray == NULL) {
1202 GPU_buffer_unbind();
1203 GPU_buffer_free(buffer);
1204 dm->drawObject->legacy = 1;
1209 /* if the buffer was set, don't use it again.
1210 * prevdraw was assumed true but didnt run so set to false - [#21036] */
1211 /* prevdraw= 0; */ /* UNUSED */
1217 if (do_draw && numdata != 0) {
1219 if (attribs.totorco) {
1220 copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]);
1221 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]);
1222 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]);
1223 offset += sizeof(float) * 3;
1225 for (b = 0; b < attribs.tottface; b++) {
1226 MTFace *tf = &attribs.tface[b].array[a];
1227 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]);
1228 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]);
1230 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]);
1231 offset += sizeof(float) * 2;
1233 for (b = 0; b < attribs.totmcol; b++) {
1234 MCol *cp = &attribs.mcol[b].array[a * 4 + 0];
1236 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1237 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
1238 cp = &attribs.mcol[b].array[a * 4 + 1];
1239 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1240 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
1241 cp = &attribs.mcol[b].array[a * 4 + 2];
1242 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1243 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
1244 offset += sizeof(unsigned char) * 4;
1246 if (attribs.tottang) {
1247 float *tang = attribs.tang.array[a * 4 + 0];
1248 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
1249 tang = attribs.tang.array[a * 4 + 1];
1250 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
1251 tang = attribs.tang.array[a * 4 + 2];
1252 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
1253 offset += sizeof(float) * 4;
1259 if (do_draw && numdata != 0) {
1261 if (attribs.totorco) {
1262 copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]);
1263 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]);
1264 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]);
1265 offset += sizeof(float) * 3;
1267 for (b = 0; b < attribs.tottface; b++) {
1268 MTFace *tf = &attribs.tface[b].array[a];
1269 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]);
1270 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]);
1271 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]);
1272 offset += sizeof(float) * 2;
1274 for (b = 0; b < attribs.totmcol; b++) {
1275 MCol *cp = &attribs.mcol[b].array[a * 4 + 2];
1277 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1278 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
1279 cp = &attribs.mcol[b].array[a * 4 + 3];
1280 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1281 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
1282 cp = &attribs.mcol[b].array[a * 4 + 0];
1283 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1284 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
1285 offset += sizeof(unsigned char) * 4;
1287 if (attribs.tottang) {
1288 float *tang = attribs.tang.array[a * 4 + 2];
1289 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
1290 tang = attribs.tang.array[a * 4 + 3];
1291 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
1292 tang = attribs.tang.array[a * 4 + 0];
1293 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
1294 offset += sizeof(float) * 4;
1302 numfaces = curface - start;
1306 GPU_buffer_unlock(buffer);
1307 GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
1309 glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3);
1312 GPU_buffer_unbind();
1314 GPU_buffer_free(buffer);
1317 glShadeModel(GL_FLAT);
1320 static void cdDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
1322 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1325 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1326 void (*setMaterial)(void *userData, int, void *attribs),
1327 int (*setFace)(void *userData, int index), void *userData)
1329 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1330 GPUVertexAttribs gattribs;
1331 DMVertexAttribs attribs;
1332 MVert *mvert = cddm->mvert;
1333 MFace *mf = cddm->mface;
1334 float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1335 int a, matnr, new_matnr;
1336 int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1338 cdDM_update_normals_from_pbvh(dm);
1342 glShadeModel(GL_SMOOTH);
1344 memset(&attribs, 0, sizeof(attribs));
1348 for (a = 0; a < dm->numTessFaceData; a++, mf++) {
1349 const int smoothnormal = (mf->flag & ME_SMOOTH);
1352 new_matnr = mf->mat_nr + 1;
1354 if (new_matnr != matnr) {
1357 setMaterial(userData, matnr = new_matnr, &gattribs);
1358 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1363 /* skipping faces */
1365 orig = (index) ? index[a] : a;
1367 if (orig != ORIGINDEX_NONE && !setFace(userData, orig))
1372 if (!smoothnormal) {
1374 glNormal3fv(nors[a]);
1377 /* TODO ideally a normal layer should always be available */
1381 normal_quad_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1383 normal_tri_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1390 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1391 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1392 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1395 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1397 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1401 glShadeModel(GL_FLAT);
1404 static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData)
1406 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1407 MVert *vert = cddm->mvert;
1408 MEdge *edge = cddm->medge;
1409 int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1412 for (i = 0; i < dm->numEdgeData; i++, edge++) {
1415 if (setDrawOptions && orig == ORIGINDEX_NONE) continue;
1420 if (!setDrawOptions || (setDrawOptions(userData, orig) != DM_DRAW_OPTION_SKIP)) {
1421 glVertex3fv(vert[edge->v1].co);
1422 glVertex3fv(vert[edge->v2].co);
1428 static void cdDM_foreachMappedVert(
1430 void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
1433 MVert *mv = CDDM_get_verts(dm);
1434 int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1436 for (i = 0; i < dm->numVertData; i++, mv++) {
1439 if (orig == ORIGINDEX_NONE) continue;
1440 func(userData, orig, mv->co, NULL, mv->no);
1443 func(userData, i, mv->co, NULL, mv->no);
1447 static void cdDM_foreachMappedEdge(
1449 void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
1452 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1453 MVert *mv = cddm->mvert;
1454 MEdge *med = cddm->medge;
1455 int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1457 for (i = 0; i < dm->numEdgeData; i++, med++) {
1460 if (orig == ORIGINDEX_NONE) continue;
1461 func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1464 func(userData, i, mv[med->v1].co, mv[med->v2].co);
1468 static void cdDM_foreachMappedFaceCenter(
1470 void (*func)(void *userData, int index, const float cent[3], const float no[3]),
1473 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1474 MVert *mv = cddm->mvert;
1475 MPoly *mp = cddm->mpoly;
1476 MLoop *ml = cddm->mloop;
1477 int i, j, orig, *index;
1479 index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1481 for (i = 0; i < dm->numPolyData; i++, mp++) {
1487 if (orig == ORIGINDEX_NONE) continue;
1492 ml = &cddm->mloop[mp->loopstart];
1493 cent[0] = cent[1] = cent[2] = 0.0f;
1494 for (j = 0; j < mp->totloop; j++, ml++) {
1495 add_v3_v3v3(cent, cent, mv[ml->v].co);
1497 mul_v3_fl(cent, 1.0f / (float)j);
1499 ml = &cddm->mloop[mp->loopstart];
1505 mv[(ml + 3)->v].co);
1511 mv[(ml + 2)->v].co);
1514 func(userData, orig, cent, no);
1519 void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const int do_face_nor_cpy)
1521 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1523 dm->numTessFaceData = BKE_mesh_recalc_tessellation(&dm->faceData, &dm->loopData, &dm->polyData,
1525 dm->numTessFaceData, dm->numLoopData, dm->numPolyData,
1528 if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) {
1529 int *polyIndex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1530 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyIndex, dm->numTessFaceData);
1533 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1535 /* Tessellation recreated faceData, and the active layer indices need to get re-propagated
1536 * from loops and polys to faces */
1537 CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
1540 void CDDM_recalc_tessellation(DerivedMesh *dm)
1542 CDDM_recalc_tessellation_ex(dm, TRUE);
1545 static void cdDM_free_internal(CDDerivedMesh *cddm)
1547 if (cddm->pmap) MEM_freeN(cddm->pmap);
1548 if (cddm->pmap_mem) MEM_freeN(cddm->pmap_mem);
1551 static void cdDM_release(DerivedMesh *dm)
1553 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1555 if (DM_release(dm)) {
1556 cdDM_free_internal(cddm);
1561 int CDDM_Check(DerivedMesh *dm)
1563 return dm && dm->getMinMax == cdDM_getMinMax;
1566 /**************** CDDM interface functions ****************/
1567 static CDDerivedMesh *cdDM_create(const char *desc)
1569 CDDerivedMesh *cddm;
1572 cddm = MEM_callocN(sizeof(*cddm), desc);
1575 dm->getMinMax = cdDM_getMinMax;
1577 dm->getNumVerts = cdDM_getNumVerts;
1578 dm->getNumEdges = cdDM_getNumEdges;
1579 dm->getNumTessFaces = cdDM_getNumTessFaces;
1580 dm->getNumLoops = cdDM_getNumLoops;
1581 dm->getNumPolys = cdDM_getNumPolys;
1583 dm->getVert = cdDM_getVert;
1584 dm->getEdge = cdDM_getEdge;
1585 dm->getTessFace = cdDM_getTessFace;
1587 dm->copyVertArray = cdDM_copyVertArray;
1588 dm->copyEdgeArray = cdDM_copyEdgeArray;
1589 dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1590 dm->copyLoopArray = cdDM_copyLoopArray;
1591 dm->copyPolyArray = cdDM_copyPolyArray;
1593 dm->getVertData = DM_get_vert_data;
1594 dm->getEdgeData = DM_get_edge_data;
1595 dm->getTessFaceData = DM_get_tessface_data;
1596 dm->getVertDataArray = DM_get_vert_data_layer;
1597 dm->getEdgeDataArray = DM_get_edge_data_layer;
1598 dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1600 dm->calcNormals = CDDM_calc_normals_mapping;
1601 dm->recalcTessellation = CDDM_recalc_tessellation;
1603 dm->getVertCos = cdDM_getVertCos;
1604 dm->getVertCo = cdDM_getVertCo;
1605 dm->getVertNo = cdDM_getVertNo;
1607 dm->getPBVH = cdDM_getPBVH;
1608 dm->getPolyMap = cdDM_getPolyMap;
1610 dm->drawVerts = cdDM_drawVerts;
1612 dm->drawUVEdges = cdDM_drawUVEdges;
1613 dm->drawEdges = cdDM_drawEdges;
1614 dm->drawLooseEdges = cdDM_drawLooseEdges;
1615 dm->drawMappedEdges = cdDM_drawMappedEdges;
1617 dm->drawFacesSolid = cdDM_drawFacesSolid;
1618 dm->drawFacesTex = cdDM_drawFacesTex;
1619 dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1620 dm->drawMappedFaces = cdDM_drawMappedFaces;
1621 dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1622 dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1623 dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1625 dm->foreachMappedVert = cdDM_foreachMappedVert;
1626 dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1627 dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1629 dm->release = cdDM_release;
1634 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
1636 CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1637 DerivedMesh *dm = &cddm->dm;
1639 DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
1641 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1642 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1643 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
1644 CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces);
1645 CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1647 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1648 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1649 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
1650 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1651 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1653 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1654 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1655 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1656 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1657 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1662 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1664 CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1665 DerivedMesh *dm = &cddm->dm;
1666 CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1668 int *polyindex = NULL;
1670 /* this does a referenced copy, with an exception for fluidsim */
1672 DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1673 mesh->totloop, mesh->totpoly);
1675 dm->deformedOnly = 1;
1677 alloctype = CD_REFERENCE;
1679 CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1681 CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1683 CustomData_merge(&mesh->fdata, &dm->faceData, mask | CD_MASK_POLYINDEX, alloctype,
1685 CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1687 CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1690 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1691 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1692 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1693 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1694 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1696 /* commented since even when CD_POLYINDEX was first added this line fails
1697 * on the default cube, (after editmode toggle too) - campbell */
1699 BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_POLYINDEX));
1702 polyindex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1703 if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) {
1704 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyindex, mesh->totface);
1710 DerivedMesh *CDDM_from_curve(Object *ob)
1712 return CDDM_from_curve_customDB(ob, &ob->disp);
1715 DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
1718 CDDerivedMesh *cddm;
1723 int totvert, totedge, totloop, totpoly;
1725 if (BKE_mesh_nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
1726 &totedge, &allloop, &allpoly, &totloop, &totpoly) != 0)
1728 /* Error initializing mdata. This often happens when curve is empty */
1729 return CDDM_new(0, 0, 0, 0, 0);
1732 dm = CDDM_new(totvert, totedge, 0, totloop, totpoly);
1733 dm->deformedOnly = 1;
1735 cddm = (CDDerivedMesh *)dm;
1737 memcpy(cddm->mvert, allvert, totvert * sizeof(MVert));
1738 memcpy(cddm->medge, alledge, totedge * sizeof(MEdge));
1739 memcpy(cddm->mloop, allloop, totloop * sizeof(MLoop));
1740 memcpy(cddm->mpoly, allpoly, totpoly * sizeof(MPoly));
1747 CDDM_calc_edges(dm);
1752 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1753 int cdindex, BMLoop *l3[3],
1754 int numCol, int numTex)
1757 BMFace *f = l3[0]->f;
1763 int i, j, hasPCol = CustomData_has_layer(&bm->ldata, CD_PREVIEW_MLOOPCOL);
1765 for (i = 0; i < numTex; i++) {
1766 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1767 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1769 ME_MTEXFACE_CPY(texface, texpoly);
1771 for (j = 0; j < 3; j++) {
1773 mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1774 copy_v2_v2(texface->uv[j], mloopuv->uv);
1778 for (i = 0; i < numCol; i++) {
1779 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1781 for (j = 0; j < 3; j++) {
1783 mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1784 MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1789 mcol = CustomData_get(facedata, cdindex, CD_PREVIEW_MCOL);
1791 for (j = 0; j < 3; j++) {
1793 mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PREVIEW_MLOOPCOL);
1794 MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1799 DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdisps, int use_tessface)
1803 DerivedMesh *dm = CDDM_new(bm->totvert,
1805 use_tessface ? em->tottri : 0,
1809 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1814 MVert *mvert = cddm->mvert;
1815 MEdge *medge = cddm->medge;
1816 MFace *mface = cddm->mface;
1817 MLoop *mloop = cddm->mloop;
1818 MPoly *mpoly = cddm->mpoly;
1819 int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
1820 int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
1821 int *index, add_orig;
1822 int has_crease, has_edge_bweight, has_vert_bweight;
1823 CustomDataMask mask;
1826 has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1827 has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
1828 has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1830 dm->deformedOnly = 1;
1832 /*don't add origindex layer if one already exists*/
1833 add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
1835 mask = use_mdisps ? CD_MASK_DERIVEDMESH | CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1837 /* don't process shapekeys, we only feed them through the modifier stack as needed,
1838 * e.g. for applying modifiers or the like*/
1839 mask &= ~CD_MASK_SHAPEKEY;
1840 CustomData_merge(&bm->vdata, &dm->vertData, mask,
1841 CD_CALLOC, dm->numVertData);
1842 CustomData_merge(&bm->edata, &dm->edgeData, mask,
1843 CD_CALLOC, dm->numEdgeData);
1844 CustomData_merge(&bm->ldata, &dm->loopData, mask,
1845 CD_CALLOC, dm->numLoopData);
1846 CustomData_merge(&bm->pdata, &dm->polyData, mask,
1847 CD_CALLOC, dm->numPolyData);
1849 /*add tessellation mface layers*/
1851 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri);
1854 index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1856 eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1857 for (i = 0; eve; eve = BM_iter_step(&iter), i++, index++) {
1858 MVert *mv = &mvert[i];
1860 copy_v3_v3(mv->co, eve->co);
1862 BM_elem_index_set(eve, i); /* set_inline */
1864 normal_float_to_short_v3(mv->no, eve->no);
1866 mv->flag = BM_vert_flag_to_mflag(eve);
1868 if (has_vert_bweight)
1869 mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
1871 if (add_orig) *index = i;
1873 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
1875 bm->elem_index_dirty &= ~BM_VERT;
1877 index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1878 eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1879 for (i = 0; eed; eed = BM_iter_step(&iter), i++, index++) {
1880 MEdge *med = &medge[i];
1882 BM_elem_index_set(eed, i); /* set_inline */
1884 med->v1 = BM_elem_index_get(eed->v1);
1885 med->v2 = BM_elem_index_get(eed->v2);
1888 med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
1889 if (has_edge_bweight)
1890 med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
1892 med->flag = BM_edge_flag_to_mflag(eed);
1894 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
1895 if (add_orig) *index = i;
1897 bm->elem_index_dirty &= ~BM_EDGE;
1899 /* avoid this where possiblem, takes extra memory */
1903 BM_mesh_elem_index_ensure(bm, BM_FACE);
1905 polyindex = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
1906 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1907 for (i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) {
1908 MFace *mf = &mface[i];
1909 BMLoop **l = em->looptris[i];
1912 mf->v1 = BM_elem_index_get(l[0]->v);
1913 mf->v2 = BM_elem_index_get(l[1]->v);
1914 mf->v3 = BM_elem_index_get(l[2]->v);
1916 mf->mat_nr = efa->mat_nr;
1917 mf->flag = BM_face_flag_to_mflag(efa);
1919 *index = add_orig ? BM_elem_index_get(efa) : *(int *)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
1920 *polyindex = BM_elem_index_get(efa);
1922 loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
1923 test_index_face(mf, &dm->faceData, i, 3);
1927 index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1929 efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
1930 for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) {
1932 MPoly *mp = &mpoly[i];
1934 BM_elem_index_set(efa, i); /* set_inline */
1936 mp->totloop = efa->len;
1937 mp->flag = BM_face_flag_to_mflag(efa);
1939 mp->mat_nr = efa->mat_nr;
1941 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
1942 mloop->v = BM_elem_index_get(l->v);
1943 mloop->e = BM_elem_index_get(l->e);
1944 CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
1950 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
1952 if (add_orig) *index = i;
1954 bm->elem_index_dirty &= ~BM_FACE;
1959 static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
1961 CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
1962 DerivedMesh *dm = &cddm->dm;
1963 int numVerts = source->numVertData;
1964 int numEdges = source->numEdgeData;
1965 int numTessFaces = source->numTessFaceData;
1966 int numLoops = source->numLoopData;
1967 int numPolys = source->numPolyData;
1969 /* ensure these are created if they are made on demand */
1970 source->getVertDataArray(source, CD_ORIGINDEX);
1971 source->getEdgeDataArray(source, CD_ORIGINDEX);
1972 source->getTessFaceDataArray(source, CD_ORIGINDEX);
1974 /* this initializes dm, and copies all non mvert/medge/mface layers */
1975 DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
1976 numLoops, numPolys);
1977 dm->deformedOnly = source->deformedOnly;
1978 dm->dirty = source->dirty;
1980 CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
1981 CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
1982 CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
1984 /* now add mvert/medge/mface layers */
1985 cddm->mvert = source->dupVertArray(source);
1986 cddm->medge = source->dupEdgeArray(source);
1987 cddm->mface = source->dupTessFaceArray(source);
1989 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
1990 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
1991 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
1993 if (!faces_from_tessfaces)
1994 DM_DupPolys(source, dm);
1996 CDDM_tessfaces_to_faces(dm);
1998 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1999 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2004 DerivedMesh *CDDM_copy(DerivedMesh *source)
2006 return cddm_copy_ex(source, 0);
2009 DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
2011 return cddm_copy_ex(source, 1);
2014 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2015 * relationship between mesh data this needs to be set by the caller. */
2016 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2017 int numVerts, int numEdges, int numTessFaces,
2018 int numLoops, int numPolys)
2020 CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2021 DerivedMesh *dm = &cddm->dm;
2023 /* ensure these are created if they are made on demand */
2024 source->getVertDataArray(source, CD_ORIGINDEX);
2025 source->getEdgeDataArray(source, CD_ORIGINDEX);
2026 source->getTessFaceDataArray(source, CD_ORIGINDEX);
2028 /* this does a copy of all non mvert/medge/mface layers */
2029 DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
2031 /* now add mvert/medge/mface layers */
2032 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2033 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2034 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2035 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2036 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2038 if (!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2039 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2040 if (!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2041 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2042 if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2043 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2044 if (!CustomData_get_layer(&dm->faceData, CD_POLYINDEX))
2045 CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces);
2047 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2048 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2049 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2050 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2051 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2056 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2058 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2062 /* this will just return the pointer if it wasn't a referenced layer */
2063 vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2066 for (i = 0; i < dm->numVertData; ++i, ++vert)
2067 copy_v3_v3(vert->co, vertCoords[i]);
2070 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2072 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2076 /* this will just return the pointer if it wasn't a referenced layer */
2077 vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2080 for (i = 0; i < dm->numVertData; ++i, ++vert)
2081 copy_v3_v3_short(vert->no, vertNormals[i]);
2084 void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals)
2086 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2087 float (*face_nors)[3] = NULL;
2089 if (dm->numVertData == 0) return;
2091 /* now we skip calculating vertex normals for referenced layer,
2092 * no need to duplicate verts.
2093 * WATCH THIS, bmesh only change!,
2094 * need to take care of the side effects here - campbell */
2096 /* we don't want to overwrite any referenced layers */
2097 cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2101 if (dm->numTessFaceData == 0) {
2102 /* No tessellation on this mesh yet, need to calculate one.
2104 * Important not to update face normals from polys since it
2105 * interfears with assigning the new normal layer in the following code.
2107 CDDM_recalc_tessellation_ex(dm, FALSE);
2110 /* A tessellation already exists, it should always have a CD_POLYINDEX */
2111 BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX));
2112 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
2116 face_nors = MEM_mallocN(sizeof(float) * 3 * dm->numTessFaceData, "face_nors");
2118 /* calculate face normals */
2119 BKE_mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2120 dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData,
2121 CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors,
2124 CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN,
2125 face_nors, dm->numTessFaceData);
2129 void CDDM_calc_normals_mapping(DerivedMesh *dm)
2131 /* use this to skip calculating normals on original vert's, this may need to be changed */
2132 const short only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
2134 CDDM_calc_normals_mapping_ex(dm, only_face_normals);
2137 /* bmesh note: this matches what we have in trunk */
2138 void CDDM_calc_normals(DerivedMesh *dm)
2140 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2141 float (*poly_nors)[3];
2143 if (dm->numVertData == 0) return;
2145 /* we don't want to overwrite any referenced layers */
2146 cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2148 /* fill in if it exists */
2149 poly_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
2151 poly_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
2154 BKE_mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2155 dm->numLoopData, dm->numPolyData, poly_nors);
2158 void CDDM_calc_normals_tessface(DerivedMesh *dm)
2160 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2161 float (*face_nors)[3];
2163 if (dm->numVertData == 0) return;
2165 /* we don't want to overwrite any referenced layers */
2166 cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2168 /* fill in if it exists */
2169 face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
2171 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numTessFaceData);
2174 BKE_mesh_calc_normals_tessface(cddm->mvert, dm->numVertData,
2175 cddm->mface, dm->numTessFaceData, face_nors);
2181 * vtargetmap is a table that maps vertices to target vertices. a value of -1
2182 * indicates a vertex is a target, and is to be kept.
2184 * this frees dm, and returns a new one.
2186 * this is a really horribly written function. ger. - joeedh
2188 * note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
2190 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
2192 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2193 CDDerivedMesh *cddm2 = NULL;
2194 MVert *mv, *mvert = NULL;
2195 BLI_array_declare(mvert);
2196 MEdge *med, *medge = NULL;
2197 BLI_array_declare(medge);
2198 MPoly *mp, *mpoly = NULL;
2199 BLI_array_declare(mpoly);
2200 MLoop *ml, *mloop = NULL;
2201 BLI_array_declare(mloop);
2202 EdgeHash *ehash = BLI_edgehash_new();
2203 int *newv = NULL, *newe = NULL, *newl = NULL;
2204 int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2205 BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2206 int i, j, c, totloop, totpoly;
2208 totloop = dm->numLoopData;
2209 totpoly = dm->numPolyData;
2211 newv = MEM_callocN(sizeof(int) * dm->numVertData, "newv vtable CDDM_merge_verts");
2212 newe = MEM_callocN(sizeof(int) * dm->numEdgeData, "newv etable CDDM_merge_verts");
2213 newl = MEM_callocN(sizeof(int) * totloop, "newv ltable CDDM_merge_verts");
2215 /*fill newl with destination vertex indices*/
2218 for (i = 0; i < dm->numVertData; i++, mv++) {
2219 if (vtargetmap[i] == -1) {
2220 BLI_array_append(oldv, i);
2222 BLI_array_append(mvert, *mv);
2226 /*now link target vertices to destination indices*/
2227 for (i = 0; i < dm->numVertData; i++) {
2228 if (vtargetmap[i] != -1) {
2229 newv[i] = newv[vtargetmap[i]];
2233 /*find-replace merged vertices with target vertices*/
2235 for (i = 0; i < totloop; i++, ml++) {
2236 if (vtargetmap[ml->v] != -1) {
2237 ml->v = vtargetmap[ml->v];
2241 /*now go through and fix edges and faces*/
2244 for (i = 0; i < dm->numEdgeData; i++, med++) {
2246 if (LIKELY(med->v1 != med->v2)) {
2247 const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
2248 const unsigned int v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
2249 void **eh_p = BLI_edgehash_lookup_p(ehash, v1, v2);
2252 newe[i] = GET_INT_FROM_POINTER(*eh_p);
2255 BLI_array_append(olde, i);
2257 BLI_array_append(medge, *med);
2258 BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
2268 for (i = 0; i < totpoly; i++, mp++) {
2271 ml = cddm->mloop + mp->loopstart;
2274 for (j = 0; j < mp->totloop; j++, ml++) {
2275 med = cddm->medge + ml->e;
2276 if (LIKELY(med->v1 != med->v2)) {
2277 newl[j + mp->loopstart] = BLI_array_count(mloop);
2278 BLI_array_append(oldl, j + mp->loopstart);
2279 BLI_array_append(mloop, *ml);
2284 if (UNLIKELY(c == 0)) {
2288 mp2 = BLI_array_append_r(mpoly, *mp);
2290 mp2->loopstart = BLI_array_count(mloop) - c;
2292 BLI_array_append(oldp, i);
2296 cddm2 = (CDDerivedMesh *) CDDM_from_template((DerivedMesh *)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
2298 /*update edge indices and copy customdata*/
2300 for (i = 0; i < cddm2->dm.numEdgeData; i++, med++) {
2301 if (newv[med->v1] != -1)
2302 med->v1 = newv[med->v1];
2303 if (newv[med->v2] != -1)
2304 med->v2 = newv[med->v2];
2306 CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
2309 /*update loop indices and copy customdata*/
2311 for (i = 0; i < cddm2->dm.numLoopData; i++, ml++) {
2312 if (newe[ml->e] != -1)
2313 ml->e = newe[ml->e];
2314 if (newv[ml->v] != -1)
2315 ml->v = newv[ml->v];
2317 CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
2320 /*copy vertex customdata*/
2322 for (i = 0; i < cddm2->dm.numVertData; i++, mv++) {
2323 CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
2326 /*copy poly customdata*/
2328 for (i = 0; i < cddm2->dm.numPolyData; i++, mp++) {
2329 CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
2332 /*copy over data. CustomData_add_layer can do this, need to look it up.*/
2333 memcpy(cddm2->mvert, mvert, sizeof(MVert) * BLI_array_count(mvert));
2334 memcpy(cddm2->medge, medge, sizeof(MEdge) * BLI_array_count(medge));
2335 memcpy(cddm2->mloop, mloop, sizeof(MLoop) * BLI_array_count(mloop));
2336 memcpy(cddm2->mpoly, mpoly, sizeof(MPoly) * BLI_array_count(mpoly));
2337 BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
2354 BLI_edgehash_free(ehash, NULL);
2356 /*free old derivedmesh*/
2360 return (DerivedMesh *)cddm2;
2364 void CDDM_calc_edges_tessface(DerivedMesh *dm)
2366 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2367 CustomData edgeData;
2368 EdgeHashIterator *ehi;
2369 MFace *mf = cddm->mface;
2371 EdgeHash *eh = BLI_edgehash_new();
2372 int i, *index, numEdges, maxFaces = dm->numTessFaceData;
2374 for (i = 0; i < maxFaces; i++, mf++) {
2375 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2376 BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2377 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2378 BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2381 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2382 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2383 if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2384 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2387 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2388 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2392 numEdges = BLI_edgehash_size(eh);
2394 /* write new edges into a temporary CustomData */
2395 memset(&edgeData, 0, sizeof(edgeData));
2396 CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2397 CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2399 med = CustomData_get_layer(&edgeData, CD_MEDGE);
2400 index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2402 for (ehi = BLI_edgehashIterator_new(eh), i = 0;
2403 BLI_edgehashIterator_isDone(ehi) == FALSE;
2404 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
2406 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2408 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
2409 *index = ORIGINDEX_NONE;
2411 BLI_edgehashIterator_free(ehi);
2413 /* free old CustomData and assign new one */
2414 CustomData_free(&dm->edgeData, dm->numEdgeData);
2415 dm->edgeData = edgeData;
2416 dm->numEdgeData = numEdges;
2418 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2420 BLI_edgehash_free(eh, NULL);
2423 /* warning, this uses existing edges but CDDM_calc_edges_tessface() doesn't */
2424 void CDDM_calc_edges(DerivedMesh *dm)
2426 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2427 CustomData edgeData;
2428 EdgeHashIterator *ehi;
2429 MPoly *mp = cddm->mpoly;
2432 EdgeHash *eh = BLI_edgehash_new();
2435 int i, j, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2437 eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2441 for (i = 0; i < numEdges; i++, med++) {
2442 BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i + 1));
2446 for (i = 0; i < maxFaces; i++, mp++) {
2447 ml = cddm->mloop + mp->loopstart;
2448 for (j = 0; j < mp->totloop; j++, ml++) {
2450 v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2451 if (!BLI_edgehash_haskey(eh, v1, v2)) {
2452 BLI_edgehash_insert(eh, v1, v2, NULL);
2457 numEdges = BLI_edgehash_size(eh);
2459 /* write new edges into a temporary CustomData */
2460 memset(&edgeData, 0, sizeof(edgeData));
2461 CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2462 CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2464 med = CustomData_get_layer(&edgeData, CD_MEDGE);
2465 index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2467 for (ehi = BLI_edgehashIterator_new(eh), i = 0;
2468 BLI_edgehashIterator_isDone(ehi) == FALSE;
2469 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
2471 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2472 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2474 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
2475 *index = j == 0 ? ORIGINDEX_NONE : eindex[j - 1];
2477 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2479 BLI_edgehashIterator_free(ehi);
2481 /* free old CustomData and assign new one */
2482 CustomData_free(&dm->edgeData, dm->numEdgeData);
2483 dm->edgeData = edgeData;
2484 dm->numEdgeData = numEdges;
2486 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2489 for (i = 0; i < maxFaces; i++, mp++) {
2490 ml = cddm->mloop + mp->loopstart;
2491 for (j = 0; j < mp->totloop; j++, ml++) {
2493 v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2494 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2498 BLI_edgehash_free(eh, NULL);
2501 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2503 if (numVerts < dm->numVertData)
2504 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData - numVerts);
2506 dm->numVertData = numVerts;
2509 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2511 if (numEdges < dm->numEdgeData)
2512 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData - numEdges);
2514 dm->numEdgeData = numEdges;
2517 void CDDM_lower_num_tessfaces(DerivedMesh *dm, int numTessFaces)
2519 if (numTessFaces < dm->numTessFaceData)
2520 CustomData_free_elem(&dm->faceData, numTessFaces, dm->numTessFaceData - numTessFaces);
2522 dm->numTessFaceData = numTessFaces;
2525 void CDDM_lower_num_polys(DerivedMesh *dm, int numPolys)
2527 if (numPolys < dm->numPolyData)
2528 CustomData_free_elem(&dm->polyData, numPolys, dm->numPolyData - numPolys);
2530 dm->numPolyData = numPolys;
2533 /* mesh element access functions */
2535 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2537 return &((CDDerivedMesh *)dm)->mvert[index];
2540 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2542 return &((CDDerivedMesh *)dm)->medge[index];
2545 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2547 return &((CDDerivedMesh *)dm)->mface[index];
2550 MLoop *CDDM_get_loop(DerivedMesh *dm, int index)
2552 return &((CDDerivedMesh *)dm)->mloop[index];
2555 MPoly *CDDM_get_poly(DerivedMesh *dm, int index)
2557 return &((CDDerivedMesh *)dm)->mpoly[index];
2560 /* array access functions */
2562 MVert *CDDM_get_verts(DerivedMesh *dm)
2564 return ((CDDerivedMesh *)dm)->mvert;
2567 MEdge *CDDM_get_edges(DerivedMesh *dm)
2569 return ((CDDerivedMesh *)dm)->medge;
2572 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2574 return ((CDDerivedMesh *)dm)->mface;
2577 MLoop *CDDM_get_loops(DerivedMesh *dm)
2579 return ((CDDerivedMesh *)dm)->mloop;
2582 MPoly *CDDM_get_polys(DerivedMesh *dm)
2584 return ((CDDerivedMesh *)dm)->mpoly;
2587 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2589 /*converts mfaces to mpolys/mloops*/
2590 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2593 EdgeHash *eh = BLI_edgehash_new();
2596 /* ... on second thaughts, better comment this and assume caller knows edge state. */
2598 /* ensure we have all the edges we need */
2599 CDDM_calc_edges_tessface(dm);
2603 /* ensure we have correct edges on non release builds */
2604 i = cddm->dm.numEdgeData;
2605 CDDM_calc_edges_tessface(dm);
2606 BLI_assert(cddm->dm.numEdgeData == i);
2613 for (i = 0; i < cddm->dm.numEdgeData; i++, me++) {
2614 BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i));
2619 for (i = 0; i < cddm->dm.numTessFaceData; i++, mf++) {
2620 totloop += mf->v4 ? 4 : 3;
2623 CustomData_free(&cddm->dm.polyData, cddm->dm.numPolyData);
2624 CustomData_free(&cddm->dm.loopData, cddm->dm.numLoopData);
2626 cddm->dm.numLoopData = totloop;
2627 cddm->dm.numPolyData = cddm->dm.numTessFaceData;
2634 cddm->mloop = MEM_callocN(sizeof(MLoop) * totloop, "cddm->mloop in CDDM_tessfaces_to_faces");
2635 cddm->mpoly = MEM_callocN(sizeof(MPoly) * cddm->dm.numTessFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces");
2637 CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, cddm->mloop, totloop);
2638 CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, cddm->mpoly, cddm->dm.numPolyData);
2639 CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData,
2640 CD_MASK_ORIGINDEX, CD_DUPLICATE, cddm->dm.numTessFaceData);
2642 polyindex = CustomData_get_layer(&cddm->dm.faceData, CD_POLYINDEX);
2648 for (i = 0; i < cddm->dm.numTessFaceData; i++, mf++, mp++, polyindex++) {
2649 mp->flag = mf->flag;
2651 mp->mat_nr = mf->mat_nr;
2652 mp->totloop = mf->v4 ? 4 : 3;
2655 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2));
2659 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v2, mf->v3));
2663 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v3, mf->v4 ? mf->v4 : mf->v1));
2668 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v4, mf->v1));
2676 BLI_edgehash_free(eh, NULL);
2679 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2681 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2683 if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
2684 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
2686 cddm->mvert = mvert;
2689 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2691 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2693 if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
2694 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
2696 cddm->medge = medge;
2699 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2701 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2703 if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
2704 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numTessFaceData);
2706 cddm->mface = mface;
2709 void CDDM_set_mloop(DerivedMesh *dm, MLoop *mloop)
2711 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2713 if (!CustomData_has_layer(&dm->loopData, CD_MLOOP))
2714 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_ASSIGN, mloop, dm->numLoopData);
2716 cddm->mloop = mloop;
2719 void CDDM_set_mpoly(DerivedMesh *dm, MPoly *mpoly)
2721 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2723 if (!CustomData_has_layer(&dm->polyData, CD_MPOLY))
2724 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_ASSIGN, mpoly, dm->numPolyData);
2726 cddm->mpoly = mpoly;