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.
This commit is contained in:
Tamito Kajiyama 2013-03-13 06:44:43 +00:00
parent 2d801f2bec
commit 894c240f9d
19 changed files with 419 additions and 125 deletions

View File

@ -1143,7 +1143,11 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
layerFree_grid_paint_mask, NULL, NULL, NULL}, layerFree_grid_paint_mask, NULL, NULL, NULL},
/* 36: CD_SKIN_NODE */ /* 36: CD_SKIN_NODE */
{sizeof(MVertSkin), "MVertSkin", 1, NULL, NULL, NULL, {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 */ /* note, numbers are from trunk and need updating for bmesh */
@ -1158,7 +1162,8 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
/* BMESH ONLY */ /* BMESH ONLY */
/* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight", /* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
/* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "CDBMElemPyPtr", "CDPaintMask", /* 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_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_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_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 = const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV | CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX | 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_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_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_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 = const CustomDataMask CD_MASK_BMESH =
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | 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_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_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_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 = const CustomDataMask CD_MASK_FACECORNERS =
CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
CD_MASK_MLOOPCOL; CD_MASK_MLOOPCOL;

View File

@ -964,11 +964,7 @@ static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
edgeFlag = (ccgdm->edgeFlags) ? &ccgdm->edgeFlags[i] : NULL; edgeFlag = (ccgdm->edgeFlags) ? &ccgdm->edgeFlags[i] : NULL;
if (edgeFlag) 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; flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER;
#endif
else else
flags |= ME_EDGEDRAW | ME_EDGERENDER; flags |= ME_EDGEDRAW | ME_EDGERENDER;
@ -1236,11 +1232,7 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
if (edgeFlags) { if (edgeFlags) {
if (edgeIdx != -1) { 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); ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
#endif
} }
} }
else { else {
@ -3117,6 +3109,10 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
MEdge *medge = NULL; MEdge *medge = NULL;
/* MFace *mface = NULL; */ /* MFace *mface = NULL; */
MPoly *mpoly = 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, DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
ccgSubSurf_getNumFinalVerts(ss), ccgSubSurf_getNumFinalVerts(ss),
@ -3291,6 +3287,18 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
has_edge_origindex = CustomData_has_layer(&ccgdm->dm.edgeData, CD_ORIGINDEX); 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 */ loopindex = loopindex2 = 0; /* current loop index */
for (index = 0; index < totface; 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... */ /* This is a simple one to one mapping, here... */
polyidx[faceNum] = faceNum; polyidx[faceNum] = faceNum;
#ifdef WITH_FREESTYLE
if (ffa && ffa[index].flag & FREESTYLE_FACE_MARK) {
ccgdm_ffa[faceNum].flag |= FREESTYLE_FACE_MARK;
}
#endif
faceNum++; 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; edgeNum += numFinalEdges;
} }

View File

@ -9094,6 +9094,64 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
linestyle->rounds = 3; 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 #endif
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT!!!: pointers from libdata have not been converted yet here! */

View File

@ -246,9 +246,6 @@ enum {
/* spare tag, assumed dirty, use define in each function to name based on use */ /* spare tag, assumed dirty, use define in each function to name based on use */
// _BM_ELEM_TAG_ALT = (1 << 6), // UNUSED // _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, BM_ELEM_INTERNAL_TAG = (1 << 7) /* for low level internal API tagging,
* since tools may want to tag verts and * since tools may want to tag verts and

View File

@ -1002,28 +1002,18 @@ char BM_vert_flag_from_mflag(const char meflag)
} }
char BM_edge_flag_from_mflag(const short meflag) char BM_edge_flag_from_mflag(const short meflag)
{ {
return ( ((meflag & SELECT) ? BM_ELEM_SELECT : 0) | return ( ((meflag & SELECT) ? BM_ELEM_SELECT : 0) |
((meflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | ((meflag & ME_SEAM) ? BM_ELEM_SEAM : 0) |
((meflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) | ((meflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) |
((meflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0) | /* invert */ ((meflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0) | /* invert */
((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0) | ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0)
#ifdef WITH_FREESTYLE
((meflag & ME_FREESTYLE_EDGE) ? BM_ELEM_FREESTYLE : 0)
#else
0
#endif
); );
} }
char BM_face_flag_from_mflag(const char meflag) char BM_face_flag_from_mflag(const char meflag)
{ {
return ( ((meflag & ME_FACE_SEL) ? BM_ELEM_SELECT : 0) | return ( ((meflag & ME_FACE_SEL) ? BM_ELEM_SELECT : 0) |
((meflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0) | ((meflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0) |
((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0) | ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0)
#ifdef WITH_FREESTYLE
((meflag & ME_FREESTYLE_FACE) ? BM_ELEM_FREESTYLE : 0)
#else
0
#endif
); );
} }
@ -1041,15 +1031,12 @@ short BM_edge_flag_to_mflag(BMEdge *eed)
{ {
const char hflag = eed->head.hflag; const char hflag = eed->head.hflag;
return ( ((hflag & BM_ELEM_SELECT) ? SELECT : 0) | return ( ((hflag & BM_ELEM_SELECT) ? SELECT : 0) |
((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) |
((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) | ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) |
((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) | ((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) |
((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) | ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) |
#ifdef WITH_FREESTYLE ((BM_edge_is_wire(eed)) ? ME_LOOSEEDGE : 0) | /* not typical */
((hflag & BM_ELEM_FREESTYLE) ? ME_FREESTYLE_EDGE : 0) |
#endif
((BM_edge_is_wire(eed)) ? ME_LOOSEEDGE : 0) | /* not typical */
ME_EDGERENDER ME_EDGERENDER
); );
} }
@ -1057,13 +1044,8 @@ char BM_face_flag_to_mflag(BMFace *efa)
{ {
const char hflag = efa->head.hflag; const char hflag = efa->head.hflag;
return ( ((hflag & BM_ELEM_SELECT) ? ME_FACE_SEL : 0) | return ( ((hflag & BM_ELEM_SELECT) ? ME_FACE_SEL : 0) |
((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0) | ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0) |
((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) | ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0)
#ifdef WITH_FREESTYLE
((hflag & BM_ELEM_FREESTYLE) ? ME_FREESTYLE_FACE : 0)
#else
0
#endif
); );
} }

View File

@ -112,6 +112,7 @@ void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
/* CustomData_bmesh_init_pool() must run first */ /* CustomData_bmesh_init_pool() must run first */
BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL); BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL);
BLI_assert(bm->edata.totlayer == 0 || bm->edata.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 (cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
if (!CustomData_has_layer(&bm->vdata, CD_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); 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) 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)) { if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
cd_flag |= ME_CDFLAG_EDGE_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; return cd_flag;
} }

View File

@ -247,9 +247,16 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
break; break;
#ifdef WITH_FREESTYLE #ifdef WITH_FREESTYLE
case SIMFACE_FREESTYLE: case SIMFACE_FREESTYLE:
if (BM_elem_flag_test(fm, BM_ELEM_FREESTYLE) == BM_elem_flag_test(fs, BM_ELEM_FREESTYLE)) { if (CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) {
BMO_elem_flag_enable(bm, fm, FACE_MARK); FreestyleEdge *ffa1, *ffa2;
cont = FALSE;
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; break;
#endif #endif
@ -473,9 +480,16 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
break; break;
#ifdef WITH_FREESTYLE #ifdef WITH_FREESTYLE
case SIMEDGE_FREESTYLE: case SIMEDGE_FREESTYLE:
if (BM_elem_flag_test(e, BM_ELEM_FREESTYLE) == BM_elem_flag_test(es, BM_ELEM_FREESTYLE)) { if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) {
BMO_elem_flag_enable(bm, e, EDGE_MARK); FreestyleEdge *fed1, *fed2;
cont = FALSE;
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; break;
#endif #endif

View File

@ -64,6 +64,7 @@
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "mesh_intern.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: case EDGE_MODE_TAG_SHARP:
BM_elem_flag_set(e, BM_ELEM_SMOOTH, !val); BM_elem_flag_set(e, BM_ELEM_SMOOTH, !val);
break; 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: case EDGE_MODE_TAG_CREASE:
BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (val) ? 1.0f : 0.0f); BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (val) ? 1.0f : 0.0f);
break; break;
case EDGE_MODE_TAG_BEVEL: case EDGE_MODE_TAG_BEVEL:
BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (val) ? 1.0f : 0.0f); BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (val) ? 1.0f : 0.0f);
break; 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); return BM_elem_flag_test(e, BM_ELEM_SEAM);
case EDGE_MODE_TAG_SHARP: case EDGE_MODE_TAG_SHARP:
return !BM_elem_flag_test(e, BM_ELEM_SMOOTH); 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: case EDGE_MODE_TAG_CREASE:
return BM_elem_float_data_get(&bm->edata, e, CD_CREASE) ? TRUE : FALSE; return BM_elem_float_data_get(&bm->edata, e, CD_CREASE) ? TRUE : FALSE;
case EDGE_MODE_TAG_BEVEL: case EDGE_MODE_TAG_BEVEL:
return BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) ? TRUE : FALSE; 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; return 0;
} }

View File

@ -34,6 +34,7 @@
#include "DNA_key_types.h" #include "DNA_key_types.h"
#include "DNA_material_types.h" #include "DNA_material_types.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h" #include "DNA_modifier_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
@ -5601,33 +5602,43 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot)
} }
#ifdef WITH_FREESTYLE #ifdef WITH_FREESTYLE
static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op) static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op)
{ {
Object *obedit = CTX_data_edit_object(C); Object *obedit = CTX_data_edit_object(C);
Mesh *me = ((Mesh *)obedit->data); Mesh *me = (Mesh *)obedit->data;
BMEditMesh *em = ((Mesh *)obedit->data)->edit_btmesh; BMEditMesh *em = BMEdit_FromObject(obedit);
BMEdge *eed; BMEdge *eed;
BMIter iter; BMIter iter;
FreestyleEdge *fed;
int clear = RNA_boolean_get(op->ptr, "clear"); int clear = RNA_boolean_get(op->ptr, "clear");
if (em == NULL) if (em == NULL)
return OPERATOR_FINISHED; return OPERATOR_FINISHED;
/* auto-enable seams drawing */ /* auto-enable Freestyle edge mark drawing */
if (clear == 0) { if (clear == 0) {
me->drawflag |= ME_DRAW_FREESTYLE_EDGE; 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) { if (clear) {
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { 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)) 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); fed = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_FREESTYLE_EDGE);
fed->flag &= ~FREESTYLE_EDGE_MARK;
}
} }
} }
else { else {
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { 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)) 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); 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) static int edbm_mark_freestyle_face_exec(bContext *C, wmOperator *op)
{ {
Object *obedit = CTX_data_edit_object(C); Object *obedit = CTX_data_edit_object(C);
Mesh *me = ((Mesh *)obedit->data); Mesh *me = (Mesh *)obedit->data;
BMEditMesh *em = ((Mesh *)obedit->data)->edit_btmesh; BMEditMesh *em = BMEdit_FromObject(obedit);
BMFace *efa; BMFace *efa;
BMIter iter; BMIter iter;
FreestyleFace *ffa;
int clear = RNA_boolean_get(op->ptr, "clear"); int clear = RNA_boolean_get(op->ptr, "clear");
if (em == NULL) return OPERATOR_FINISHED; if (em == NULL) return OPERATOR_FINISHED;
/* auto-enable Freestyle face mark drawing */ /* auto-enable Freestyle face mark drawing */
if(!clear) { if (!clear) {
me->drawflag |= ME_DRAW_FREESTYLE_FACE; 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) { 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)) 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); 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) { 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)) 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); 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", ""); RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
} }
#endif
#endif

View File

@ -2307,12 +2307,24 @@ static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm)
} }
#ifdef WITH_FREESTYLE #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 */ /* Draw only Freestyle feature edges */
static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index) static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index)
{ {
BMEdge *eed = EDBM_edge_at_index(userData, 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; return DM_DRAW_OPTION_NORMAL;
else else
return DM_DRAW_OPTION_SKIP; 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); 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 #endif
/* Draw faces with color set based on selection /* Draw faces with color set based on selection
@ -2342,7 +2363,7 @@ static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index)
} }
else { else {
#ifdef WITH_FREESTYLE #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 #else
col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0];
#endif #endif
@ -2377,8 +2398,8 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int
return 0; return 0;
#ifdef WITH_FREESTYLE #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];
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]; 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 #else
col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; 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]; 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; col1[3] = 0;
#ifdef WITH_FREESTYLE #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; col4[3] = 0;
draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act); 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 #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); UI_ThemeColor(TH_FREESTYLE_EDGE_MARK);
glLineWidth(2); glLineWidth(2);

View File

@ -521,7 +521,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
if (numTris_1 == 0 && numTris_2 == 0) if (numTris_1 == 0 && numTris_2 == 0)
continue; continue;
bool fm, em1, em2, em3, em4; 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; em1 = (vlr->freestyle_edge_mark & R_EDGE_V1V2) != 0;
em2 = (vlr->freestyle_edge_mark & R_EDGE_V2V3) != 0; em2 = (vlr->freestyle_edge_mark & R_EDGE_V2V3) != 0;
if (!vlr->v4) { if (!vlr->v4) {

View File

@ -63,7 +63,7 @@ typedef struct CustomDataExternal {
* layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */ * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */
typedef struct CustomData { typedef struct CustomData {
CustomDataLayer *layers; /* CustomDataLayers, ordered by type */ 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. * MUST be >= CD_NUMTYPES, but we cant use a define here.
* Correct size is ensured in CustomData_update_typemap assert() */ * Correct size is ensured in CustomData_update_typemap assert() */
int totlayer, maxlayer; /* number of layers, size of layers array */ int totlayer, maxlayer; /* number of layers, size of layers array */
@ -114,7 +114,9 @@ typedef struct CustomData {
#define CD_PAINT_MASK 34 #define CD_PAINT_MASK 34
#define CD_GRID_PAINT_MASK 35 #define CD_GRID_PAINT_MASK 35
#define CD_MVERT_SKIN 36 #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 */ /* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT) #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_PAINT_MASK (1LL << CD_PAINT_MASK)
#define CD_MASK_GRID_PAINT_MASK (1LL << CD_GRID_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_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 */ /* CustomData.flag */

View File

@ -179,6 +179,8 @@ typedef struct TFace {
#define ME_CDFLAG_VERT_BWEIGHT (1 << 0) #define ME_CDFLAG_VERT_BWEIGHT (1 << 0)
#define ME_CDFLAG_EDGE_BWEIGHT (1 << 1) #define ME_CDFLAG_EDGE_BWEIGHT (1 << 1)
#define ME_CDFLAG_EDGE_CREASE (1 << 2) #define ME_CDFLAG_EDGE_CREASE (1 << 2)
#define ME_CDFLAG_FREESTYLE_EDGE (1 << 3)
#define ME_CDFLAG_FREESTYLE_FACE (1 << 4)
/* me->drawflag, short */ /* me->drawflag, short */
#define ME_DRAWEDGES (1 << 0) #define ME_DRAWEDGES (1 << 0)

View File

@ -279,6 +279,22 @@ typedef struct MVertSkin {
int flag; int flag;
} MVertSkin; } 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) */ /* mvert->flag (1=SELECT) */
#define ME_SPHERETEST 2 #define ME_SPHERETEST 2
#define ME_VERT_TMP_TAG 4 #define ME_VERT_TMP_TAG 4
@ -296,7 +312,7 @@ typedef struct MVertSkin {
/* #define ME_SEAM_LAST (1<<8) */ /* UNUSED */ /* #define ME_SEAM_LAST (1<<8) */ /* UNUSED */
#define ME_SHARP (1<<9) /* only reason this flag remains a 'short' */ #define ME_SHARP (1<<9) /* only reason this flag remains a 'short' */
/* #ifdef WITH_FREESTYLE */ /* #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 */ /* #endif */
/* puno = vertexnormal (mface) */ /* puno = vertexnormal (mface) */
@ -315,7 +331,7 @@ typedef struct MVertSkin {
#define ME_SMOOTH 1 #define ME_SMOOTH 1
#define ME_FACE_SEL 2 #define ME_FACE_SEL 2
/* #ifdef WITH_FREESTYLE */ /* #ifdef WITH_FREESTYLE */
#define ME_FREESTYLE_FACE 4 #define ME_FREESTYLE_FACE 4 /* TO BE REMOVED when the trunk merger is done */
/* #endif */ /* #endif */
/* flag ME_HIDE==16 is used here too */ /* flag ME_HIDE==16 is used here too */

View File

@ -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_ui_text(prop, "Sharp", "Sharp edge for the EdgeSplit modifier");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); 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); 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_boolean_sdna(prop, NULL, "flag", ME_FREESTYLE_EDGE);
RNA_def_property_ui_text(prop, "Freestyle Edge Mark", "Edge mark for Freestyle feature edge detection"); 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_ui_text(prop, "Smooth", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); 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); 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_boolean_sdna(prop, NULL, "flag", ME_FREESTYLE_FACE);
RNA_def_property_ui_text(prop, "Freestyle Face Mark", "Face mark for Freestyle feature edge detection"); RNA_def_property_ui_text(prop, "Freestyle Face Mark", "Face mark for Freestyle feature edge detection");

View File

@ -84,9 +84,6 @@ PyC_FlagSet bpy_bm_hflag_all_flags[] = {
{BM_ELEM_SEAM, "SEAM"}, {BM_ELEM_SEAM, "SEAM"},
{BM_ELEM_SMOOTH, "SMOOTH"}, {BM_ELEM_SMOOTH, "SMOOTH"},
{BM_ELEM_TAG, "TAG"}, {BM_ELEM_TAG, "TAG"},
#ifdef WITH_FREESTYLE
{BM_ELEM_FREESTYLE, "FREESTYLE"},
#endif
{0, NULL} {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_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"); 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) static PyObject *bpy_bm_elem_hflag_get(BPy_BMElem *self, void *flag)
{ {
const char hflag = (char)GET_INT_FROM_POINTER(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)); 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 /* 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 /* 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}, {(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 #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 #endif
/* connectivity data */ /* 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}, {(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 #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 #endif
{(char *)"normal", (getter)bpy_bmface_normal_get, (setter)bpy_bmface_normal_set, (char *)bpy_bmface_normal_doc, NULL}, {(char *)"normal", (getter)bpy_bmface_normal_get, (setter)bpy_bmface_normal_set, (char *)bpy_bmface_normal_doc, NULL},

View File

@ -112,6 +112,14 @@ PyDoc_STRVAR(bpy_bmlayeraccess_collection__uv_doc,
PyDoc_STRVAR(bpy_bmlayeraccess_collection__color_doc, PyDoc_STRVAR(bpy_bmlayeraccess_collection__color_doc,
"Accessor for vertex color layer.\n\ntype: :class:`BMLayerCollection`" "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) 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 *)"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}, {(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 */ {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}, {(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 */ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
}; };

View File

@ -396,6 +396,7 @@ typedef struct VlakRen {
char flag, ec; char flag, ec;
#ifdef WITH_FREESTYLE #ifdef WITH_FREESTYLE
char freestyle_edge_mark; char freestyle_edge_mark;
char freestyle_face_mark;
#endif #endif
int index; int index;
} VlakRen; } VlakRen;

View File

@ -2657,6 +2657,9 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
MVert *mvert = NULL; MVert *mvert = NULL;
MFace *mface; MFace *mface;
Material *ma; Material *ma;
#ifdef WITH_FREESTYLE
FreestyleFace *ffa;
#endif
/* Curve *cu= ELEM(ob->type, OB_FONT, OB_CURVE) ? ob->data : NULL; */ /* Curve *cu= ELEM(ob->type, OB_FONT, OB_CURVE) ? ob->data : NULL; */
mvert= dm->getVertArray(dm); 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); ma= give_render_material(re, ob, mat_iter+1);
end= dm->getNumTessFaces(dm); end= dm->getNumTessFaces(dm);
mface= dm->getTessFaceArray(dm); mface= dm->getTessFaceArray(dm);
#ifdef WITH_FREESTYLE
ffa= dm->getTessFaceDataArray(dm, CD_FREESTYLE_FACE);
#endif
for (a=0; a<end; a++, mface++) { for (a=0; a<end; a++, mface++) {
int v1, v2, v3, v4, flag; int v1, v2, v3, v4, flag;
@ -2697,11 +2703,7 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
v2= mface->v2; v2= mface->v2;
v3= mface->v3; v3= mface->v3;
v4= mface->v4; v4= mface->v4;
#ifdef WITH_FREESTYLE
flag = mface->flag & (ME_SMOOTH | ME_FREESTYLE_FACE);
#else
flag = mface->flag & ME_SMOOTH; flag = mface->flag & ME_SMOOTH;
#endif
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->v1= RE_findOrAddVert(obr, vertofs+v1); 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->mat= ma;
vlr->flag= flag; vlr->flag= flag;
vlr->ec= 0; /* mesh edges rendered separately */ 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--; if (len==0) obr->totvlak--;
else { else {
@ -3227,14 +3232,21 @@ static void add_volume(Render *re, ObjectRen *obr, Material *ma)
} }
#ifdef WITH_FREESTYLE #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(); EdgeHash *edge_hash= BLI_edgehash_new();
int a; FreestyleEdge *fed;
MEdge *medge;
int totedge, a;
for(a=0; a<totedge; a++) { medge = dm->getEdgeArray(dm);
if(medge[a].flag & ME_FREESTYLE_EDGE) totedge = dm->getNumEdges(dm);
BLI_edgehash_insert(edge_hash, medge[a].v1, medge[a].v2, medge+a); 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; return edge_hash;
} }
@ -3265,6 +3277,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
int use_original_normals = FALSE; int use_original_normals = FALSE;
int recalc_normals = 0; /* false by default */ int recalc_normals = 0; /* false by default */
int negative_scale; int negative_scale;
#ifdef WITH_FREESTYLE
FreestyleFace *ffa;
#endif
me= ob->data; me= ob->data;
@ -3392,13 +3407,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if (!timeoffset) { if (!timeoffset) {
#ifdef WITH_FREESTYLE #ifdef WITH_FREESTYLE
EdgeHash *edge_hash; EdgeHash *edge_hash;
MEdge *medge;
int totedge;
/* create a hash table of Freestyle edge marks */ /* create a hash table of Freestyle edge marks */
medge = dm->getEdgeArray(dm); edge_hash = make_freestyle_edge_mark_hash(dm);
totedge = dm->getNumEdges(dm);
edge_hash = make_freestyle_edge_mark_hash(medge, totedge);
#endif #endif
/* store customdata names, because DerivedMesh is freed */ /* store customdata names, because DerivedMesh is freed */
@ -3437,6 +3448,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if (ok) { if (ok) {
end= dm->getNumTessFaces(dm); end= dm->getNumTessFaces(dm);
mface= dm->getTessFaceArray(dm); mface= dm->getTessFaceArray(dm);
#ifdef WITH_FREESTYLE
ffa= dm->getTessFaceDataArray(dm, CD_FREESTYLE_FACE);
#endif
for (a=0; a<end; a++, mface++) { for (a=0; a<end; a++, mface++) {
int v1, v2, v3, v4, flag; int v1, v2, v3, v4, flag;
@ -3449,11 +3463,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
v2= mface->v2; v2= mface->v2;
v3= reverse_verts==0 ? mface->v3 : mface->v1; v3= reverse_verts==0 ? mface->v3 : mface->v1;
v4= mface->v4; v4= mface->v4;
#ifdef WITH_FREESTYLE
flag = mface->flag & (ME_SMOOTH | ME_FREESTYLE_FACE);
#else
flag = mface->flag & ME_SMOOTH; flag = mface->flag & ME_SMOOTH;
#endif
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->v1= RE_findOrAddVert(obr, vertofs+v1); 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; else vlr->v4= 0;
#ifdef WITH_FREESTYLE #ifdef WITH_FREESTYLE
/* Freestyle edge marks */ /* Freestyle edge/face marks */
{ {
int edge_mark = 0; 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_edge_mark= edge_mark;
} }
vlr->freestyle_face_mark= (ffa && (ffa[a].flag & FREESTYLE_FACE_MARK)) ? 1 : 0;
#endif #endif
/* render normals are inverted in render */ /* render normals are inverted in render */