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_tessmesh.h"
54 #include "BKE_curve.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 pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
278 BKE_mesh_tessface_ensure(me);
280 BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
281 me->totface, me->totvert, &me->vdata);
283 deformed = ss->modifiers_active || me->key;
285 if (deformed && ob->derivedDeform) {
286 DerivedMesh *deformdm = ob->derivedDeform;
290 totvert = deformdm->getNumVerts(deformdm);
291 vertCos = MEM_callocN(3 * totvert * sizeof(float), "cdDM_getPBVH vertCos");
292 deformdm->getVertCos(deformdm, vertCos);
293 BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
301 /* update vertex normals so that drawing smooth faces works during sculpt
302 * TODO: proper fix is to support the pbvh in all drawing modes */
303 static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
305 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
306 float (*face_nors)[3];
308 if (!cddm->pbvh || !cddm->pbvh_draw || !dm->numTessFaceData)
311 face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
313 BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
316 static void cdDM_drawVerts(DerivedMesh *dm)
318 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
319 MVert *mv = cddm->mvert;
322 if (GPU_buffer_legacy(dm)) {
324 for (i = 0; i < dm->numVertData; i++, mv++)
328 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
329 GPU_vertex_setup(dm);
330 if (!GPU_buffer_legacy(dm)) {
331 if (dm->drawObject->tot_triangle_point)
332 glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point);
334 glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point);
340 static void cdDM_drawUVEdges(DerivedMesh *dm)
342 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
343 MFace *mf = cddm->mface;
344 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
348 if (GPU_buffer_legacy(dm)) {
350 for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) {
351 if (!(mf->flag & ME_HIDE)) {
352 glVertex2fv(tf->uv[0]);
353 glVertex2fv(tf->uv[1]);
355 glVertex2fv(tf->uv[1]);
356 glVertex2fv(tf->uv[2]);
359 glVertex2fv(tf->uv[2]);
360 glVertex2fv(tf->uv[0]);
363 glVertex2fv(tf->uv[2]);
364 glVertex2fv(tf->uv[3]);
366 glVertex2fv(tf->uv[3]);
367 glVertex2fv(tf->uv[0]);
379 GPU_uvedge_setup(dm);
380 if (!GPU_buffer_legacy(dm)) {
381 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
382 if (!(mf->flag & ME_HIDE)) {
388 if (prevdraw != draw) {
389 if (prevdraw > 0 && (curpos - prevstart) > 0) {
390 glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
402 if (prevdraw > 0 && (curpos - prevstart) > 0) {
403 glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
411 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
413 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
414 MVert *mvert = cddm->mvert;
415 MEdge *medge = cddm->medge;
418 if (GPU_buffer_legacy(dm)) {
419 DEBUG_VBO("Using legacy code. cdDM_drawEdges\n");
421 for (i = 0; i < dm->numEdgeData; i++, medge++) {
422 if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
423 (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
425 glVertex3fv(mvert[medge->v1].co);
426 glVertex3fv(mvert[medge->v2].co);
431 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
437 if (!GPU_buffer_legacy(dm)) {
438 for (i = 0; i < dm->numEdgeData; i++, medge++) {
439 if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
440 (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
447 if (prevdraw != draw) {
448 if (prevdraw > 0 && (i - prevstart) > 0) {
449 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
455 if (prevdraw > 0 && (i - prevstart) > 0) {
456 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
463 static void cdDM_drawLooseEdges(DerivedMesh *dm)
465 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
466 MVert *mvert = cddm->mvert;
467 MEdge *medge = cddm->medge;
470 if (GPU_buffer_legacy(dm)) {
471 DEBUG_VBO("Using legacy code. cdDM_drawLooseEdges\n");
473 for (i = 0; i < dm->numEdgeData; i++, medge++) {
474 if (medge->flag & ME_LOOSEEDGE) {
475 glVertex3fv(mvert[medge->v1].co);
476 glVertex3fv(mvert[medge->v2].co);
481 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
487 if (!GPU_buffer_legacy(dm)) {
488 for (i = 0; i < dm->numEdgeData; i++, medge++) {
489 if (medge->flag & ME_LOOSEEDGE) {
495 if (prevdraw != draw) {
496 if (prevdraw > 0 && (i - prevstart) > 0) {
497 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
503 if (prevdraw > 0 && (i - prevstart) > 0) {
504 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
511 static void cdDM_drawFacesSolid(DerivedMesh *dm,
512 float (*partial_redraw_planes)[4],
513 int UNUSED(fast), DMSetMaterial setMaterial)
515 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
516 MVert *mvert = cddm->mvert;
517 MFace *mface = cddm->mface;
518 float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
519 int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
521 #define PASSVERT(index) { \
522 if (shademodel == GL_SMOOTH) { \
523 short *no = mvert[index].no; \
526 glVertex3fv(mvert[index].co); \
529 if (cddm->pbvh && cddm->pbvh_draw) {
530 if (dm->numTessFaceData) {
531 float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
533 BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, setMaterial);
534 glShadeModel(GL_FLAT);
540 if (GPU_buffer_legacy(dm)) {
541 DEBUG_VBO("Using legacy code. cdDM_drawFacesSolid\n");
542 glBegin(glmode = GL_QUADS);
543 for (a = 0; a < dm->numTessFaceData; a++, mface++) {
544 int new_glmode, new_matnr, new_shademodel;
546 new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES;
547 new_matnr = mface->mat_nr + 1;
548 new_shademodel = (mface->flag & ME_SMOOTH) ? GL_SMOOTH : GL_FLAT;
550 if (new_glmode != glmode || new_matnr != matnr || new_shademodel != shademodel) {
553 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
555 glShadeModel(shademodel = new_shademodel);
556 glBegin(glmode = new_glmode);
559 if (drawCurrentMat) {
560 if (shademodel == GL_FLAT) {
565 /* TODO make this better (cache facenormals as layer?) */
568 normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
571 normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
589 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
590 GPU_vertex_setup(dm);
591 GPU_normal_setup(dm);
592 if (!GPU_buffer_legacy(dm)) {
593 glShadeModel(GL_SMOOTH);
594 for (a = 0; a < dm->drawObject->totmaterial; a++) {
595 if (setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
596 glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
597 dm->drawObject->materials[a].totpoint);
605 glShadeModel(GL_FLAT);
608 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
609 DMSetDrawOptionsTex drawParams,
610 DMSetDrawOptions drawParamsMapped,
611 DMCompareDrawOptions compareDrawOptions,
614 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
615 MVert *mv = cddm->mvert;
616 MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
617 float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
618 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
621 int colType, startFace = 0;
624 const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
625 const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
626 if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
627 index_mf_to_mpoly = index_mp_to_orig = NULL;
630 colType = CD_TEXTURE_MCOL;
631 mcol = dm->getTessFaceDataArray(dm, colType);
633 colType = CD_PREVIEW_MCOL;
634 mcol = dm->getTessFaceDataArray(dm, colType);
638 mcol = dm->getTessFaceDataArray(dm, colType);
641 cdDM_update_normals_from_pbvh(dm);
643 if (GPU_buffer_legacy(dm)) {
644 DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n");
645 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
647 DMDrawOption draw_option;
648 unsigned char *cp = NULL;
651 draw_option = drawParams(tf ? &tf[i] : NULL, (mcol != NULL), mf->mat_nr);
654 if (index_mf_to_mpoly) {
655 orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i);
656 if (orig == ORIGINDEX_NONE) { if (nors) nors += 3; continue; }
657 if (drawParamsMapped) { draw_option = drawParamsMapped(userData, orig); }
658 else { if (nors) nors += 3; continue; }
660 else if (drawParamsMapped) { draw_option = drawParamsMapped(userData, i); }
661 else { if (nors) nors += 3; continue; }
664 if (draw_option != DM_DRAW_OPTION_SKIP) {
665 if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol)
666 cp = (unsigned char *) &mcol[i * 4];
668 if (!(mf->flag & ME_SMOOTH)) {
675 normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
678 normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
684 glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
685 if (tf) glTexCoord2fv(tf[i].uv[0]);
686 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
688 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
689 glVertex3fv(mvert->co);
691 if (tf) glTexCoord2fv(tf[i].uv[1]);
692 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
694 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
695 glVertex3fv(mvert->co);
697 if (tf) glTexCoord2fv(tf[i].uv[2]);
698 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
700 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
701 glVertex3fv(mvert->co);
704 if (tf) glTexCoord2fv(tf[i].uv[3]);
705 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
707 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
708 glVertex3fv(mvert->co);
716 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
717 GPU_vertex_setup(dm);
718 GPU_normal_setup(dm);
721 GPU_color_setup(dm, colType);
724 if (!GPU_buffer_legacy(dm)) {
725 int tottri = dm->drawObject->tot_triangle_point / 3;
726 int next_actualFace = dm->drawObject->triangle_to_mface[0];
728 glShadeModel(GL_SMOOTH);
729 /* lastFlag = 0; */ /* UNUSED */
730 for (i = 0; i < tottri; i++) {
731 int actualFace = next_actualFace;
732 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
736 next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
739 draw_option = drawParams(tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr);
742 if (index_mf_to_mpoly) {
743 orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace);
744 if (orig == ORIGINDEX_NONE) {
747 if (drawParamsMapped) {
748 draw_option = drawParamsMapped(userData, orig);
751 else if (drawParamsMapped) {
752 draw_option = drawParamsMapped(userData, actualFace);
756 /* flush buffer if current triangle isn't drawable or it's last triangle */
757 flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
759 if (!flush && compareDrawOptions) {
760 /* also compare draw options and flush buffer if they're different
761 * need for face selection highlight in edit mode */
762 flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
766 int first = startFace * 3;
767 /* Add one to the length if we're drawing at the end of the array */
768 int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
771 if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
776 glDrawArrays(GL_TRIANGLES, first, count);
785 glShadeModel(GL_FLAT);
789 static void cdDM_drawFacesTex(DerivedMesh *dm,
790 DMSetDrawOptionsTex setDrawOptions,
791 DMCompareDrawOptions compareDrawOptions,
794 cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
797 static void cdDM_drawMappedFaces(DerivedMesh *dm,
798 DMSetDrawOptions setDrawOptions,
799 DMSetMaterial setMaterial,
800 DMCompareDrawOptions compareDrawOptions,
801 void *userData, DMDrawFlag flag)
803 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
804 MVert *mv = cddm->mvert;
805 MFace *mf = cddm->mface;
807 float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL);
808 int colType, useColors = flag & DM_DRAW_USE_COLORS;
813 const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
814 const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
815 if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
816 index_mf_to_mpoly = index_mp_to_orig = NULL;
820 colType = CD_ID_MCOL;
821 mcol = DM_get_tessface_data_layer(dm, colType);
823 colType = CD_PREVIEW_MCOL;
824 mcol = DM_get_tessface_data_layer(dm, colType);
828 mcol = DM_get_tessface_data_layer(dm, colType);
831 cdDM_update_normals_from_pbvh(dm);
833 /* back-buffer always uses legacy since VBO's would need the
834 * color array temporarily overwritten for drawing, then reset. */
835 if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
836 DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n");
837 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
838 int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH);
839 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
841 orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
843 if (orig == ORIGINDEX_NONE)
844 draw_option = setMaterial(mf->mat_nr + 1, NULL);
845 else if (setDrawOptions != NULL)
846 draw_option = setDrawOptions(userData, orig);
848 if (draw_option != DM_DRAW_OPTION_SKIP) {
849 unsigned char *cp = NULL;
851 if (useColors && mcol)
852 cp = (unsigned char *)&mcol[i * 4];
854 /* no need to set shading mode to flat because
855 * normals are already used to change shading */
856 glShadeModel(GL_SMOOTH);
857 glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
866 normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
869 normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
874 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
875 glVertex3fv(mv[mf->v1].co);
876 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
877 glVertex3fv(mv[mf->v2].co);
878 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
879 glVertex3fv(mv[mf->v3].co);
881 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
882 glVertex3fv(mv[mf->v4].co);
886 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
887 glNormal3sv(mv[mf->v1].no);
888 glVertex3fv(mv[mf->v1].co);
889 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
890 glNormal3sv(mv[mf->v2].no);
891 glVertex3fv(mv[mf->v2].co);
892 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
893 glNormal3sv(mv[mf->v3].no);
894 glVertex3fv(mv[mf->v3].co);
896 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
897 glNormal3sv(mv[mf->v4].no);
898 glVertex3fv(mv[mf->v4].co);
908 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
910 GPU_vertex_setup(dm);
911 GPU_normal_setup(dm);
912 if (useColors && mcol) {
913 GPU_color_setup(dm, colType);
915 if (!GPU_buffer_legacy(dm)) {
916 int tottri = dm->drawObject->tot_triangle_point / 3;
917 glShadeModel(GL_SMOOTH);
920 /* avoid buffer problems in following code */
922 if (setDrawOptions == NULL) {
923 /* just draw the entire face array */
924 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
927 /* we need to check if the next material changes */
928 int next_actualFace = dm->drawObject->triangle_to_mface[0];
930 for (i = 0; i < tottri; i++) {
931 //int actualFace = dm->drawObject->triangle_to_mface[i];
932 int actualFace = next_actualFace;
933 MFace *mface = mf + actualFace;
934 /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */
935 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
939 next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
941 orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace;
943 if (orig == ORIGINDEX_NONE)
944 draw_option = setMaterial(mface->mat_nr + 1, NULL);
945 else if (setDrawOptions != NULL)
946 draw_option = setDrawOptions(userData, orig);
948 /* Goal is to draw as long of a contiguous triangle
949 * array as possible, so draw when we hit either an
950 * invisible triangle or at the end of the array */
952 /* flush buffer if current triangle isn't drawable or it's last triangle... */
953 flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
955 /* ... or when material setting is dissferent */
956 flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
958 if (!flush && compareDrawOptions) {
959 flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
963 int first = prevstart * 3;
964 /* Add one to the length if we're drawing at the end of the array */
965 int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
968 glDrawArrays(GL_TRIANGLES, first, count);
975 glShadeModel(GL_FLAT);
981 static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
982 DMSetDrawOptions setDrawOptions,
983 DMCompareDrawOptions compareDrawOptions,
986 cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
989 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
993 /* orco texture coordinates */
994 if (attribs->totorco) {
995 if (attribs->orco.gl_texco)
996 glTexCoord3fv(attribs->orco.array[index]);
998 glVertexAttrib3fvARB(attribs->orco.gl_index, attribs->orco.array[index]);
1001 /* uv texture coordinates */
1002 for (b = 0; b < attribs->tottface; b++) {
1003 MTFace *tf = &attribs->tface[b].array[a];
1005 if (attribs->tface[b].gl_texco)
1006 glTexCoord2fv(tf->uv[vert]);
1008 glVertexAttrib2fvARB(attribs->tface[b].gl_index, tf->uv[vert]);
1012 for (b = 0; b < attribs->totmcol; b++) {
1013 MCol *cp = &attribs->mcol[b].array[a * 4 + vert];
1015 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1016 glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col);
1019 /* tangent for normal mapping */
1020 if (attribs->tottang) {
1021 float *tang = attribs->tang.array[a * 4 + vert];
1022 glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
1027 glNormal3sv(mvert[index].no);
1029 /* vertex coordinate */
1030 glVertex3fv(mvert[index].co);
1033 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
1034 DMSetMaterial setMaterial,
1035 DMSetDrawOptions setDrawOptions,
1038 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1039 GPUVertexAttribs gattribs;
1040 DMVertexAttribs attribs;
1041 MVert *mvert = cddm->mvert;
1042 MFace *mface = cddm->mface;
1043 /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1044 float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1045 int a, b, do_draw, matnr, new_matnr;
1049 const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1050 const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1051 if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
1052 index_mf_to_mpoly = index_mp_to_orig = NULL;
1055 cdDM_update_normals_from_pbvh(dm);
1060 glShadeModel(GL_SMOOTH);
1062 if (GPU_buffer_legacy(dm) || setDrawOptions != NULL) {
1063 DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n");
1064 memset(&attribs, 0, sizeof(attribs));
1068 for (a = 0; a < dm->numTessFaceData; a++, mface++) {
1069 const int smoothnormal = (mface->flag & ME_SMOOTH);
1070 new_matnr = mface->mat_nr + 1;
1072 if (new_matnr != matnr) {
1075 do_draw = setMaterial(matnr = new_matnr, &gattribs);
1077 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1085 else if (setDrawOptions) {
1086 orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
1088 if (orig == ORIGINDEX_NONE) {
1089 /* since the material is set by setMaterial(), faces with no
1090 * origin can be assumed to be generated by a modifier */
1094 else if (setDrawOptions(userData, orig) == DM_DRAW_OPTION_SKIP)
1098 if (!smoothnormal) {
1100 glNormal3fv(nors[a]);
1103 /* TODO ideally a normal layer should always be available */
1106 normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1109 normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1115 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1116 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1117 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1120 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1122 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1127 GPUBuffer *buffer = NULL;
1128 char *varray = NULL;
1129 int numdata = 0, elementsize = 0, offset;
1130 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1134 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1135 memset(&attribs, 0, sizeof(attribs));
1137 GPU_vertex_setup(dm);
1138 GPU_normal_setup(dm);
1140 if (!GPU_buffer_legacy(dm)) {
1141 for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) {
1143 a = dm->drawObject->triangle_to_mface[i];
1146 new_matnr = mface->mat_nr + 1;
1148 if (new_matnr != matnr) {
1149 numfaces = curface - start;
1156 GPU_buffer_unlock(buffer);
1158 GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
1161 glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3);
1165 GPU_buffer_free(buffer);
1174 /* prevdraw = do_draw; */ /* UNUSED */
1175 do_draw = setMaterial(matnr = new_matnr, &gattribs);
1177 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1179 if (attribs.totorco) {
1180 datatypes[numdata].index = attribs.orco.gl_index;
1181 datatypes[numdata].size = 3;
1182 datatypes[numdata].type = GL_FLOAT;
1185 for (b = 0; b < attribs.tottface; b++) {
1186 datatypes[numdata].index = attribs.tface[b].gl_index;
1187 datatypes[numdata].size = 2;
1188 datatypes[numdata].type = GL_FLOAT;
1191 for (b = 0; b < attribs.totmcol; b++) {
1192 datatypes[numdata].index = attribs.mcol[b].gl_index;
1193 datatypes[numdata].size = 4;
1194 datatypes[numdata].type = GL_UNSIGNED_BYTE;
1197 if (attribs.tottang) {
1198 datatypes[numdata].index = attribs.tang.gl_index;
1199 datatypes[numdata].size = 4;
1200 datatypes[numdata].type = GL_FLOAT;
1204 elementsize = GPU_attrib_element_size(datatypes, numdata);
1205 buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point);
1206 if (buffer == NULL) {
1207 GPU_buffer_unbind();
1208 dm->drawObject->legacy = 1;
1211 varray = GPU_buffer_lock_stream(buffer);
1212 if (varray == NULL) {
1213 GPU_buffer_unbind();
1214 GPU_buffer_free(buffer);
1215 dm->drawObject->legacy = 1;
1220 /* if the buffer was set, don't use it again.
1221 * prevdraw was assumed true but didnt run so set to false - [#21036] */
1222 /* prevdraw = 0; */ /* UNUSED */
1228 if (do_draw && numdata != 0) {
1230 if (attribs.totorco) {
1231 copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]);
1232 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]);
1233 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]);
1234 offset += sizeof(float) * 3;
1236 for (b = 0; b < attribs.tottface; b++) {
1237 MTFace *tf = &attribs.tface[b].array[a];
1238 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]);
1239 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]);
1241 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]);
1242 offset += sizeof(float) * 2;
1244 for (b = 0; b < attribs.totmcol; b++) {
1245 MCol *cp = &attribs.mcol[b].array[a * 4 + 0];
1247 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1248 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
1249 cp = &attribs.mcol[b].array[a * 4 + 1];
1250 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1251 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
1252 cp = &attribs.mcol[b].array[a * 4 + 2];
1253 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1254 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
1255 offset += sizeof(unsigned char) * 4;
1257 if (attribs.tottang) {
1258 float *tang = attribs.tang.array[a * 4 + 0];
1259 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
1260 tang = attribs.tang.array[a * 4 + 1];
1261 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
1262 tang = attribs.tang.array[a * 4 + 2];
1263 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
1264 offset += sizeof(float) * 4;
1270 if (do_draw && numdata != 0) {
1272 if (attribs.totorco) {
1273 copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]);
1274 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]);
1275 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]);
1276 offset += sizeof(float) * 3;
1278 for (b = 0; b < attribs.tottface; b++) {
1279 MTFace *tf = &attribs.tface[b].array[a];
1280 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]);
1281 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]);
1282 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]);
1283 offset += sizeof(float) * 2;
1285 for (b = 0; b < attribs.totmcol; b++) {
1286 MCol *cp = &attribs.mcol[b].array[a * 4 + 2];
1288 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1289 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
1290 cp = &attribs.mcol[b].array[a * 4 + 3];
1291 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1292 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
1293 cp = &attribs.mcol[b].array[a * 4 + 0];
1294 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1295 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
1296 offset += sizeof(unsigned char) * 4;
1298 if (attribs.tottang) {
1299 float *tang = attribs.tang.array[a * 4 + 2];
1300 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
1301 tang = attribs.tang.array[a * 4 + 3];
1302 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
1303 tang = attribs.tang.array[a * 4 + 0];
1304 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
1305 offset += sizeof(float) * 4;
1313 numfaces = curface - start;
1317 GPU_buffer_unlock(buffer);
1318 GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
1320 glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3);
1323 GPU_buffer_unbind();
1325 GPU_buffer_free(buffer);
1328 glShadeModel(GL_FLAT);
1331 static void cdDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
1333 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1336 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1337 void (*setMaterial)(void *userData, int, void *attribs),
1338 int (*setFace)(void *userData, int index), void *userData)
1340 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1341 GPUVertexAttribs gattribs;
1342 DMVertexAttribs attribs;
1343 MVert *mvert = cddm->mvert;
1344 MFace *mf = cddm->mface;
1345 float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1346 int a, matnr, new_matnr;
1350 const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1351 const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1352 if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
1353 index_mf_to_mpoly = index_mp_to_orig = NULL;
1356 cdDM_update_normals_from_pbvh(dm);
1360 glShadeModel(GL_SMOOTH);
1362 memset(&attribs, 0, sizeof(attribs));
1366 for (a = 0; a < dm->numTessFaceData; a++, mf++) {
1367 const int smoothnormal = (mf->flag & ME_SMOOTH);
1370 new_matnr = mf->mat_nr + 1;
1372 if (new_matnr != matnr) {
1375 setMaterial(userData, matnr = new_matnr, &gattribs);
1376 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1381 /* skipping faces */
1383 orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
1385 if (orig != ORIGINDEX_NONE && !setFace(userData, orig))
1390 if (!smoothnormal) {
1392 glNormal3fv(nors[a]);
1395 /* TODO ideally a normal layer should always be available */
1399 normal_quad_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1401 normal_tri_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1408 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1409 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1410 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1413 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1415 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1419 glShadeModel(GL_FLAT);
1422 static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData)
1424 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1425 MVert *vert = cddm->mvert;
1426 MEdge *edge = cddm->medge;
1427 int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1430 for (i = 0; i < dm->numEdgeData; i++, edge++) {
1433 if (setDrawOptions && orig == ORIGINDEX_NONE) continue;
1438 if (!setDrawOptions || (setDrawOptions(userData, orig) != DM_DRAW_OPTION_SKIP)) {
1439 glVertex3fv(vert[edge->v1].co);
1440 glVertex3fv(vert[edge->v2].co);
1446 static void cdDM_foreachMappedVert(
1448 void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
1451 MVert *mv = CDDM_get_verts(dm);
1452 int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1454 for (i = 0; i < dm->numVertData; i++, mv++) {
1457 if (orig == ORIGINDEX_NONE) continue;
1458 func(userData, orig, mv->co, NULL, mv->no);
1461 func(userData, i, mv->co, NULL, mv->no);
1465 static void cdDM_foreachMappedEdge(
1467 void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
1470 CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1471 MVert *mv = cddm->mvert;
1472 MEdge *med = cddm->medge;
1473 int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1475 for (i = 0; i < dm->numEdgeData; i++, med++) {
1478 if (orig == ORIGINDEX_NONE) continue;
1479 func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1482 func(userData, i, mv[med->v1].co, mv[med->v2].co);
1486 static void cdDM_foreachMappedFaceCenter(
1488 void (*func)(void *userData, int index, const float cent[3], const float no[3]),
1491 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1492 MVert *mvert = cddm->mvert;
1495 int i, j, orig, *index;
1497 index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1499 for (i = 0; i < dm->numPolyData; i++, mp++) {
1505 if (orig == ORIGINDEX_NONE) continue;
1510 ml = &cddm->mloop[mp->loopstart];
1511 cent[0] = cent[1] = cent[2] = 0.0f;
1512 for (j = 0; j < mp->totloop; j++, ml++) {
1513 add_v3_v3v3(cent, cent, mvert[ml->v].co);
1515 mul_v3_fl(cent, 1.0f / (float)j);
1517 ml = &cddm->mloop[mp->loopstart];
1520 mvert[(ml + 0)->v].co,
1521 mvert[(ml + 1)->v].co,
1522 mvert[(ml + 2)->v].co,
1523 mvert[(ml + 3)->v].co);
1527 mvert[(ml + 0)->v].co,
1528 mvert[(ml + 1)->v].co,
1529 mvert[(ml + 2)->v].co);
1532 func(userData, orig, cent, no);
1537 void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const int do_face_nor_cpy)
1539 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1541 dm->numTessFaceData = BKE_mesh_recalc_tessellation(&dm->faceData, &dm->loopData, &dm->polyData,
1543 dm->numTessFaceData, dm->numLoopData, dm->numPolyData,
1546 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1548 /* Tessellation recreated faceData, and the active layer indices need to get re-propagated
1549 * from loops and polys to faces */
1550 CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
1553 void CDDM_recalc_tessellation(DerivedMesh *dm)
1555 CDDM_recalc_tessellation_ex(dm, TRUE);
1558 static void cdDM_free_internal(CDDerivedMesh *cddm)
1560 if (cddm->pmap) MEM_freeN(cddm->pmap);
1561 if (cddm->pmap_mem) MEM_freeN(cddm->pmap_mem);
1564 static void cdDM_release(DerivedMesh *dm)
1566 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1568 if (DM_release(dm)) {
1569 cdDM_free_internal(cddm);
1574 int CDDM_Check(DerivedMesh *dm)
1576 return dm && dm->getMinMax == cdDM_getMinMax;
1579 /**************** CDDM interface functions ****************/
1580 static CDDerivedMesh *cdDM_create(const char *desc)
1582 CDDerivedMesh *cddm;
1585 cddm = MEM_callocN(sizeof(*cddm), desc);
1588 dm->getMinMax = cdDM_getMinMax;
1590 dm->getNumVerts = cdDM_getNumVerts;
1591 dm->getNumEdges = cdDM_getNumEdges;
1592 dm->getNumTessFaces = cdDM_getNumTessFaces;
1593 dm->getNumLoops = cdDM_getNumLoops;
1594 dm->getNumPolys = cdDM_getNumPolys;
1596 dm->getVert = cdDM_getVert;
1597 dm->getEdge = cdDM_getEdge;
1598 dm->getTessFace = cdDM_getTessFace;
1600 dm->copyVertArray = cdDM_copyVertArray;
1601 dm->copyEdgeArray = cdDM_copyEdgeArray;
1602 dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1603 dm->copyLoopArray = cdDM_copyLoopArray;
1604 dm->copyPolyArray = cdDM_copyPolyArray;
1606 dm->getVertData = DM_get_vert_data;
1607 dm->getEdgeData = DM_get_edge_data;
1608 dm->getTessFaceData = DM_get_tessface_data;
1609 dm->getVertDataArray = DM_get_vert_data_layer;
1610 dm->getEdgeDataArray = DM_get_edge_data_layer;
1611 dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1613 dm->calcNormals = CDDM_calc_normals_mapping;
1614 dm->recalcTessellation = CDDM_recalc_tessellation;
1616 dm->getVertCos = cdDM_getVertCos;
1617 dm->getVertCo = cdDM_getVertCo;
1618 dm->getVertNo = cdDM_getVertNo;
1620 dm->getPBVH = cdDM_getPBVH;
1621 dm->getPolyMap = cdDM_getPolyMap;
1623 dm->drawVerts = cdDM_drawVerts;
1625 dm->drawUVEdges = cdDM_drawUVEdges;
1626 dm->drawEdges = cdDM_drawEdges;
1627 dm->drawLooseEdges = cdDM_drawLooseEdges;
1628 dm->drawMappedEdges = cdDM_drawMappedEdges;
1630 dm->drawFacesSolid = cdDM_drawFacesSolid;
1631 dm->drawFacesTex = cdDM_drawFacesTex;
1632 dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1633 dm->drawMappedFaces = cdDM_drawMappedFaces;
1634 dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1635 dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1636 dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1638 dm->foreachMappedVert = cdDM_foreachMappedVert;
1639 dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1640 dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1642 dm->release = cdDM_release;
1647 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
1649 CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1650 DerivedMesh *dm = &cddm->dm;
1652 DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
1654 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1655 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1656 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
1657 CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1659 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1660 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1661 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
1662 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1663 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1665 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1666 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1667 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1668 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1669 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1674 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1676 CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1677 DerivedMesh *dm = &cddm->dm;
1678 CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1681 /* this does a referenced copy, with an exception for fluidsim */
1683 DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1684 mesh->totloop, mesh->totpoly);
1686 dm->deformedOnly = 1;
1688 alloctype = CD_REFERENCE;
1690 CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1692 CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1694 CustomData_merge(&mesh->fdata, &dm->faceData, mask | CD_MASK_ORIGINDEX, alloctype,
1696 CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1698 CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1701 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1702 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1703 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1704 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1705 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1707 /* commented since even when CD_ORIGINDEX was first added this line fails
1708 * on the default cube, (after editmode toggle too) - campbell */
1710 BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX));
1716 DerivedMesh *CDDM_from_curve(Object *ob)
1718 return CDDM_from_curve_displist(ob, &ob->disp, NULL);
1721 DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob)
1723 int *orco_index_ptr = NULL;
1724 int (*orco_index)[4] = NULL;
1725 float (*orco)[3] = NULL;
1726 DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr);
1728 if (orco_index_ptr) {
1729 orco = (float (*)[3])BKE_curve_make_orco(scene, ob);
1732 if (orco && orco_index_ptr) {
1733 const char *uvname = "Orco";
1735 int totpoly = dm->getNumPolys(dm);
1737 MPoly *mpolys = dm->getPolyArray(dm);
1738 MLoop *mloops = dm->getLoopArray(dm);
1742 CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname);
1743 mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV, CD_DEFAULT, NULL, dm->numLoopData, uvname);
1745 BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly,
1751 MEM_freeN(orco_index);
1760 DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
1763 CDDerivedMesh *cddm;
1768 int totvert, totedge, totloop, totpoly;
1770 if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge,
1771 &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
1773 /* Error initializing mdata. This often happens when curve is empty */
1774 return CDDM_new(0, 0, 0, 0, 0);
1777 dm = CDDM_new(totvert, totedge, 0, totloop, totpoly);
1778 dm->deformedOnly = 1;
1780 cddm = (CDDerivedMesh *)dm;
1782 memcpy(cddm->mvert, allvert, totvert * sizeof(MVert));
1783 memcpy(cddm->medge, alledge, totedge * sizeof(MEdge));
1784 memcpy(cddm->mloop, allloop, totloop * sizeof(MLoop));
1785 memcpy(cddm->mpoly, allpoly, totpoly * sizeof(MPoly));
1792 CDDM_calc_edges(dm);
1797 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1798 int cdindex, const BMLoop *l3[3],
1799 int numCol, int numTex)
1802 BMFace *f = l3[0]->f;
1808 int i, j, hasPCol = CustomData_has_layer(&bm->ldata, CD_PREVIEW_MLOOPCOL);
1810 for (i = 0; i < numTex; i++) {
1811 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1812 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1814 ME_MTEXFACE_CPY(texface, texpoly);
1816 for (j = 0; j < 3; j++) {
1818 mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1819 copy_v2_v2(texface->uv[j], mloopuv->uv);
1823 for (i = 0; i < numCol; i++) {
1824 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1826 for (j = 0; j < 3; j++) {
1828 mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1829 MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1834 mcol = CustomData_get(facedata, cdindex, CD_PREVIEW_MCOL);
1836 for (j = 0; j < 3; j++) {
1838 mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PREVIEW_MLOOPCOL);
1839 MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1844 /* used for both editbmesh and bmesh */
1845 static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
1846 /* EditBMesh vars for use_tessface */
1848 const int em_tottri, const BMLoop *(*em_looptris)[3]
1851 DerivedMesh *dm = CDDM_new(bm->totvert,
1853 use_tessface ? em_tottri : 0,
1857 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1862 MVert *mvert = cddm->mvert;
1863 MEdge *medge = cddm->medge;
1864 MFace *mface = cddm->mface;
1865 MLoop *mloop = cddm->mloop;
1866 MPoly *mpoly = cddm->mpoly;
1867 int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
1868 int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
1869 int *index, add_orig;
1870 int has_crease, has_edge_bweight, has_vert_bweight;
1871 CustomDataMask mask;
1874 has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1875 has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
1876 has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1878 dm->deformedOnly = 1;
1880 /* don't add origindex layer if one already exists */
1881 add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
1883 mask = use_mdisps ? CD_MASK_DERIVEDMESH | CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1885 /* don't process shapekeys, we only feed them through the modifier stack as needed,
1886 * e.g. for applying modifiers or the like*/
1887 mask &= ~CD_MASK_SHAPEKEY;
1888 CustomData_merge(&bm->vdata, &dm->vertData, mask,
1889 CD_CALLOC, dm->numVertData);
1890 CustomData_merge(&bm->edata, &dm->edgeData, mask,
1891 CD_CALLOC, dm->numEdgeData);
1892 CustomData_merge(&bm->ldata, &dm->loopData, mask,
1893 CD_CALLOC, dm->numLoopData);
1894 CustomData_merge(&bm->pdata, &dm->polyData, mask,
1895 CD_CALLOC, dm->numPolyData);
1897 /* add tessellation mface layers */
1899 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em_tottri);
1902 index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1904 eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1905 for (i = 0; eve; eve = BM_iter_step(&iter), i++, index++) {
1906 MVert *mv = &mvert[i];
1908 copy_v3_v3(mv->co, eve->co);
1910 BM_elem_index_set(eve, i); /* set_inline */
1912 normal_float_to_short_v3(mv->no, eve->no);
1914 mv->flag = BM_vert_flag_to_mflag(eve);
1916 if (has_vert_bweight)
1917 mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
1919 if (add_orig) *index = i;
1921 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
1923 bm->elem_index_dirty &= ~BM_VERT;
1925 index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1926 eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1927 for (i = 0; eed; eed = BM_iter_step(&iter), i++, index++) {
1928 MEdge *med = &medge[i];
1930 BM_elem_index_set(eed, i); /* set_inline */
1932 med->v1 = BM_elem_index_get(eed->v1);
1933 med->v2 = BM_elem_index_get(eed->v2);
1936 med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
1937 if (has_edge_bweight)
1938 med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
1940 med->flag = BM_edge_flag_to_mflag(eed);
1942 /* handle this differently to editmode switching,
1943 * only enable draw for single user edges rather then calculating angle */
1944 if ((med->flag & ME_EDGEDRAW) == 0) {
1945 if (eed->l && eed->l == eed->l->radial_next) {
1946 med->flag |= ME_EDGEDRAW;
1950 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
1951 if (add_orig) *index = i;
1953 bm->elem_index_dirty &= ~BM_EDGE;
1955 /* avoid this where possiblem, takes extra memory */
1959 BM_mesh_elem_index_ensure(bm, BM_FACE);
1961 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1962 for (i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) {
1963 MFace *mf = &mface[i];
1964 const BMLoop **l = em_looptris[i];
1967 mf->v1 = BM_elem_index_get(l[0]->v);
1968 mf->v2 = BM_elem_index_get(l[1]->v);
1969 mf->v3 = BM_elem_index_get(l[2]->v);
1971 mf->mat_nr = efa->mat_nr;
1972 mf->flag = BM_face_flag_to_mflag(efa);
1974 /* map mfaces to polygons in the same cddm intentionally */
1975 *index = BM_elem_index_get(efa);
1977 loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
1978 test_index_face(mf, &dm->faceData, i, 3);
1982 index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1984 efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
1985 for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) {
1987 MPoly *mp = &mpoly[i];
1989 BM_elem_index_set(efa, i); /* set_inline */
1991 mp->totloop = efa->len;
1992 mp->flag = BM_face_flag_to_mflag(efa);
1994 mp->mat_nr = efa->mat_nr;
1996 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
1997 mloop->v = BM_elem_index_get(l->v);
1998 mloop->e = BM_elem_index_get(l->e);
1999 CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
2005 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
2007 if (add_orig) *index = i;
2009 bm->elem_index_dirty &= ~BM_FACE;
2014 struct DerivedMesh *CDDM_from_bmesh(struct BMesh *bm, int use_mdisps)
2016 return cddm_from_bmesh_ex(bm, use_mdisps, FALSE,
2017 /* these vars are for editmesh only */
2021 DerivedMesh *CDDM_from_editbmesh(BMEditMesh *em, int use_mdisps, int use_tessface)
2023 return cddm_from_bmesh_ex(em->bm, use_mdisps,
2025 use_tessface, em->tottri, (const BMLoop *(*)[3])em->looptris);
2028 static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
2030 CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
2031 DerivedMesh *dm = &cddm->dm;
2032 int numVerts = source->numVertData;
2033 int numEdges = source->numEdgeData;
2034 int numTessFaces = source->numTessFaceData;
2035 int numLoops = source->numLoopData;
2036 int numPolys = source->numPolyData;
2038 /* ensure these are created if they are made on demand */
2039 source->getVertDataArray(source, CD_ORIGINDEX);
2040 source->getEdgeDataArray(source, CD_ORIGINDEX);
2041 source->getTessFaceDataArray(source, CD_ORIGINDEX);
2042 source->getPolyDataArray(source, CD_ORIGINDEX);
2044 /* this initializes dm, and copies all non mvert/medge/mface layers */
2045 DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
2046 numLoops, numPolys);
2047 dm->deformedOnly = source->deformedOnly;
2048 dm->dirty = source->dirty;
2050 CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
2051 CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
2052 CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
2054 /* now add mvert/medge/mface layers */
2055 cddm->mvert = source->dupVertArray(source);
2056 cddm->medge = source->dupEdgeArray(source);
2057 cddm->mface = source->dupTessFaceArray(source);
2059 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
2060 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
2061 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
2063 if (!faces_from_tessfaces)
2064 DM_DupPolys(source, dm);
2066 CDDM_tessfaces_to_faces(dm);
2068 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2069 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2074 DerivedMesh *CDDM_copy(DerivedMesh *source)
2076 return cddm_copy_ex(source, 0);
2079 DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
2081 return cddm_copy_ex(source, 1);
2084 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2085 * relationship between mesh data this needs to be set by the caller. */
2086 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2087 int numVerts, int numEdges, int numTessFaces,
2088 int numLoops, int numPolys)
2090 CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2091 DerivedMesh *dm = &cddm->dm;
2093 /* ensure these are created if they are made on demand */
2094 source->getVertDataArray(source, CD_ORIGINDEX);
2095 source->getEdgeDataArray(source, CD_ORIGINDEX);
2096 source->getTessFaceDataArray(source, CD_ORIGINDEX);
2097 source->getPolyDataArray(source, CD_ORIGINDEX);
2099 /* this does a copy of all non mvert/medge/mface layers */
2100 DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
2102 /* now add mvert/medge/mface layers */
2103 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2104 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2105 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2106 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2107 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2109 if (!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2110 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2111 if (!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2112 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2113 if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2114 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2116 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2117 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2118 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2119 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2120 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2125 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2127 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2131 /* this will just return the pointer if it wasn't a referenced layer */
2132 vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2135 for (i = 0; i < dm->numVertData; ++i, ++vert)
2136 copy_v3_v3(vert->co, vertCoords[i]);
2139 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2141 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2145 /* this will just return the pointer if it wasn't a referenced layer */
2146 vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2149 for (i = 0; i < dm->numVertData; ++i, ++vert)
2150 copy_v3_v3_short(vert->no, vertNormals[i]);
2153 void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals)
2155 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2156 float (*face_nors)[3] = NULL;
2158 if (dm->numVertData == 0) return;
2160 /* now we skip calculating vertex normals for referenced layer,
2161 * no need to duplicate verts.
2162 * WATCH THIS, bmesh only change!,
2163 * need to take care of the side effects here - campbell */
2165 /* we don't want to overwrite any referenced layers */
2166 cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2170 if (dm->numTessFaceData == 0) {
2171 /* No tessellation on this mesh yet, need to calculate one.
2173 * Important not to update face normals from polys since it
2174 * interferes with assigning the new normal layer in the following code.
2176 CDDM_recalc_tessellation_ex(dm, FALSE);
2179 /* A tessellation already exists, it should always have a CD_ORIGINDEX */
2180 BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX));
2181 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
2185 face_nors = MEM_mallocN(sizeof(float) * 3 * dm->numTessFaceData, "face_nors");
2187 /* calculate face normals */
2188 BKE_mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2189 dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData,
2190 CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors,
2193 CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN,
2194 face_nors, dm->numTessFaceData);
2198 void CDDM_calc_normals_mapping(DerivedMesh *dm)
2200 /* use this to skip calculating normals on original vert's, this may need to be changed */
2201 const short only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
2203 CDDM_calc_normals_mapping_ex(dm, only_face_normals);
2206 /* bmesh note: this matches what we have in trunk */
2207 void CDDM_calc_normals(DerivedMesh *dm)
2209 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2210 float (*poly_nors)[3];
2212 if (dm->numVertData == 0) return;
2214 /* we don't want to overwrite any referenced layers */
2215 cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2217 /* fill in if it exists */
2218 poly_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
2220 poly_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
2223 BKE_mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2224 dm->numLoopData, dm->numPolyData, poly_nors);
2227 void CDDM_calc_normals_tessface(DerivedMesh *dm)
2229 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2230 float (*face_nors)[3];
2232 if (dm->numVertData == 0) return;
2234 /* we don't want to overwrite any referenced layers */
2235 cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2237 /* fill in if it exists */
2238 face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
2240 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numTessFaceData);
2243 BKE_mesh_calc_normals_tessface(cddm->mvert, dm->numVertData,
2244 cddm->mface, dm->numTessFaceData, face_nors);
2250 * vtargetmap is a table that maps vertices to target vertices. a value of -1
2251 * indicates a vertex is a target, and is to be kept.
2253 * this frees dm, and returns a new one.
2255 * this is a really horribly written function. ger. - joeedh
2257 * note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
2259 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
2261 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2262 CDDerivedMesh *cddm2 = NULL;
2263 MVert *mv, *mvert = NULL;
2264 BLI_array_declare(mvert);
2265 MEdge *med, *medge = NULL;
2266 BLI_array_declare(medge);
2267 MPoly *mp, *mpoly = NULL;
2268 BLI_array_declare(mpoly);
2269 MLoop *ml, *mloop = NULL;
2270 BLI_array_declare(mloop);
2271 EdgeHash *ehash = BLI_edgehash_new();
2272 int *newv = NULL, *newe = NULL, *newl = NULL;
2273 int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2274 BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2275 int i, j, c, totloop, totpoly;
2277 totloop = dm->numLoopData;
2278 totpoly = dm->numPolyData;
2280 newv = MEM_callocN(sizeof(int) * dm->numVertData, "newv vtable CDDM_merge_verts");
2281 newe = MEM_callocN(sizeof(int) * dm->numEdgeData, "newv etable CDDM_merge_verts");
2282 newl = MEM_callocN(sizeof(int) * totloop, "newv ltable CDDM_merge_verts");
2284 /* fill newl with destination vertex indices */
2287 for (i = 0; i < dm->numVertData; i++, mv++) {
2288 if (vtargetmap[i] == -1) {
2289 BLI_array_append(oldv, i);
2291 BLI_array_append(mvert, *mv);
2295 /* now link target vertices to destination indices */
2296 for (i = 0; i < dm->numVertData; i++) {
2297 if (vtargetmap[i] != -1) {
2298 newv[i] = newv[vtargetmap[i]];
2302 /* find-replace merged vertices with target vertices */
2304 for (i = 0; i < totloop; i++, ml++) {
2305 if (vtargetmap[ml->v] != -1) {
2306 ml->v = vtargetmap[ml->v];
2310 /* now go through and fix edges and faces */
2313 for (i = 0; i < dm->numEdgeData; i++, med++) {
2315 if (LIKELY(med->v1 != med->v2)) {
2316 const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
2317 const unsigned int v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
2318 void **eh_p = BLI_edgehash_lookup_p(ehash, v1, v2);
2321 newe[i] = GET_INT_FROM_POINTER(*eh_p);
2324 BLI_array_append(olde, i);
2326 BLI_array_append(medge, *med);
2327 BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
2337 for (i = 0; i < totpoly; i++, mp++) {
2340 ml = cddm->mloop + mp->loopstart;
2343 for (j = 0; j < mp->totloop; j++, ml++) {
2344 med = cddm->medge + ml->e;
2345 if (LIKELY(med->v1 != med->v2)) {
2346 newl[j + mp->loopstart] = BLI_array_count(mloop);
2347 BLI_array_append(oldl, j + mp->loopstart);
2348 BLI_array_append(mloop, *ml);
2353 if (UNLIKELY(c == 0)) {
2357 mp2 = BLI_array_append_r(mpoly, *mp);
2359 mp2->loopstart = BLI_array_count(mloop) - c;
2361 BLI_array_append(oldp, i);
2365 cddm2 = (CDDerivedMesh *) CDDM_from_template((DerivedMesh *)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
2367 /*update edge indices and copy customdata*/
2369 for (i = 0; i < cddm2->dm.numEdgeData; i++, med++) {
2370 if (newv[med->v1] != -1)
2371 med->v1 = newv[med->v1];
2372 if (newv[med->v2] != -1)
2373 med->v2 = newv[med->v2];
2375 CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
2378 /*update loop indices and copy customdata*/
2380 for (i = 0; i < cddm2->dm.numLoopData; i++, ml++) {
2381 if (newe[ml->e] != -1)
2382 ml->e = newe[ml->e];
2383 if (newv[ml->v] != -1)
2384 ml->v = newv[ml->v];
2386 CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
2389 /*copy vertex customdata*/
2391 for (i = 0; i < cddm2->dm.numVertData; i++, mv++) {
2392 CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
2395 /*copy poly customdata*/
2397 for (i = 0; i < cddm2->dm.numPolyData; i++, mp++) {
2398 CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
2401 /*copy over data. CustomData_add_layer can do this, need to look it up.*/
2402 memcpy(cddm2->mvert, mvert, sizeof(MVert) * BLI_array_count(mvert));
2403 memcpy(cddm2->medge, medge, sizeof(MEdge) * BLI_array_count(medge));
2404 memcpy(cddm2->mloop, mloop, sizeof(MLoop) * BLI_array_count(mloop));
2405 memcpy(cddm2->mpoly, mpoly, sizeof(MPoly) * BLI_array_count(mpoly));
2406 BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
2423 BLI_edgehash_free(ehash, NULL);
2425 /*free old derivedmesh*/
2429 return (DerivedMesh *)cddm2;
2433 void CDDM_calc_edges_tessface(DerivedMesh *dm)
2435 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2436 CustomData edgeData;
2437 EdgeHashIterator *ehi;
2438 MFace *mf = cddm->mface;
2440 EdgeHash *eh = BLI_edgehash_new();
2441 int i, *index, numEdges, maxFaces = dm->numTessFaceData;
2443 for (i = 0; i < maxFaces; i++, mf++) {
2444 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2445 BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2446 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2447 BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2450 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2451 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2452 if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2453 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2456 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2457 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2461 numEdges = BLI_edgehash_size(eh);
2463 /* write new edges into a temporary CustomData */
2464 CustomData_reset(&edgeData);
2465 CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2466 CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2468 med = CustomData_get_layer(&edgeData, CD_MEDGE);
2469 index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2471 for (ehi = BLI_edgehashIterator_new(eh), i = 0;
2472 BLI_edgehashIterator_isDone(ehi) == FALSE;
2473 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
2475 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2477 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
2478 *index = ORIGINDEX_NONE;
2480 BLI_edgehashIterator_free(ehi);
2482 /* free old CustomData and assign new one */
2483 CustomData_free(&dm->edgeData, dm->numEdgeData);
2484 dm->edgeData = edgeData;
2485 dm->numEdgeData = numEdges;
2487 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2489 BLI_edgehash_free(eh, NULL);
2492 /* warning, this uses existing edges but CDDM_calc_edges_tessface() doesn't */
2493 void CDDM_calc_edges(DerivedMesh *dm)
2495 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2496 CustomData edgeData;
2497 EdgeHashIterator *ehi;
2498 MPoly *mp = cddm->mpoly;
2501 EdgeHash *eh = BLI_edgehash_new();
2504 int i, j, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2506 eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2510 for (i = 0; i < numEdges; i++, med++) {
2511 BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i + 1));
2515 for (i = 0; i < maxFaces; i++, mp++) {
2516 ml = cddm->mloop + mp->loopstart;
2517 for (j = 0; j < mp->totloop; j++, ml++) {
2519 v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2520 if (!BLI_edgehash_haskey(eh, v1, v2)) {
2521 BLI_edgehash_insert(eh, v1, v2, NULL);
2526 numEdges = BLI_edgehash_size(eh);
2528 /* write new edges into a temporary CustomData */
2529 CustomData_reset(&edgeData);
2530 CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2531 CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2533 med = CustomData_get_layer(&edgeData, CD_MEDGE);
2534 index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2536 for (ehi = BLI_edgehashIterator_new(eh), i = 0;
2537 BLI_edgehashIterator_isDone(ehi) == FALSE;
2538 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
2540 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2541 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2543 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
2544 *index = j == 0 ? ORIGINDEX_NONE : eindex[j - 1];
2546 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2548 BLI_edgehashIterator_free(ehi);
2550 /* free old CustomData and assign new one */
2551 CustomData_free(&dm->edgeData, dm->numEdgeData);
2552 dm->edgeData = edgeData;
2553 dm->numEdgeData = numEdges;
2555 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2558 for (i = 0; i < maxFaces; i++, mp++) {
2559 ml = cddm->mloop + mp->loopstart;
2560 for (j = 0; j < mp->totloop; j++, ml++) {
2562 v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2563 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2567 BLI_edgehash_free(eh, NULL);
2570 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2572 if (numVerts < dm->numVertData)
2573 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData - numVerts);
2575 dm->numVertData = numVerts;
2578 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2580 if (numEdges < dm->numEdgeData)
2581 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData - numEdges);
2583 dm->numEdgeData = numEdges;
2586 void CDDM_lower_num_tessfaces(DerivedMesh *dm, int numTessFaces)
2588 if (numTessFaces < dm->numTessFaceData)
2589 CustomData_free_elem(&dm->faceData, numTessFaces, dm->numTessFaceData - numTessFaces);
2591 dm->numTessFaceData = numTessFaces;
2594 void CDDM_lower_num_polys(DerivedMesh *dm, int numPolys)
2596 if (numPolys < dm->numPolyData)
2597 CustomData_free_elem(&dm->polyData, numPolys, dm->numPolyData - numPolys);
2599 dm->numPolyData = numPolys;
2602 /* mesh element access functions */
2604 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2606 return &((CDDerivedMesh *)dm)->mvert[index];
2609 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2611 return &((CDDerivedMesh *)dm)->medge[index];
2614 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2616 return &((CDDerivedMesh *)dm)->mface[index];
2619 MLoop *CDDM_get_loop(DerivedMesh *dm, int index)
2621 return &((CDDerivedMesh *)dm)->mloop[index];
2624 MPoly *CDDM_get_poly(DerivedMesh *dm, int index)
2626 return &((CDDerivedMesh *)dm)->mpoly[index];
2629 /* array access functions */
2631 MVert *CDDM_get_verts(DerivedMesh *dm)
2633 return ((CDDerivedMesh *)dm)->mvert;
2636 MEdge *CDDM_get_edges(DerivedMesh *dm)
2638 return ((CDDerivedMesh *)dm)->medge;
2641 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2643 return ((CDDerivedMesh *)dm)->mface;
2646 MLoop *CDDM_get_loops(DerivedMesh *dm)
2648 return ((CDDerivedMesh *)dm)->mloop;
2651 MPoly *CDDM_get_polys(DerivedMesh *dm)
2653 return ((CDDerivedMesh *)dm)->mpoly;
2656 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2658 /* converts mfaces to mpolys/mloops */
2659 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2661 BKE_mesh_convert_mfaces_to_mpolys_ex(NULL, &cddm->dm.faceData, &cddm->dm.loopData, &cddm->dm.polyData,
2662 cddm->dm.numEdgeData, cddm->dm.numTessFaceData,
2663 cddm->dm.numLoopData, cddm->dm.numPolyData,
2664 cddm->medge, cddm->mface,
2665 &cddm->dm.numLoopData, &cddm->dm.numPolyData,
2666 &cddm->mloop, &cddm->mpoly);
2669 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2671 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2673 if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
2674 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
2676 cddm->mvert = mvert;
2679 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2681 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2683 if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
2684 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
2686 cddm->medge = medge;
2689 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2691 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2693 if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
2694 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numTessFaceData);
2696 cddm->mface = mface;
2699 void CDDM_set_mloop(DerivedMesh *dm, MLoop *mloop)
2701 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2703 if (!CustomData_has_layer(&dm->loopData, CD_MLOOP))
2704 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_ASSIGN, mloop, dm->numLoopData);
2706 cddm->mloop = mloop;
2709 void CDDM_set_mpoly(DerivedMesh *dm, MPoly *mpoly)
2711 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2713 if (!CustomData_has_layer(&dm->polyData, CD_MPOLY))
2714 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_ASSIGN, mpoly, dm->numPolyData);
2716 cddm->mpoly = mpoly;