From 1360bb6fb0bf0c5c14235c47bf1399accbcecc6f Mon Sep 17 00:00:00 2001 From: Tamito Kajiyama Date: Sun, 31 Mar 2013 10:33:27 +0000 Subject: Work-in-progress re-implementation of CustomData-based edge/face marks. Most changes in revision 55228 were reverted and Freestyle edge/face marks were re-implemented using CD_ORIGINDEX layers of edge/poly custom data. For this implementation to work properly, modifiers were updated so that required CD_ORIGINDEX layers will be set. As pilot cases, the Mirror and Solidify modifiers were updated (see comments in the code). Some Freestyle-specific code is necessary in DerivedMesh.c so that the CD_FREESTYLE_EDGE/FACE layers will be transferred from meshes to derived meshes. This seems unnecessary, so further investigation is foreseen. --- source/blender/blenkernel/intern/DerivedMesh.c | 30 +++++++++++++++ source/blender/blenkernel/intern/mesh.c | 10 ----- source/blender/blenkernel/intern/subsurf_ccg.c | 31 --------------- source/blender/modifiers/intern/MOD_mirror.c | 9 +++++ source/blender/modifiers/intern/MOD_solidify.c | 21 +++++++++++ .../blender/render/intern/source/convertblender.c | 44 ++++++++++++++++++---- 6 files changed, 97 insertions(+), 48 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index cc0770cd186..f53743ea06e 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1840,6 +1840,36 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } } +#ifdef WITH_FREESTYLE + /* This Freestyle-specific code still needs to get the Subdivision Surface modifier working */ + if (CustomData_has_layer(&me->edata, CD_FREESTYLE_EDGE)) { + FreestyleEdge *fed = DM_get_edge_data_layer(finaldm, CD_FREESTYLE_EDGE); + if (fed) { + FreestyleEdge *source = CustomData_get_layer(&me->edata, CD_FREESTYLE_EDGE); + int a; + for (a = 0; a < me->totedge; a++) { + fed[a].flag = source[a].flag; + } + for (; a < finaldm->numEdgeData; a++) { + fed[a].flag = 0; + } + } + } + if (CustomData_has_layer(&me->pdata, CD_FREESTYLE_FACE)) { + FreestyleFace *ffa = DM_get_poly_data_layer(finaldm, CD_FREESTYLE_FACE); + if (ffa) { + FreestyleFace *source = CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE); + int a; + for (a = 0; a < me->totpoly; a++) { + ffa[a].flag = source[a].flag; + } + for (; a < finaldm->numPolyData; a++) { + ffa[a].flag = 0; + } + } + } +#endif + #ifdef WITH_GAMEENGINE /* NavMesh - this is a hack but saves having a NavMesh modifier */ if ((ob->gameflag & OB_NAVMESH) && (finaldm->type == DM_TYPE_CDDM)) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 4c963969797..408fadde564 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -2636,16 +2636,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, } } -#ifdef WITH_FREESTYLE - if (CustomData_has_layer(pdata, CD_FREESTYLE_FACE)) { - FreestyleEdge *poly_ffa = CustomData_get_layer(pdata, CD_FREESTYLE_FACE); - FreestyleEdge *face_ffa = CustomData_add_layer(fdata, CD_FREESTYLE_FACE, CD_CALLOC, NULL, totface); - for (mface_index = 0; mface_index < totface; mface_index++) { - face_ffa[mface_index] = poly_ffa[mface_to_poly_map[mface_index]]; - } - } -#endif - mf = mface; for (mface_index = 0; mface_index < totface; mface_index++, mf++) { diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index d3ffde33f0d..025ea909e05 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -3108,10 +3108,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, MEdge *medge = NULL; /* MFace *mface = NULL; */ MPoly *mpoly = NULL; -#ifdef WITH_FREESTYLE - FreestyleEdge *fed = NULL, *ccgdm_fed = NULL; - FreestyleFace *ffa = NULL, *ccgdm_ffa = NULL; -#endif DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM, ccgSubSurf_getNumFinalVerts(ss), @@ -3286,19 +3282,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, has_edge_origindex = CustomData_has_layer(&ccgdm->dm.edgeData, CD_ORIGINDEX); -#ifdef WITH_FREESTYLE - fed = DM_get_edge_data_layer(dm, CD_FREESTYLE_EDGE); - if (fed) { - ccgdm_fed = CustomData_add_layer(&ccgdm->dm.edgeData, CD_FREESTYLE_EDGE, CD_CALLOC, NULL, - ccgSubSurf_getNumFinalEdges(ss)); - } - ffa = DM_get_poly_data_layer(dm, CD_FREESTYLE_FACE); - if (ffa) { - ccgdm_ffa = CustomData_add_layer(&ccgdm->dm.faceData, CD_FREESTYLE_FACE, CD_CALLOC, NULL, - ccgSubSurf_getNumFinalFaces(ss)); - } -#endif - loopindex = loopindex2 = 0; /* current loop index */ for (index = 0; index < totface; index++) { CCGFace *f = ccgdm->faceMap[index].face; @@ -3435,12 +3418,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, /* This is a simple one to one mapping, here... */ polyidx[faceNum] = faceNum; -#ifdef WITH_FREESTYLE - if (ffa && ffa[index].flag & FREESTYLE_FACE_MARK) { - ccgdm_ffa[faceNum].flag |= FREESTYLE_FACE_MARK; - } -#endif - faceNum++; } } @@ -3490,14 +3467,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, } } -#ifdef WITH_FREESTYLE - if (fed && fed[index].flag & FREESTYLE_EDGE_MARK) { - for (i = 0; i < numFinalEdges; ++i) { - ccgdm_fed[edgeNum + i].flag |= FREESTYLE_EDGE_MARK; - } - } -#endif - edgeNum += numFinalEdges; } diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index 2b29f2afb9a..3570b62dbdf 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -161,6 +161,15 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, dm->copyPolyArray(dm, CDDM_get_polys(result)); } +#if 1 /* WITH_FREESTYLE generic changes */ + /* if the source DM does not have edge CD_ORIGINDEX layer, then + * the corresponding layer of the result DM is filled with zeros + * (see CDDM_from_template()) */ + if (!CustomData_has_layer(&dm->edgeData, CD_ORIGINDEX)) { + range_vn_i(DM_get_edge_data_layer(result, CD_ORIGINDEX), maxEdges, 0); + } +#endif + /* copy customdata to new geometry, * copy from its self because this data may have been created in the checks above */ DM_copy_vert_data(result, result, 0, maxVerts, maxVerts); diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 9cdd52f2375..e957b4e4572 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -374,6 +374,27 @@ static DerivedMesh *applyModifier( DM_copy_poly_data(dm, result, 0, 0, numFaces); DM_copy_poly_data(dm, result, 0, numFaces, numFaces); +#if 1 /* WITH_FREESTYLE generic changes */ + /* When the input DM has no edge CD_ORIGINDEX layer (i.e., the corresponding + * layer of the result DM is filled with zeros; see CDDM_from_template()), + * set the layer to an identity mapping */ + if (!CustomData_has_layer(&dm->edgeData, CD_ORIGINDEX)) { + int *index = DM_get_edge_data_layer(result, CD_ORIGINDEX); + range_vn_i(index, numEdges, 0); + range_vn_i(index+numEdges, numEdges, 0); + } + /* Do the same for poly CD_ORIGINDEX layer */ + if (!CustomData_has_layer(&dm->polyData, CD_ORIGINDEX)) { + int *index, a; + DM_add_poly_layer(result, CD_ORIGINDEX, CD_CALLOC, NULL); + index = DM_get_poly_data_layer(result, CD_ORIGINDEX); + range_vn_i(index, numFaces, 0); + range_vn_i(index+numFaces, numFaces, 0); + for (a = 0; a < newFaces; a++) + index[numFaces*2+a] = ORIGINDEX_NONE; + } +#endif + /* if the original has it, get the result so we can update it */ face_nors_result = CustomData_get_layer(&result->polyData, CD_NORMAL); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 4cbf4309697..4369a6b02c6 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -2660,6 +2660,8 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, MFace *mface; Material *ma; #ifdef WITH_FREESTYLE + const int *index_mf_to_mpoly = NULL; + const int *index_mp_to_orig = NULL; FreestyleFace *ffa; #endif /* Curve *cu= ELEM(ob->type, OB_FONT, OB_CURVE) ? ob->data : NULL; */ @@ -2692,7 +2694,9 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, end= dm->getNumTessFaces(dm); mface= dm->getTessFaceArray(dm); #ifdef WITH_FREESTYLE - ffa= dm->getTessFaceDataArray(dm, CD_FREESTYLE_FACE); + index_mf_to_mpoly= dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + index_mp_to_orig= dm->getPolyDataArray(dm, CD_ORIGINDEX); + ffa= dm->getPolyDataArray(dm, CD_FREESTYLE_FACE); #endif for (a=0; aflag= flag; vlr->ec= 0; /* mesh edges rendered separately */ #ifdef WITH_FREESTYLE - vlr->freestyle_face_mark= (ffa && (ffa[a].flag & FREESTYLE_FACE_MARK)) ? 1 : 0; + if (ffa) { + int index = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; + vlr->freestyle_face_mark= (ffa[index].flag & FREESTYLE_FACE_MARK) ? 1 : 0; + } else { + vlr->freestyle_face_mark= 0; + } #endif if (len==0) obr->totvlak--; @@ -3240,14 +3249,26 @@ static EdgeHash *make_freestyle_edge_mark_hash(DerivedMesh *dm) FreestyleEdge *fed; MEdge *medge; int totedge, a; + int *index; medge = dm->getEdgeArray(dm); totedge = dm->getNumEdges(dm); + index = dm->getEdgeDataArray(dm, CD_ORIGINDEX); fed = dm->getEdgeDataArray(dm, CD_FREESTYLE_EDGE); if (fed) { - for (a = 0; a < totedge; a++) { - if (fed[a].flag & FREESTYLE_EDGE_MARK) - BLI_edgehash_insert(edge_hash, medge[a].v1, medge[a].v2, medge+a); + if (!index) { + for (a = 0; a < totedge; a++) { + if (fed[a].flag & FREESTYLE_EDGE_MARK) + BLI_edgehash_insert(edge_hash, medge[a].v1, medge[a].v2, medge+a); + } + } + else { + for (a = 0; a < totedge; a++) { + if (index[a] == ORIGINDEX_NONE) + continue; + if (fed[index[a]].flag & FREESTYLE_EDGE_MARK) + BLI_edgehash_insert(edge_hash, medge[a].v1, medge[a].v2, medge+a); + } } } return edge_hash; @@ -3280,6 +3301,8 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) int recalc_normals = 0; /* false by default */ int negative_scale; #ifdef WITH_FREESTYLE + const int *index_mf_to_mpoly = NULL; + const int *index_mp_to_orig = NULL; FreestyleFace *ffa; #endif @@ -3451,7 +3474,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) end= dm->getNumTessFaces(dm); mface= dm->getTessFaceArray(dm); #ifdef WITH_FREESTYLE - ffa= dm->getTessFaceDataArray(dm, CD_FREESTYLE_FACE); + index_mf_to_mpoly= dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + index_mp_to_orig= dm->getPolyDataArray(dm, CD_ORIGINDEX); + ffa= dm->getPolyDataArray(dm, CD_FREESTYLE_FACE); #endif for (a=0; afreestyle_edge_mark= edge_mark; } - vlr->freestyle_face_mark= (ffa && (ffa[a].flag & FREESTYLE_FACE_MARK)) ? 1 : 0; + if (ffa) { + int index = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; + vlr->freestyle_face_mark= (ffa[index].flag & FREESTYLE_FACE_MARK) ? 1 : 0; + } else { + vlr->freestyle_face_mark= 0; + } #endif /* render normals are inverted in render */ -- cgit v1.2.3