From 894c240f9d007271e9d587d3c1b6f961c445b1b8 Mon Sep 17 00:00:00 2001 From: Tamito Kajiyama Date: Wed, 13 Mar 2013 06:44:43 +0000 Subject: New implementation of Freestyle edge/face marks The previous implementation of Freestyle edge/face marks was refactored based on suggestions from the latest code review by Campbell. The new implementation relies on mesh CustomData to store edge/face marks, instead of introducing extra flags in the core Mesh and BMesh data structures. The CustomData-based implementation will allow further additions of new edge/face attributes because of the independence from Mesh/BMesh. This revision is work in progress, mainly intended to address the review comments and ask for further code review in view of the trunk merger in the upcoming 2.67 release. --- source/blender/blenkernel/intern/customdata.c | 15 ++-- source/blender/blenkernel/intern/subsurf_ccg.c | 38 +++++++-- source/blender/blenloader/intern/readfile.c | 58 +++++++++++++ source/blender/bmesh/bmesh_class.h | 3 - source/blender/bmesh/intern/bmesh_construct.c | 52 ++++-------- source/blender/bmesh/intern/bmesh_mesh_conv.c | 32 ++++++++ source/blender/bmesh/operators/bmo_similar.c | 26 ++++-- source/blender/editors/mesh/editmesh_select.c | 35 ++++++-- source/blender/editors/mesh/editmesh_tools.c | 56 +++++++++---- source/blender/editors/space_view3d/drawobject.c | 33 ++++++-- .../intern/blender_interface/BlenderFileLoader.cpp | 2 +- source/blender/makesdna/DNA_customdata_types.h | 8 +- source/blender/makesdna/DNA_mesh_types.h | 2 + source/blender/makesdna/DNA_meshdata_types.h | 20 ++++- source/blender/makesrna/intern/rna_mesh.c | 4 +- source/blender/python/bmesh/bmesh_py_types.c | 95 +++++++++++++++++++--- .../python/bmesh/bmesh_py_types_customdata.c | 15 ++++ .../blender/render/intern/include/render_types.h | 1 + .../blender/render/intern/source/convertblender.c | 51 +++++++----- 19 files changed, 420 insertions(+), 126 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 580a69466c9..48d7ae1de86 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1143,7 +1143,11 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { layerFree_grid_paint_mask, NULL, NULL, NULL}, /* 36: CD_SKIN_NODE */ {sizeof(MVertSkin), "MVertSkin", 1, NULL, NULL, NULL, - layerInterp_mvert_skin, NULL, layerDefault_mvert_skin} + layerInterp_mvert_skin, NULL, layerDefault_mvert_skin}, + /* 37: CD_FREESTYLE_EDGE */ + {sizeof(FreestyleEdge), "FreestyleEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL}, + /* 38: CD_FREESTYLE_FACE */ + {sizeof(FreestyleFace), "FreestyleFace", 1, NULL, NULL, NULL, NULL, NULL, NULL} }; /* note, numbers are from trunk and need updating for bmesh */ @@ -1158,7 +1162,8 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = { /* BMESH ONLY */ /* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight", /* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "CDBMElemPyPtr", "CDPaintMask", - /* 35-36 */ "CDGridPaintMask", "CDMVertSkin" + /* 35-36 */ "CDGridPaintMask", "CDMVertSkin", + /* 37-38 */ "CDFreestyleEdge", "CDFreestyleFace" }; @@ -1170,7 +1175,7 @@ const CustomDataMask CD_MASK_MESH = CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP | CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_RECAST | CD_MASK_PAINT_MASK | - CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN; + CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE; const CustomDataMask CD_MASK_EDITMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX | @@ -1183,13 +1188,13 @@ const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_PREVIEW_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY | CD_MASK_RECAST | - CD_MASK_ORIGINDEX | CD_MASK_MVERT_SKIN; + CD_MASK_ORIGINDEX | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE; const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS | CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST | CD_MASK_PAINT_MASK | - CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN; + CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE; const CustomDataMask CD_MASK_FACECORNERS = CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 0d0944d6ea7..3c90da60103 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -964,11 +964,7 @@ static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med) edgeFlag = (ccgdm->edgeFlags) ? &ccgdm->edgeFlags[i] : NULL; if (edgeFlag) -#ifdef WITH_FREESTYLE - flags |= (*edgeFlag & (ME_SEAM | ME_SHARP | ME_FREESTYLE_EDGE)) | ME_EDGEDRAW | ME_EDGERENDER; -#else flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER; -#endif else flags |= ME_EDGEDRAW | ME_EDGERENDER; @@ -1236,11 +1232,7 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) if (edgeFlags) { if (edgeIdx != -1) { -#ifdef WITH_FREESTYLE - ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP | ME_FREESTYLE_EDGE)) | ME_EDGEDRAW | ME_EDGERENDER); -#else ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER); -#endif } } else { @@ -3117,6 +3109,10 @@ 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), @@ -3291,6 +3287,18 @@ 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++) { @@ -3430,6 +3438,12 @@ 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++; } } @@ -3479,6 +3493,14 @@ 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/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b804a751b18..4bd8f82562c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9094,6 +9094,64 @@ static void do_versions(FileData *fd, Library *lib, Main *main) linestyle->rounds = 3; } } + /* The code segment below will be removed when the trunk merger is done. + For now it is kept for backward compatibility, giving branch users time + to migrate to the new CustomData-based edge/face marks. */ + { + Mesh *me; + MEdge *medge; + MPoly *mpoly; + int i, found; + + for (me = main->mesh.first; me; me = me->id.next) { + /* Freestyle edge marks */ + found = 0; + medge = me->medge; + for (i = 0; i < me->totedge; i++) { + if (medge->flag & ME_FREESTYLE_EDGE) { + found = 1; + break; + } + medge++; + } + if (found) { + FreestyleEdge *fed = CustomData_add_layer(&me->edata, CD_FREESTYLE_EDGE, CD_CALLOC, NULL, me->totedge); + medge = me->medge; + for (i = 0; i < me->totedge; i++) { + if (medge->flag & ME_FREESTYLE_EDGE) { + medge->flag &= ~ME_FREESTYLE_EDGE; + fed->flag |= FREESTYLE_EDGE_MARK; + } + medge++; + fed++; + } + printf("Migrated to CustomData-based Freestyle edge marks\n"); + } + /* Freestyle face marks */ + found = 0; + mpoly = me->mpoly; + for (i = 0; i < me->totpoly; i++) { + if (mpoly->flag & ME_FREESTYLE_FACE) { + found = 1; + break; + } + mpoly++; + } + if (found) { + FreestyleFace *ffa = CustomData_add_layer(&me->pdata, CD_FREESTYLE_FACE, CD_CALLOC, NULL, me->totpoly); + mpoly = me->mpoly; + for (i = 0; i < me->totpoly; i++) { + if (mpoly->flag & ME_FREESTYLE_FACE) { + mpoly->flag &= ~ME_FREESTYLE_FACE; + ffa->flag |= FREESTYLE_FACE_MARK; + } + mpoly++; + ffa++; + } + printf("Migrated to CustomData-based Freestyle face marks\n"); + } + } + } #endif /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 384ff341dff..6dc0218da93 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -246,9 +246,6 @@ enum { /* spare tag, assumed dirty, use define in each function to name based on use */ // _BM_ELEM_TAG_ALT = (1 << 6), // UNUSED -#ifdef WITH_FREESTYLE - BM_ELEM_FREESTYLE = (1 << 6), /* used for Freestyle faces and edges */ -#endif BM_ELEM_INTERNAL_TAG = (1 << 7) /* for low level internal API tagging, * since tools may want to tag verts and diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index fa58ccd98bc..fddb7b4bf2c 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -1002,28 +1002,18 @@ char BM_vert_flag_from_mflag(const char meflag) } char BM_edge_flag_from_mflag(const short meflag) { - return ( ((meflag & SELECT) ? BM_ELEM_SELECT : 0) | - ((meflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | - ((meflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) | - ((meflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0) | /* invert */ - ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0) | -#ifdef WITH_FREESTYLE - ((meflag & ME_FREESTYLE_EDGE) ? BM_ELEM_FREESTYLE : 0) -#else - 0 -#endif + return ( ((meflag & SELECT) ? BM_ELEM_SELECT : 0) | + ((meflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | + ((meflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) | + ((meflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0) | /* invert */ + ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0) ); } char BM_face_flag_from_mflag(const char meflag) { - return ( ((meflag & ME_FACE_SEL) ? BM_ELEM_SELECT : 0) | - ((meflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0) | - ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0) | -#ifdef WITH_FREESTYLE - ((meflag & ME_FREESTYLE_FACE) ? BM_ELEM_FREESTYLE : 0) -#else - 0 -#endif + return ( ((meflag & ME_FACE_SEL) ? BM_ELEM_SELECT : 0) | + ((meflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0) | + ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0) ); } @@ -1041,15 +1031,12 @@ short BM_edge_flag_to_mflag(BMEdge *eed) { const char hflag = eed->head.hflag; - return ( ((hflag & BM_ELEM_SELECT) ? SELECT : 0) | - ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | - ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) | - ((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) | - ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) | -#ifdef WITH_FREESTYLE - ((hflag & BM_ELEM_FREESTYLE) ? ME_FREESTYLE_EDGE : 0) | -#endif - ((BM_edge_is_wire(eed)) ? ME_LOOSEEDGE : 0) | /* not typical */ + return ( ((hflag & BM_ELEM_SELECT) ? SELECT : 0) | + ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | + ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) | + ((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) | + ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) | + ((BM_edge_is_wire(eed)) ? ME_LOOSEEDGE : 0) | /* not typical */ ME_EDGERENDER ); } @@ -1057,13 +1044,8 @@ char BM_face_flag_to_mflag(BMFace *efa) { const char hflag = efa->head.hflag; - return ( ((hflag & BM_ELEM_SELECT) ? ME_FACE_SEL : 0) | - ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0) | - ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) | -#ifdef WITH_FREESTYLE - ((hflag & BM_ELEM_FREESTYLE) ? ME_FREESTYLE_FACE : 0) -#else - 0 -#endif + return ( ((hflag & BM_ELEM_SELECT) ? ME_FACE_SEL : 0) | + ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0) | + ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) ); } diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 6697430a88d..4c0c1507dbf 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -112,6 +112,7 @@ void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag) /* CustomData_bmesh_init_pool() must run first */ BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL); BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL); + BLI_assert(bm->pdata.totlayer == 0 || bm->pdata.pool != NULL); if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) { if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { @@ -145,6 +146,29 @@ void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag) BM_data_layer_free(bm, &bm->edata, CD_CREASE); } } +#ifdef WITH_FREESTYLE + if (cd_flag & ME_CDFLAG_FREESTYLE_EDGE) { + if (!CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) { + BM_data_layer_add(bm, &bm->edata, CD_FREESTYLE_EDGE); + } + } + else { + if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) { + BM_data_layer_free(bm, &bm->edata, CD_FREESTYLE_EDGE); + } + } + + if (cd_flag & ME_CDFLAG_FREESTYLE_FACE) { + if (!CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) { + BM_data_layer_add(bm, &bm->pdata, CD_FREESTYLE_FACE); + } + } + else { + if (CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) { + BM_data_layer_free(bm, &bm->pdata, CD_FREESTYLE_FACE); + } + } +#endif } char BM_mesh_cd_flag_from_bmesh(BMesh *bm) @@ -159,6 +183,14 @@ char BM_mesh_cd_flag_from_bmesh(BMesh *bm) if (CustomData_has_layer(&bm->edata, CD_CREASE)) { cd_flag |= ME_CDFLAG_EDGE_CREASE; } +#ifdef WITH_FREESTYLE + if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) { + cd_flag |= ME_CDFLAG_FREESTYLE_EDGE; + } + if (CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) { + cd_flag |= ME_CDFLAG_FREESTYLE_FACE; + } +#endif return cd_flag; } diff --git a/source/blender/bmesh/operators/bmo_similar.c b/source/blender/bmesh/operators/bmo_similar.c index 454f9ab2ad3..5bea47969da 100644 --- a/source/blender/bmesh/operators/bmo_similar.c +++ b/source/blender/bmesh/operators/bmo_similar.c @@ -247,9 +247,16 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op) break; #ifdef WITH_FREESTYLE case SIMFACE_FREESTYLE: - if (BM_elem_flag_test(fm, BM_ELEM_FREESTYLE) == BM_elem_flag_test(fs, BM_ELEM_FREESTYLE)) { - BMO_elem_flag_enable(bm, fm, FACE_MARK); - cont = FALSE; + if (CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) { + FreestyleEdge *ffa1, *ffa2; + + ffa1 = CustomData_bmesh_get(&bm->pdata, fs->head.data, CD_FREESTYLE_FACE); + ffa2 = CustomData_bmesh_get(&bm->pdata, fm->head.data, CD_FREESTYLE_FACE); + + if (ffa1 && ffa2 && (ffa1->flag & FREESTYLE_FACE_MARK) == (ffa2->flag & FREESTYLE_FACE_MARK)) { + BMO_elem_flag_enable(bm, fm, FACE_MARK); + cont = false; + } } break; #endif @@ -473,9 +480,16 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op) break; #ifdef WITH_FREESTYLE case SIMEDGE_FREESTYLE: - if (BM_elem_flag_test(e, BM_ELEM_FREESTYLE) == BM_elem_flag_test(es, BM_ELEM_FREESTYLE)) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); - cont = FALSE; + if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) { + FreestyleEdge *fed1, *fed2; + + fed1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_FREESTYLE_EDGE); + fed2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_FREESTYLE_EDGE); + + if (fed1 && fed2 && (fed1->flag & FREESTYLE_EDGE_MARK) == (fed2->flag & FREESTYLE_EDGE_MARK)) { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + cont = false; + } } break; #endif diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 51161970c0b..1016c08e1c4 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -64,6 +64,7 @@ #include "DNA_scene_types.h" #include "DNA_object_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "mesh_intern.h" @@ -1327,17 +1328,29 @@ static void edgetag_context_set(BMesh *bm, Scene *scene, BMEdge *e, int val) case EDGE_MODE_TAG_SHARP: BM_elem_flag_set(e, BM_ELEM_SMOOTH, !val); break; -#ifdef WITH_FREESTYLE - case EDGE_MODE_TAG_FREESTYLE: - BM_elem_flag_set(e, BM_ELEM_FREESTYLE, val); - break; -#endif case EDGE_MODE_TAG_CREASE: BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (val) ? 1.0f : 0.0f); break; case EDGE_MODE_TAG_BEVEL: BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (val) ? 1.0f : 0.0f); break; +#ifdef WITH_FREESTYLE + case EDGE_MODE_TAG_FREESTYLE: + { + FreestyleEdge *fed; + + if (!CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) { + BM_data_layer_add(bm, &bm->pdata, CD_FREESTYLE_FACE); + } + + fed = CustomData_bmesh_get(&bm->edata, e->head.data, CD_FREESTYLE_EDGE); + if (!val) + fed->flag &= ~FREESTYLE_EDGE_MARK; + else + fed->flag |= FREESTYLE_EDGE_MARK; + } + break; +#endif } } @@ -1350,14 +1363,18 @@ static int edgetag_context_check(Scene *scene, BMesh *bm, BMEdge *e) return BM_elem_flag_test(e, BM_ELEM_SEAM); case EDGE_MODE_TAG_SHARP: return !BM_elem_flag_test(e, BM_ELEM_SMOOTH); -#ifdef WITH_FREESTYLE - case EDGE_MODE_TAG_FREESTYLE: - return !BM_elem_flag_test(e, BM_ELEM_FREESTYLE); -#endif case EDGE_MODE_TAG_CREASE: return BM_elem_float_data_get(&bm->edata, e, CD_CREASE) ? TRUE : FALSE; case EDGE_MODE_TAG_BEVEL: return BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) ? TRUE : FALSE; +#ifdef WITH_FREESTYLE + case EDGE_MODE_TAG_FREESTYLE: + { + FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, e->head.data, CD_FREESTYLE_EDGE); + return (!fed) ? FALSE : (fed->flag & FREESTYLE_EDGE_MARK) ? TRUE : FALSE; + } + break; +#endif } return 0; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 92e1dbf433f..c35f942cf33 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -34,6 +34,7 @@ #include "DNA_key_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -5601,33 +5602,43 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot) } #ifdef WITH_FREESTYLE + static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); - Mesh *me = ((Mesh *)obedit->data); - BMEditMesh *em = ((Mesh *)obedit->data)->edit_btmesh; + Mesh *me = (Mesh *)obedit->data; + BMEditMesh *em = BMEdit_FromObject(obedit); BMEdge *eed; BMIter iter; + FreestyleEdge *fed; int clear = RNA_boolean_get(op->ptr, "clear"); if (em == NULL) return OPERATOR_FINISHED; - /* auto-enable seams drawing */ + /* auto-enable Freestyle edge mark drawing */ if (clear == 0) { me->drawflag |= ME_DRAW_FREESTYLE_EDGE; } + if (!CustomData_has_layer(&em->bm->edata, CD_FREESTYLE_EDGE)) { + BM_data_layer_add(em->bm, &em->bm->edata, CD_FREESTYLE_EDGE); + } + if (clear) { BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) - BM_elem_flag_disable(eed, BM_ELEM_FREESTYLE); + if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + fed = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_FREESTYLE_EDGE); + fed->flag &= ~FREESTYLE_EDGE_MARK; + } } } else { BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) - BM_elem_flag_enable(eed, BM_ELEM_FREESTYLE); + if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + fed = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_FREESTYLE_EDGE); + fed->flag |= FREESTYLE_EDGE_MARK; + } } } @@ -5657,28 +5668,38 @@ void MESH_OT_mark_freestyle_edge(wmOperatorType *ot) static int edbm_mark_freestyle_face_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); - Mesh *me = ((Mesh *)obedit->data); - BMEditMesh *em = ((Mesh *)obedit->data)->edit_btmesh; + Mesh *me = (Mesh *)obedit->data; + BMEditMesh *em = BMEdit_FromObject(obedit); BMFace *efa; BMIter iter; + FreestyleFace *ffa; int clear = RNA_boolean_get(op->ptr, "clear"); if (em == NULL) return OPERATOR_FINISHED; /* auto-enable Freestyle face mark drawing */ - if(!clear) { + if (!clear) { me->drawflag |= ME_DRAW_FREESTYLE_FACE; } - if(clear) { + if (!CustomData_has_layer(&em->bm->pdata, CD_FREESTYLE_FACE)) { + BM_data_layer_add(em->bm, &em->bm->pdata, CD_FREESTYLE_FACE); + } + + if (clear) { BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) - BM_elem_flag_disable(efa, BM_ELEM_FREESTYLE); + if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + ffa = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_FREESTYLE_FACE); + ffa->flag &= ~FREESTYLE_FACE_MARK; + } } - } else { + } + else { BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) - BM_elem_flag_enable(efa, BM_ELEM_FREESTYLE); + if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + ffa = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_FREESTYLE_FACE); + ffa->flag |= FREESTYLE_FACE_MARK; + } } } @@ -5704,4 +5725,5 @@ void MESH_OT_mark_freestyle_face(wmOperatorType *ot) RNA_def_boolean(ot->srna, "clear", 0, "Clear", ""); } -#endif \ No newline at end of file + +#endif diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 32d961ab64c..158b75c494a 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2307,12 +2307,24 @@ static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm) } #ifdef WITH_FREESTYLE + +static int draw_dm_test_freestyle_edge_mark(BMEditMesh *em, BMEdge *eed) +{ + FreestyleEdge *fed = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_FREESTYLE_EDGE); + if (!fed) + return 0; + return (fed->flag & FREESTYLE_EDGE_MARK) != 0; +} + /* Draw only Freestyle feature edges */ static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index) { BMEdge *eed = EDBM_edge_at_index(userData, index); - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_FREESTYLE)) + if (!eed) + return DM_DRAW_OPTION_SKIP; + + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && draw_dm_test_freestyle_edge_mark(userData, eed)) return DM_DRAW_OPTION_NORMAL; else return DM_DRAW_OPTION_SKIP; @@ -2322,6 +2334,15 @@ static void draw_dm_edges_freestyle(BMEditMesh *em, DerivedMesh *dm) { dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em); } + +static int draw_dm_test_freestyle_face_mark(BMEditMesh *em, BMFace *efa) +{ + FreestyleFace *ffa = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_FREESTYLE_FACE); + if (!ffa) + return 0; + return (ffa->flag & FREESTYLE_FACE_MARK) != 0; +} + #endif /* Draw faces with color set based on selection @@ -2342,7 +2363,7 @@ static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index) } else { #ifdef WITH_FREESTYLE - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : BM_elem_flag_test(efa, BM_ELEM_FREESTYLE) ? 3 : 0]; + col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->em, efa) ? 3 : 0]; #else col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; #endif @@ -2377,8 +2398,8 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int return 0; #ifdef WITH_FREESTYLE - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : BM_elem_flag_test(efa, BM_ELEM_FREESTYLE) ? 3 : 0]; - next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : BM_elem_flag_test(next_efa, BM_ELEM_FREESTYLE) ? 3 : 0]; + col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->em, efa) ? 3 : 0]; + next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->em, efa) ? 3 : 0]; #else col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : 0]; @@ -2969,7 +2990,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, col1[3] = 0; #ifdef WITH_FREESTYLE - if (!(me->drawflag & ME_DRAW_FREESTYLE_FACE)) + if (!(me->drawflag & ME_DRAW_FREESTYLE_FACE) || !CustomData_has_layer(&em->bm->pdata, CD_FREESTYLE_FACE)) col4[3] = 0; draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act); @@ -3033,7 +3054,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, } #ifdef WITH_FREESTYLE - if(me->drawflag & ME_DRAW_FREESTYLE_EDGE) { + if (me->drawflag & ME_DRAW_FREESTYLE_EDGE && CustomData_has_layer(&em->bm->edata, CD_FREESTYLE_EDGE)) { UI_ThemeColor(TH_FREESTYLE_EDGE_MARK); glLineWidth(2); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 2018c7a740d..2e27eefadcb 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -521,7 +521,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) if (numTris_1 == 0 && numTris_2 == 0) continue; bool fm, em1, em2, em3, em4; - fm = (vlr->flag & ME_FREESTYLE_FACE) != 0; + fm = (vlr->freestyle_face_mark) != 0; em1 = (vlr->freestyle_edge_mark & R_EDGE_V1V2) != 0; em2 = (vlr->freestyle_edge_mark & R_EDGE_V2V3) != 0; if (!vlr->v4) { diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 4a3debe756b..8debadf24c3 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -63,7 +63,7 @@ typedef struct CustomDataExternal { * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */ typedef struct CustomData { CustomDataLayer *layers; /* CustomDataLayers, ordered by type */ - int typemap[37]; /* runtime only! - maps types to indices of first layer of that type, + int typemap[39]; /* runtime only! - maps types to indices of first layer of that type, * MUST be >= CD_NUMTYPES, but we cant use a define here. * Correct size is ensured in CustomData_update_typemap assert() */ int totlayer, maxlayer; /* number of layers, size of layers array */ @@ -114,7 +114,9 @@ typedef struct CustomData { #define CD_PAINT_MASK 34 #define CD_GRID_PAINT_MASK 35 #define CD_MVERT_SKIN 36 -#define CD_NUMTYPES 37 +#define CD_FREESTYLE_EDGE 37 +#define CD_FREESTYLE_FACE 38 +#define CD_NUMTYPES 39 /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) @@ -156,6 +158,8 @@ typedef struct CustomData { #define CD_MASK_PAINT_MASK (1LL << CD_PAINT_MASK) #define CD_MASK_GRID_PAINT_MASK (1LL << CD_GRID_PAINT_MASK) #define CD_MASK_MVERT_SKIN (1LL << CD_MVERT_SKIN) +#define CD_MASK_FREESTYLE_EDGE (1LL << CD_FREESTYLE_EDGE) +#define CD_MASK_FREESTYLE_FACE (1LL << CD_FREESTYLE_FACE) /* CustomData.flag */ diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 042a353642a..c125518ba73 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -179,6 +179,8 @@ typedef struct TFace { #define ME_CDFLAG_VERT_BWEIGHT (1 << 0) #define ME_CDFLAG_EDGE_BWEIGHT (1 << 1) #define ME_CDFLAG_EDGE_CREASE (1 << 2) +#define ME_CDFLAG_FREESTYLE_EDGE (1 << 3) +#define ME_CDFLAG_FREESTYLE_FACE (1 << 4) /* me->drawflag, short */ #define ME_DRAWEDGES (1 << 0) diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 2323c95d8ba..b849ca28d49 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -279,6 +279,22 @@ typedef struct MVertSkin { int flag; } MVertSkin; +typedef struct FreestyleEdge { + char flag; + char pad[3]; +} FreestyleEdge; + +/* FreestyleEdge->flag */ +#define FREESTYLE_EDGE_MARK 1 + +typedef struct FreestyleFace { + char flag; + char pad[3]; +} FreestyleFace; + +/* FreestyleFace->flag */ +#define FREESTYLE_FACE_MARK 1 + /* mvert->flag (1=SELECT) */ #define ME_SPHERETEST 2 #define ME_VERT_TMP_TAG 4 @@ -296,7 +312,7 @@ typedef struct MVertSkin { /* #define ME_SEAM_LAST (1<<8) */ /* UNUSED */ #define ME_SHARP (1<<9) /* only reason this flag remains a 'short' */ /* #ifdef WITH_FREESTYLE */ -#define ME_FREESTYLE_EDGE (1<<10) +#define ME_FREESTYLE_EDGE (1<<10) /* TO BE REMOVED when the trunk merger is done */ /* #endif */ /* puno = vertexnormal (mface) */ @@ -315,7 +331,7 @@ typedef struct MVertSkin { #define ME_SMOOTH 1 #define ME_FACE_SEL 2 /* #ifdef WITH_FREESTYLE */ -#define ME_FREESTYLE_FACE 4 +#define ME_FREESTYLE_FACE 4 /* TO BE REMOVED when the trunk merger is done */ /* #endif */ /* flag ME_HIDE==16 is used here too */ diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 0ab6a690b92..2fcec014a9c 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1570,7 +1570,7 @@ static void rna_def_medge(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for the EdgeSplit modifier"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); -#ifdef WITH_FREESTYLE +#ifdef WITH_FREESTYLE /* TO BE REMOVED when the trunk merger is done */ prop = RNA_def_property(srna, "use_freestyle_edge_mark", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FREESTYLE_EDGE); RNA_def_property_ui_text(prop, "Freestyle Edge Mark", "Edge mark for Freestyle feature edge detection"); @@ -1633,7 +1633,7 @@ static void rna_def_mface(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Smooth", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); -#ifdef WITH_FREESTYLE +#ifdef WITH_FREESTYLE /* TO BE REMOVED when the trunk merger is done */ prop = RNA_def_property(srna, "use_freestyle_face_mark", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FREESTYLE_FACE); RNA_def_property_ui_text(prop, "Freestyle Face Mark", "Face mark for Freestyle feature edge detection"); diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index b95db945eb1..052496e3ed7 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -84,9 +84,6 @@ PyC_FlagSet bpy_bm_hflag_all_flags[] = { {BM_ELEM_SEAM, "SEAM"}, {BM_ELEM_SMOOTH, "SMOOTH"}, {BM_ELEM_TAG, "TAG"}, -#ifdef WITH_FREESTYLE - {BM_ELEM_FREESTYLE, "FREESTYLE"}, -#endif {0, NULL} }; @@ -106,11 +103,6 @@ PyDoc_STRVAR(bpy_bm_elem_tag_doc, "Generic attribute scripts can use for own PyDoc_STRVAR(bpy_bm_elem_smooth_doc, "Smooth state of this element.\n\n:type: boolean"); PyDoc_STRVAR(bpy_bm_elem_seam_doc, "Seam for UV unwrapping.\n\n:type: boolean"); -#ifdef WITH_FREESTYLE -PyDoc_STRVAR(bpy_bm_freestyle_edge_mark_doc, "Freestyle edge mark.\n\n:type: boolean"); -PyDoc_STRVAR(bpy_bm_freestyle_face_mark_doc, "Freestyle face mark.\n\n:type: boolean"); -#endif - static PyObject *bpy_bm_elem_hflag_get(BPy_BMElem *self, void *flag) { const char hflag = (char)GET_INT_FROM_POINTER(flag); @@ -449,6 +441,47 @@ static PyObject *bpy_bmedge_is_boundary_get(BPy_BMEdge *self) return PyBool_FromLong(BM_edge_is_boundary(self->e)); } +#ifdef WITH_FREESTYLE +PyDoc_STRVAR(bpy_bmedge_freestyle_edge_mark_doc, +"Freestyle edge mark.\n\n:type: boolean" +); +static PyObject *bpy_bmedge_freestyle_edge_mark_get(BPy_BMEdge *self) +{ + FreestyleEdge *fed; + + BPY_BM_CHECK_OBJ(self); + fed = CustomData_bmesh_get(&self->bm->edata, self->e->head.data, CD_FREESTYLE_EDGE); + return PyBool_FromLong(fed->flag & FREESTYLE_EDGE_MARK); +} + +static int bpy_bmedge_freestyle_edge_mark_set(BPy_BMEdge *self, PyObject *value) +{ + int param; + FreestyleEdge *fed; + + BPY_BM_CHECK_INT(self); + + param = PyLong_AsLong(value); + if (param != false && param != true) { + PyErr_SetString(PyExc_TypeError, + "expected a boolean type 0/1"); + return -1; + } + + if (!CustomData_has_layer(&self->bm->edata, CD_FREESTYLE_EDGE)) { + BM_data_layer_add(self->bm, &self->bm->edata, CD_FREESTYLE_EDGE); + } + + fed = CustomData_bmesh_get(&self->bm->edata, self->e->head.data, CD_FREESTYLE_EDGE); + if (param) + fed->flag &= ~FREESTYLE_EDGE_MARK; + else + fed->flag |= FREESTYLE_EDGE_MARK; + + return 0; +} +#endif + /* Face * ^^^^ */ @@ -508,6 +541,48 @@ static int bpy_bmface_material_index_set(BPy_BMFace *self, PyObject *value) } } +#ifdef WITH_FREESTYLE +PyDoc_STRVAR(bpy_bmface_freestyle_face_mark_doc, +"Freestyle face mark.\n\n:type: boolean" +); +static PyObject *bpy_bmface_freestyle_face_mark_get(BPy_BMFace *self) +{ + FreestyleFace *ffa; + + BPY_BM_CHECK_OBJ(self); + ffa = CustomData_bmesh_get(&self->bm->pdata, self->f->head.data, CD_FREESTYLE_FACE); + return PyBool_FromLong(ffa->flag & FREESTYLE_FACE_MARK); +} + +static int bpy_bmface_freestyle_face_mark_set(BPy_BMFace *self, PyObject *value) +{ + int param; + FreestyleFace *ffa; + + BPY_BM_CHECK_INT(self); + + param = PyLong_AsLong(value); + if (param != false && param != true) { + PyErr_SetString(PyExc_TypeError, + "expected a boolean type 0/1"); + return -1; + } + + if (!CustomData_has_layer(&self->bm->pdata, CD_FREESTYLE_FACE)) { + BM_data_layer_add(self->bm, &self->bm->pdata, CD_FREESTYLE_FACE); + } + + ffa = CustomData_bmesh_get(&self->bm->pdata, self->f->head.data, CD_FREESTYLE_FACE); + if (param) + ffa->flag &= ~FREESTYLE_FACE_MARK; + else + ffa->flag |= FREESTYLE_FACE_MARK; + + return 0; +} +#endif + + /* Loop * ^^^^ */ @@ -689,7 +764,7 @@ static PyGetSetDef bpy_bmedge_getseters[] = { {(char *)"seam", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_seam_doc, (void *)BM_ELEM_SEAM}, #ifdef WITH_FREESTYLE - {(char *)"freestyle_edge_mark", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_freestyle_edge_mark_doc, (void *)BM_ELEM_FREESTYLE}, + {(char *)"freestyle_edge_mark", (getter)bpy_bmedge_freestyle_edge_mark_get, (setter)bpy_bmedge_freestyle_edge_mark_set, (char *)bpy_bmedge_freestyle_edge_mark_doc, NULL}, #endif /* connectivity data */ @@ -718,7 +793,7 @@ static PyGetSetDef bpy_bmface_getseters[] = { {(char *)"smooth", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_smooth_doc, (void *)BM_ELEM_SMOOTH}, #ifdef WITH_FREESTYLE - {(char *)"freestyle_face_mark", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_freestyle_face_mark_doc, (void *)BM_ELEM_FREESTYLE}, + {(char *)"freestyle_face_mark", (getter)bpy_bmface_freestyle_face_mark_get, (setter)bpy_bmface_freestyle_face_mark_set, (char *)bpy_bmface_freestyle_face_mark_doc, NULL}, #endif {(char *)"normal", (getter)bpy_bmface_normal_get, (setter)bpy_bmface_normal_set, (char *)bpy_bmface_normal_doc, NULL}, diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 4a8f8d49f35..63ad8756cec 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -112,6 +112,14 @@ PyDoc_STRVAR(bpy_bmlayeraccess_collection__uv_doc, PyDoc_STRVAR(bpy_bmlayeraccess_collection__color_doc, "Accessor for vertex color layer.\n\ntype: :class:`BMLayerCollection`" ); +#ifdef WITH_FREESTYLE +PyDoc_STRVAR(bpy_bmlayeraccess_collection__freestyle_edge_doc, +"Accessor for Freestyle edge layer.\n\ntype: :class:`BMLayerCollection`" +); +PyDoc_STRVAR(bpy_bmlayeraccess_collection__freestyle_face_doc, +"Accessor for Freestyle face layer.\n\ntype: :class:`BMLayerCollection`" +); +#endif static PyObject *bpy_bmlayeraccess_collection_get(BPy_BMLayerAccess *self, void *flag) { @@ -194,6 +202,9 @@ static PyGetSetDef bpy_bmlayeraccess_edge_getseters[] = { {(char *)"bevel_weight", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__bevel_weight_doc, (void *)CD_BWEIGHT}, {(char *)"crease", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__crease_doc, (void *)CD_CREASE}, +#ifdef WITH_FREESTYLE + {(char *)"freestyle_edge", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__freestyle_edge_doc, (void *)CD_FREESTYLE_EDGE}, +#endif {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -205,6 +216,10 @@ static PyGetSetDef bpy_bmlayeraccess_face_getseters[] = { {(char *)"tex", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__tex_doc, (void *)CD_MTEXPOLY}, +#ifdef WITH_FREESTYLE + {(char *)"freestyle_face", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__freestyle_face_doc, (void *)CD_FREESTYLE_FACE}, +#endif + {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index deba6d165f2..f3cd60d8031 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -396,6 +396,7 @@ typedef struct VlakRen { char flag, ec; #ifdef WITH_FREESTYLE char freestyle_edge_mark; + char freestyle_face_mark; #endif int index; } VlakRen; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 496edae9a38..cbc357b3d60 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -2657,6 +2657,9 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, MVert *mvert = NULL; MFace *mface; Material *ma; +#ifdef WITH_FREESTYLE + FreestyleFace *ffa; +#endif /* Curve *cu= ELEM(ob->type, OB_FONT, OB_CURVE) ? ob->data : NULL; */ mvert= dm->getVertArray(dm); @@ -2686,6 +2689,9 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, ma= give_render_material(re, ob, mat_iter+1); end= dm->getNumTessFaces(dm); mface= dm->getTessFaceArray(dm); +#ifdef WITH_FREESTYLE + ffa= dm->getTessFaceDataArray(dm, CD_FREESTYLE_FACE); +#endif for (a=0; av2; v3= mface->v3; v4= mface->v4; -#ifdef WITH_FREESTYLE - flag = mface->flag & (ME_SMOOTH | ME_FREESTYLE_FACE); -#else flag = mface->flag & ME_SMOOTH; -#endif vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->v1= RE_findOrAddVert(obr, vertofs+v1); @@ -2719,6 +2721,9 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, vlr->mat= ma; vlr->flag= flag; vlr->ec= 0; /* mesh edges rendered separately */ +#ifdef WITH_FREESTYLE + vlr->freestyle_face_mark= (ffa && (ffa[a].flag & FREESTYLE_FACE_MARK)) ? 1 : 0; +#endif if (len==0) obr->totvlak--; else { @@ -3227,14 +3232,21 @@ static void add_volume(Render *re, ObjectRen *obr, Material *ma) } #ifdef WITH_FREESTYLE -static EdgeHash *make_freestyle_edge_mark_hash(MEdge *medge, int totedge) +static EdgeHash *make_freestyle_edge_mark_hash(DerivedMesh *dm) { EdgeHash *edge_hash= BLI_edgehash_new(); - int a; - - for(a=0; agetEdgeArray(dm); + totedge = dm->getNumEdges(dm); + 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); + } } return edge_hash; } @@ -3265,6 +3277,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) int use_original_normals = FALSE; int recalc_normals = 0; /* false by default */ int negative_scale; +#ifdef WITH_FREESTYLE + FreestyleFace *ffa; +#endif me= ob->data; @@ -3392,13 +3407,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) if (!timeoffset) { #ifdef WITH_FREESTYLE EdgeHash *edge_hash; - MEdge *medge; - int totedge; /* create a hash table of Freestyle edge marks */ - medge = dm->getEdgeArray(dm); - totedge = dm->getNumEdges(dm); - edge_hash = make_freestyle_edge_mark_hash(medge, totedge); + edge_hash = make_freestyle_edge_mark_hash(dm); #endif /* store customdata names, because DerivedMesh is freed */ @@ -3437,6 +3448,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) if (ok) { end= dm->getNumTessFaces(dm); mface= dm->getTessFaceArray(dm); +#ifdef WITH_FREESTYLE + ffa= dm->getTessFaceDataArray(dm, CD_FREESTYLE_FACE); +#endif for (a=0; av2; v3= reverse_verts==0 ? mface->v3 : mface->v1; v4= mface->v4; -#ifdef WITH_FREESTYLE - flag = mface->flag & (ME_SMOOTH | ME_FREESTYLE_FACE); -#else flag = mface->flag & ME_SMOOTH; -#endif vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->v1= RE_findOrAddVert(obr, vertofs+v1); @@ -3463,7 +3473,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) else vlr->v4= 0; #ifdef WITH_FREESTYLE - /* Freestyle edge marks */ + /* Freestyle edge/face marks */ { int edge_mark = 0; @@ -3477,6 +3487,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) } vlr->freestyle_edge_mark= edge_mark; } + vlr->freestyle_face_mark= (ffa && (ffa[a].flag & FREESTYLE_FACE_MARK)) ? 1 : 0; #endif /* render normals are inverted in render */ -- cgit v1.2.3