diff options
Diffstat (limited to 'source/blender/blenkernel/intern/cdderivedmesh.c')
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 355 |
1 files changed, 253 insertions, 102 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 32a008c3d33..ba8fe83155e 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -40,7 +40,6 @@ #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_utildefines.h" -#include "BLI_scanfill.h" #include "BKE_pbvh.h" #include "BKE_cdderivedmesh.h" @@ -223,24 +222,39 @@ static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm) return cddm->pmap; } -static bool can_pbvh_draw(Object *ob, DerivedMesh *dm) +static bool check_sculpt_object_deformed(Object *object, bool for_construction) { - CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - Mesh *me = ob->data; - int deformed = 0; + bool deformed = false; - /* active modifiers means extra deformation, which can't be handled correct + /* Active modifiers means extra deformation, which can't be handled correct * on birth of PBVH and sculpt "layer" levels, so use PBVH only for internal brush - * stuff and show final DerivedMesh so user would see actual object shape */ - deformed |= ob->sculpt->modifiers_active; + * stuff and show final DerivedMesh so user would see actual object shape. + */ + deformed |= object->sculpt->modifiers_active; + + if (for_construction) { + deformed |= object->sculpt->kb != NULL; + } + else { + /* As in case with modifiers, we can't synchronize deformation made against + * PBVH and non-locked keyblock, so also use PBVH only for brushes and + * final DM to give final result to user. + */ + deformed |= object->sculpt->kb && (object->shapeflag & OB_SHAPE_LOCK) == 0; + } + + return deformed; +} - /* as in case with modifiers, we can't synchronize deformation made against - * PBVH and non-locked keyblock, so also use PBVH only for brushes and - * final DM to give final result to user */ - deformed |= ob->sculpt->kb && (ob->shapeflag & OB_SHAPE_LOCK) == 0; +static bool can_pbvh_draw(Object *ob, DerivedMesh *dm) +{ + CDDerivedMesh *cddm = (CDDerivedMesh *) dm; + Mesh *me = ob->data; + bool deformed = check_sculpt_object_deformed(ob, false); - if (deformed) - return 0; + if (deformed) { + return false; + } return cddm->mvert == me->mvert || ob->sculpt->kb; } @@ -269,7 +283,8 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) BKE_pbvh_build_bmesh(cddm->pbvh, ob->sculpt->bm, ob->sculpt->bm_smooth_shading, - ob->sculpt->bm_log); + ob->sculpt->bm_log, ob->sculpt->cd_vert_node_offset, + ob->sculpt->cd_face_node_offset); pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color); } @@ -279,21 +294,20 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) * this derivedmesh is just original mesh. it's the multires subsurf dm * that this is actually for, to support a pbvh on a modified mesh */ if (!cddm->pbvh && ob->type == OB_MESH) { - SculptSession *ss = ob->sculpt; Mesh *me = ob->data; - int deformed = 0; + bool deformed; cddm->pbvh = BKE_pbvh_new(); cddm->pbvh_draw = can_pbvh_draw(ob, dm); - pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color); - BKE_mesh_tessface_ensure(me); BKE_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert, me->totface, me->totvert, &me->vdata); - deformed = ss->modifiers_active || me->key; + pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color); + + deformed = check_sculpt_object_deformed(ob, true); if (deformed && ob->derivedDeform) { DerivedMesh *deformdm = ob->derivedDeform; @@ -421,7 +435,7 @@ static void cdDM_drawUVEdges(DerivedMesh *dm) } } -static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges) +static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MVert *mvert = cddm->mvert; @@ -531,22 +545,15 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm) static void cdDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], - int UNUSED(fast), DMSetMaterial setMaterial) + bool UNUSED(fast), DMSetMaterial setMaterial) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MVert *mvert = cddm->mvert; MFace *mface = cddm->mface; - float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); + const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1; -#define PASSVERT(index) { \ - if (shademodel == GL_SMOOTH) { \ - short *no = mvert[index].no; \ - glNormal3sv(no); \ - } \ - glVertex3fv(mvert[index].co); \ -} (void)0 - if (cddm->pbvh && cddm->pbvh_draw) { if (dm->numTessFaceData) { float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL); @@ -567,7 +574,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES; new_matnr = mface->mat_nr + 1; - new_shademodel = (mface->flag & ME_SMOOTH) ? GL_SMOOTH : GL_FLAT; + new_shademodel = (lnors || (mface->flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT; if (new_glmode != glmode || new_matnr != matnr || new_shademodel != shademodel) { glEnd(); @@ -579,7 +586,19 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, } if (drawCurrentMat) { - if (shademodel == GL_FLAT) { + if (lnors) { + glNormal3sv((const GLshort *)lnors[0][0]); + glVertex3fv(mvert[mface->v1].co); + glNormal3sv((const GLshort *)lnors[0][1]); + glVertex3fv(mvert[mface->v2].co); + glNormal3sv((const GLshort *)lnors[0][2]); + glVertex3fv(mvert[mface->v3].co); + if (mface->v4) { + glNormal3sv((const GLshort *)lnors[0][3]); + glVertex3fv(mvert[mface->v4].co); + } + } + else if (shademodel == GL_FLAT) { if (nors) { glNormal3fv(nors); } @@ -594,17 +613,31 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, } glNormal3fv(nor); } + glVertex3fv(mvert[mface->v1].co); + glVertex3fv(mvert[mface->v2].co); + glVertex3fv(mvert[mface->v3].co); + if (mface->v4) { + glVertex3fv(mvert[mface->v4].co); + } } - - PASSVERT(mface->v1); - PASSVERT(mface->v2); - PASSVERT(mface->v3); - if (mface->v4) { - PASSVERT(mface->v4); + else { /* shademodel == GL_SMOOTH */ + glNormal3sv(mvert[mface->v1].no); + glVertex3fv(mvert[mface->v1].co); + glNormal3sv(mvert[mface->v2].no); + glVertex3fv(mvert[mface->v2].co); + glNormal3sv(mvert[mface->v3].no); + glVertex3fv(mvert[mface->v3].co); + if (mface->v4) { + glNormal3sv(mvert[mface->v4].no); + glVertex3fv(mvert[mface->v4].co); + } } } - if (nors) nors += 3; + if (nors) + nors += 3; + if (lnors) + lnors++; } glEnd(); } @@ -623,7 +656,6 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, GPU_buffer_unbind(); } -#undef PASSVERT glShadeModel(GL_FLAT); } @@ -636,7 +668,8 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MVert *mv = cddm->mvert; MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE); - float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); + const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); MCol *mcol; int i, orig; @@ -722,7 +755,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol) cp = (unsigned char *) &mcol[i * 4]; - if (!(mf->flag & ME_SMOOTH)) { + if (!(lnors || (mf->flag & ME_SMOOTH))) { if (nors) { glNormal3fv(nors); } @@ -742,32 +775,39 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, if (tf) glTexCoord2fv(tf[i].uv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); mvert = &mv[mf->v1]; - if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); + if (lnors) glNormal3sv((const GLshort *)lnors[0][0]); + else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); glVertex3fv(mvert->co); - + if (tf) glTexCoord2fv(tf[i].uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); mvert = &mv[mf->v2]; - if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); + if (lnors) glNormal3sv((const GLshort *)lnors[0][1]); + else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); glVertex3fv(mvert->co); if (tf) glTexCoord2fv(tf[i].uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); mvert = &mv[mf->v3]; - if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); + if (lnors) glNormal3sv((const GLshort *)lnors[0][2]); + else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); glVertex3fv(mvert->co); if (mf->v4) { if (tf) glTexCoord2fv(tf[i].uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); mvert = &mv[mf->v4]; - if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); + if (lnors) glNormal3sv((const GLshort *)lnors[0][3]); + else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); glVertex3fv(mvert->co); } glEnd(); } - if (nors) nors += 3; + if (nors) + nors += 3; + if (lnors) + lnors++; } } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ @@ -864,7 +904,8 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, MVert *mv = cddm->mvert; MFace *mf = cddm->mface; MCol *mcol; - float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL); + const float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int colType, useColors = flag & DM_DRAW_USE_COLORS; int i, orig; @@ -895,7 +936,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) { DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n"); for (i = 0; i < dm->numTessFaceData; i++, mf++) { - int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH); + int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mf->flag & ME_SMOOTH); DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i; @@ -921,7 +962,23 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, glShadeModel(GL_SMOOTH); glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES); - if (!drawSmooth) { + if (lnors) { + if (cp) glColor3ub(cp[3], cp[2], cp[1]); + glNormal3sv((const GLshort *)lnors[0][0]); + glVertex3fv(mv[mf->v1].co); + if (cp) glColor3ub(cp[7], cp[6], cp[5]); + glNormal3sv((const GLshort *)lnors[0][1]); + glVertex3fv(mv[mf->v2].co); + if (cp) glColor3ub(cp[11], cp[10], cp[9]); + glNormal3sv((const GLshort *)lnors[0][2]); + glVertex3fv(mv[mf->v3].co); + if (mf->v4) { + if (cp) glColor3ub(cp[15], cp[14], cp[13]); + glNormal3sv((const GLshort *)lnors[0][3]); + glVertex3fv(mv[mf->v4].co); + } + } + else if (!drawSmooth) { if (nors) { glNormal3fv(nors); } @@ -970,7 +1027,10 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, glDisable(GL_POLYGON_STIPPLE); } - if (nors) nors += 3; + if (nors) + nors += 3; + if (lnors) + lnors++; } } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ @@ -1062,7 +1122,8 @@ static void cdDM_drawMappedFacesTex(DerivedMesh *dm, cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData); } -static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal) +static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, + short (*lnor)[3], int smoothnormal) { const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; int b; @@ -1119,9 +1180,13 @@ static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int } /* vertex normal */ - if (smoothnormal) + if (lnor) { + glNormal3sv((const GLshort *)lnor); + } + else if (smoothnormal) { glNormal3sv(mvert[index].no); - + } + /* vertex coordinate */ glVertex3fv(mvert[index].co); } @@ -1138,6 +1203,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, MFace *mface = cddm->mface; /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int a, b, matnr, new_matnr; bool do_draw; int orig; @@ -1176,7 +1242,8 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, glBegin(GL_QUADS); for (a = 0; a < dm->numTessFaceData; a++, mface++) { - const int smoothnormal = (mface->flag & ME_SMOOTH); + const int smoothnormal = lnors || (mface->flag & ME_SMOOTH); + short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL; new_matnr = mface->mat_nr + 1; if (new_matnr != matnr) { @@ -1222,20 +1289,28 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, } } - cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal); + if (lnors) { + ln1 = &lnors[0][0]; + ln2 = &lnors[0][1]; + ln3 = &lnors[0][2]; + ln4 = &lnors[0][3]; + lnors++; + } + + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, ln1, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, ln2, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal); if (mface->v4) - cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, ln4, smoothnormal); else - cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal); } glEnd(); } else { GPUBuffer *buffer = NULL; - char *varray = NULL; + const char *varray = NULL; int numdata = 0, elementsize = 0, offset; int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0; int i; @@ -1373,7 +1448,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, } } if (attribs.tottang && attribs.tang.array) { - float *tang = attribs.tang.array[a * 4 + 0]; + const float *tang = attribs.tang.array[a * 4 + 0]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); tang = attribs.tang.array[a * 4 + 1]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); @@ -1418,7 +1493,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, } } if (attribs.tottang && attribs.tang.array) { - float *tang = attribs.tang.array[a * 4 + 2]; + const float *tang = attribs.tang.array[a * 4 + 2]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); tang = attribs.tang.array[a * 4 + 3]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); @@ -1456,7 +1531,7 @@ static void cdDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial) } static void cdDM_drawMappedFacesMat(DerivedMesh *dm, - void (*setMaterial)(void *userData, int, void *attribs), + void (*setMaterial)(void *userData, int matnr, void *attribs), bool (*setFace)(void *userData, int index), void *userData) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; @@ -1465,6 +1540,7 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, MVert *mvert = cddm->mvert; MFace *mf = cddm->mface; float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL); + short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int a, matnr, new_matnr; int orig; @@ -1499,7 +1575,8 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, glBegin(GL_QUADS); for (a = 0; a < dm->numTessFaceData; a++, mf++) { - const int smoothnormal = (mf->flag & ME_SMOOTH); + const int smoothnormal = lnors || (mf->flag & ME_SMOOTH); + short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL; /* material */ new_matnr = mf->mat_nr + 1; @@ -1539,15 +1616,23 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, } } + if (lnors) { + ln1 = &lnors[0][0]; + ln2 = &lnors[0][1]; + ln3 = &lnors[0][2]; + ln4 = &lnors[0][3]; + lnors++; + } + /* vertices */ - cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal); - cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, ln1, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, ln2, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, ln3, smoothnormal); if (mf->v4) - cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, ln4, smoothnormal); else - cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, ln3, smoothnormal); } glEnd(); @@ -1585,7 +1670,7 @@ static void cdDM_foreachMappedVert( DMForeachFlag flag) { MVert *mv = CDDM_get_verts(dm); - int *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX); + const int *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX); int i; if (index) { @@ -1625,6 +1710,35 @@ static void cdDM_foreachMappedEdge( } } +static void cdDM_foreachMappedLoop( + DerivedMesh *dm, + void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]), + void *userData, + DMForeachFlag flag) +{ + /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would + * return loop data from bmesh itself. */ + const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL; + + const MVert *mv = CDDM_get_verts(dm); + const MLoop *ml = CDDM_get_loops(dm); + const MPoly *mp = CDDM_get_polys(dm); + const int *v_index = DM_get_vert_data_layer(dm, CD_ORIGINDEX); + const int *f_index = DM_get_poly_data_layer(dm, CD_ORIGINDEX); + int p_idx, i; + + for (p_idx = 0; p_idx < dm->numPolyData; ++p_idx, ++mp) { + for (i = 0; i < mp->totloop; ++i, ++ml) { + const int v_idx = v_index ? v_index[ml->v] : ml->v; + const int f_idx = f_index ? f_index[p_idx] : p_idx; + const float *no = lnors ? *lnors++ : NULL; + if (!ELEM(ORIGINDEX_NONE, v_idx, f_idx)) { + func(userData, v_idx, f_idx, mv[ml->v].co, no); + } + } + } +} + static void cdDM_foreachMappedFaceCenter( DerivedMesh *dm, void (*func)(void *userData, int index, const float cent[3], const float no[3]), @@ -1738,6 +1852,7 @@ static CDDerivedMesh *cdDM_create(const char *desc) dm->getTessFaceDataArray = DM_get_tessface_data_layer; dm->calcNormals = CDDM_calc_normals; + dm->calcLoopNormals = CDDM_calc_loop_normals; dm->recalcTessellation = CDDM_recalc_tessellation; dm->getVertCos = cdDM_getVertCos; @@ -1764,6 +1879,7 @@ static CDDerivedMesh *cdDM_create(const char *desc) dm->foreachMappedVert = cdDM_foreachMappedVert; dm->foreachMappedEdge = cdDM_foreachMappedEdge; + dm->foreachMappedLoop = cdDM_foreachMappedLoop; dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter; dm->release = cdDM_release; @@ -2096,6 +2212,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, const bool use_mdisps, mloop->e = BM_elem_index_get(l_iter->e); CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l_iter->head.data, j); + BM_elem_index_set(l_iter, j); /* set_inline */ + j++; mloop++; } while ((l_iter = l_iter->next) != l_first); @@ -2104,7 +2222,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, const bool use_mdisps, if (add_orig) *index++ = i; } - bm->elem_index_dirty &= ~BM_FACE; + bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); @@ -2289,8 +2407,7 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const bool only_face_normals) CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData); } - - face_nors = MEM_mallocN(sizeof(float) * 3 * dm->numTessFaceData, "face_nors"); + face_nors = MEM_mallocN(sizeof(*face_nors) * dm->numTessFaceData, "face_nors"); /* calculate face normals */ BKE_mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), @@ -2298,8 +2415,7 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const bool only_face_normals) CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors, only_face_normals); - CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, - face_nors, dm->numTessFaceData); + CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, face_nors, dm->numTessFaceData); cddm->dm.dirty &= ~DM_DIRTY_NORMALS; } @@ -2353,6 +2469,48 @@ void CDDM_calc_normals(DerivedMesh *dm) #endif +void CDDM_calc_loop_normals(DerivedMesh *dm, const float split_angle) +{ + MVert *mverts = dm->getVertArray(dm); + MEdge *medges = dm->getEdgeArray(dm); + MLoop *mloops = dm->getLoopArray(dm); + MPoly *mpolys = dm->getPolyArray(dm); + + CustomData *ldata, *pdata; + + float (*lnors)[3]; + float (*pnors)[3]; + + const int numVerts = dm->getNumVerts(dm); + const int numEdges = dm->getNumEdges(dm); + const int numLoops = dm->getNumLoops(dm); + const int numPolys = dm->getNumPolys(dm); + + ldata = dm->getLoopDataLayout(dm); + if (CustomData_has_layer(ldata, CD_NORMAL)) { + lnors = CustomData_get_layer(ldata, CD_NORMAL); + } + else { + lnors = CustomData_add_layer(ldata, CD_NORMAL, CD_CALLOC, NULL, numLoops); + } + + /* Compute poly (always needed) and vert normals. */ + /* Note we can't use DM_ensure_normals, since it won't keep computed poly nors... */ + pdata = dm->getPolyDataLayout(dm); + pnors = CustomData_get_layer(pdata, CD_NORMAL); + if (!pnors) { + pnors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, numPolys); + } + BKE_mesh_calc_normals_poly(mverts, numVerts, mloops, mpolys, numLoops, numPolys, pnors, + (dm->dirty & DM_DIRTY_NORMALS) ? false : true); + + dm->dirty &= ~DM_DIRTY_NORMALS; + + BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops, lnors, numLoops, + mpolys, pnors, numPolys, split_angle); +} + + void CDDM_calc_normals_tessface(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh *)dm; @@ -2633,33 +2791,28 @@ void CDDM_calc_edges_tessface(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh *)dm; CustomData edgeData; - EdgeHashIterator *ehi; + EdgeSetIterator *ehi; MFace *mf = cddm->mface; MEdge *med; - EdgeHash *eh; + EdgeSet *eh; int i, *index, numEdges, numFaces = dm->numTessFaceData; - eh = BLI_edgehash_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(numFaces)); + eh = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(numFaces)); for (i = 0; i < numFaces; i++, mf++) { - if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2)) - BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL); - if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3)) - BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL); + BLI_edgeset_reinsert(eh, mf->v1, mf->v2); + BLI_edgeset_reinsert(eh, mf->v2, mf->v3); if (mf->v4) { - if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4)) - BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL); - if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1)) - BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL); + BLI_edgeset_reinsert(eh, mf->v3, mf->v4); + BLI_edgeset_reinsert(eh, mf->v4, mf->v1); } else { - if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1)) - BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL); + BLI_edgeset_reinsert(eh, mf->v3, mf->v1); } } - numEdges = BLI_edgehash_size(eh); + numEdges = BLI_edgeset_size(eh); /* write new edges into a temporary CustomData */ CustomData_reset(&edgeData); @@ -2669,16 +2822,16 @@ void CDDM_calc_edges_tessface(DerivedMesh *dm) med = CustomData_get_layer(&edgeData, CD_MEDGE); index = CustomData_get_layer(&edgeData, CD_ORIGINDEX); - for (ehi = BLI_edgehashIterator_new(eh), i = 0; - BLI_edgehashIterator_isDone(ehi) == false; - BLI_edgehashIterator_step(ehi), i++, med++, index++) + for (ehi = BLI_edgesetIterator_new(eh), i = 0; + BLI_edgesetIterator_isDone(ehi) == false; + BLI_edgesetIterator_step(ehi), i++, med++, index++) { - BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2); + BLI_edgesetIterator_getKey(ehi, &med->v1, &med->v2); med->flag = ME_EDGEDRAW | ME_EDGERENDER; *index = ORIGINDEX_NONE; } - BLI_edgehashIterator_free(ehi); + BLI_edgesetIterator_free(ehi); /* free old CustomData and assign new one */ CustomData_free(&dm->edgeData, dm->numEdgeData); @@ -2687,7 +2840,7 @@ void CDDM_calc_edges_tessface(DerivedMesh *dm) cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); - BLI_edgehash_free(eh, NULL); + BLI_edgeset_free(eh); } /* warning, this uses existing edges but CDDM_calc_edges_tessface() doesn't */ @@ -2702,7 +2855,7 @@ void CDDM_calc_edges(DerivedMesh *dm) EdgeHash *eh; unsigned int eh_reserve; int v1, v2; - int *eindex; + const int *eindex; int i, j, *index; const int numFaces = dm->numPolyData; const int numLoops = dm->numLoopData; @@ -2724,9 +2877,7 @@ void CDDM_calc_edges(DerivedMesh *dm) for (j = 0; j < mp->totloop; j++, ml++) { v1 = ml->v; v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v; - if (!BLI_edgehash_haskey(eh, v1, v2)) { - BLI_edgehash_insert(eh, v1, v2, NULL); - } + BLI_edgehash_reinsert(eh, v1, v2, NULL); } } |