Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/cdderivedmesh.c')
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c355
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);
}
}