diff options
Diffstat (limited to 'source/blender/editors')
23 files changed, 1011 insertions, 20 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index f5c9bfb4cf5..038fbf291d3 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -47,6 +47,7 @@ #include "DNA_key_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" +#include "DNA_linestyle_types.h" #include "DNA_mesh_types.h" #include "DNA_material_types.h" #include "DNA_meta_types.h" @@ -2010,6 +2011,83 @@ static bAnimChannelType ACF_DSNTREE = acf_dsntree_setting_ptr /* pointer for setting */ }; +/* LineStyle Expander ------------------------------------------- */ + +/* TODO: just get this from RNA? */ +static int acf_dslinestyle_icon(bAnimListElem *UNUSED(ale)) +{ + return ICON_BRUSH_DATA; /* FIXME */ +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +{ + /* clear extra return data first */ + *neg = 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return LS_DS_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ + *neg = 1; + return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ale->data; + + /* clear extra return data first */ + *type = 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return GET_ACF_FLAG_PTR(linestyle->flag, type); + + case ACHANNEL_SETTING_SELECT: /* selected */ + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ + if (linestyle->adt) + return GET_ACF_FLAG_PTR(linestyle->adt->flag, type); + else + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* node tree expander type define */ +static bAnimChannelType ACF_DSLINESTYLE= +{ + "Line Style Expander", /* type name */ + + acf_generic_dataexpand_color, /* backdrop color */ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_generic_idblock_nameprop, /* name prop */ + acf_dslinestyle_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dslinestyle_setting_flag, /* flag for setting */ + acf_dslinestyle_setting_ptr /* pointer for setting */ +}; + /* Mesh Expander ------------------------------------------- */ // TODO: just get this from RNA? @@ -2722,6 +2800,7 @@ static void ANIM_init_channel_typeinfo_data(void) animchannelTypeInfo[type++] = &ACF_DSTEX; /* Texture Channel */ animchannelTypeInfo[type++] = &ACF_DSLAT; /* Lattice Channel */ animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */ + animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */ animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */ diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 458054c9d7f..466bb178136 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -124,6 +124,7 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, short datatype, int f case ANIMTYPE_DSMESH: case ANIMTYPE_DSTEX: case ANIMTYPE_DSLAT: + case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: { /* need to verify that this data is valid for now */ @@ -169,6 +170,7 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, short datatype, int f case ANIMTYPE_DSARM: case ANIMTYPE_DSMESH: case ANIMTYPE_DSLAT: + case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: { /* need to verify that this data is valid for now */ @@ -249,6 +251,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, short datatype, s case ANIMTYPE_DSNTREE: case ANIMTYPE_DSTEX: case ANIMTYPE_DSLAT: + case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: { if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) @@ -343,6 +346,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, short datatype, s case ANIMTYPE_DSNTREE: case ANIMTYPE_DSTEX: case ANIMTYPE_DSLAT: + case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: { /* need to verify that this data is valid for now */ @@ -2207,6 +2211,7 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in case ANIMTYPE_DSNTREE: case ANIMTYPE_DSTEX: case ANIMTYPE_DSLAT: + case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: { /* sanity checking... */ diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 5e215fbd6a2..86cb805c68a 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -55,6 +55,7 @@ #include "DNA_camera_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" +#include "DNA_linestyle_types.h" #include "DNA_key_types.h" #include "DNA_mask_types.h" #include "DNA_material_types.h" @@ -736,6 +737,19 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->adt = BKE_animdata_from_id(data); } break; + case ANIMTYPE_DSLINESTYLE: + { + FreestyleLineStyle *linestyle = (FreestyleLineStyle *)data; + AnimData *adt = linestyle->adt; + + ale->flag = FILTER_LS_SCED(linestyle); + + ale->key_data = (adt) ? adt->action : NULL; + ale->datatype = ALE_ACT; + + ale->adt = BKE_animdata_from_id(data); + } + break; case ANIMTYPE_DSPART: { ParticleSettings *part = (ParticleSettings *)ale->data; @@ -1513,6 +1527,54 @@ static size_t animdata_filter_ds_nodetree(bAnimContext *ac, ListBase *anim_data, return items; } +static size_t animdata_filter_ds_linestyle (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode) +{ + SceneRenderLayer *srl; + size_t items = 0; + + for (srl = sce->r.layers.first; srl; srl = srl->next) { + FreestyleLineSet *lineset; + + /* skip render layers without Freestyle enabled */ + if (!(srl->layflag & SCE_LAY_FRS)) + continue; + + /* loop over linesets defined in the render layer */ + for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { + FreestyleLineStyle *linestyle = lineset->linestyle; + ListBase tmp_data = {NULL, NULL}; + size_t tmp_items = 0; + + /* add scene-level animation channels */ + BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_LS_SCED(linestyle)) + { + /* animation data filtering */ + tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)linestyle, filter_mode); + } + END_ANIMFILTER_SUBCHANNELS; + + /* did we find anything? */ + if (tmp_items) { + /* include anim-expand widget first */ + if (filter_mode & ANIMFILTER_LIST_CHANNELS) { + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(linestyle) { + ANIMCHANNEL_NEW_CHANNEL(linestyle, ANIMTYPE_DSLINESTYLE, sce); + } + } + + /* now add the list of collected channels */ + BLI_movelisttolist(anim_data, &tmp_data); + BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL)); + items += tmp_items; + } + } + } + + /* return the number of items added to the list */ + return items; +} + /* NOTE: owner_id is either material, lamp, or world block, which is the direct owner of the texture stack in question */ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode) { @@ -2147,6 +2209,11 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode); } + /* line styles */ + if ((ads->filterflag & ADS_FILTER_NOLINESTYLE) == 0) { + tmp_items += animdata_filter_ds_linestyle(ac, &tmp_data, ads, sce, filter_mode); + } + /* TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here */ } END_ANIMFILTER_SUBCHANNELS; diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 551d3041398..e288963553e 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -155,6 +155,7 @@ typedef enum eAnim_ChannelType { ANIMTYPE_DSMESH, ANIMTYPE_DSTEX, ANIMTYPE_DSLAT, + ANIMTYPE_DSLINESTYLE, ANIMTYPE_DSSPK, ANIMTYPE_SHAPEKEY, @@ -236,6 +237,7 @@ typedef enum eAnimFilter_Flags { #define EXPANDED_SCEC(sce) (CHECK_TYPE_INLINE(sce, Scene), ((sce->flag & SCE_DS_COLLAPSED) == 0)) /* 'Sub-Scene' channels (flags stored in Data block) */ #define FILTER_WOR_SCED(wo) (CHECK_TYPE_INLINE(wo, World), (wo->flag & WO_DS_EXPAND)) +#define FILTER_LS_SCED(linestyle) ((linestyle->flag & LS_DS_EXPAND)) /* 'Object' channels */ #define SEL_OBJC(base) (CHECK_TYPE_INLINE(base, Base), ((base->flag & SELECT))) #define EXPANDED_OBJC(ob) (CHECK_TYPE_INLINE(ob, Object), ((ob->nlaflag & OB_ADS_COLLAPSED) == 0)) diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index eaab17c4137..a43e1705101 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -200,6 +200,9 @@ enum { TH_STITCH_PREVIEW_UNSTITCHABLE, TH_STITCH_PREVIEW_ACTIVE, + TH_FREESTYLE_EDGE_MARK, + TH_FREESTYLE_FACE_MARK, + TH_MATCH, /* highlight color for search matches */ TH_SELECT_HIGHLIGHT, /* highlight color for selected outliner item */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 6983723e9b5..456a8a95a58 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -325,6 +325,7 @@ static const char *template_id_browse_tip(StructRNA *type) case ID_MA: return N_("Browse Material to be linked"); case ID_TE: return N_("Browse Texture to be linked"); case ID_IM: return N_("Browse Image to be linked"); + case ID_LS: return N_("Browse Line Style Data to be linked"); case ID_LT: return N_("Browse Lattice Data to be linked"); case ID_LA: return N_("Browse Lamp Data to be linked"); case ID_CA: return N_("Browse Camera Data to be linked"); @@ -360,6 +361,7 @@ static const char *template_id_context(StructRNA *type) case ID_MA: return BLF_I18NCONTEXT_ID_MATERIAL; case ID_TE: return BLF_I18NCONTEXT_ID_TEXTURE; case ID_IM: return BLF_I18NCONTEXT_ID_IMAGE; + case ID_LS: return BLF_I18NCONTEXT_ID_FREESTYLELINESTYLE; case ID_LT: return BLF_I18NCONTEXT_ID_LATTICE; case ID_LA: return BLF_I18NCONTEXT_ID_LAMP; case ID_CA: return BLF_I18NCONTEXT_ID_CAMERA; @@ -515,7 +517,8 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str BLF_I18NCONTEXT_ID_NODETREE, BLF_I18NCONTEXT_ID_BRUSH, BLF_I18NCONTEXT_ID_PARTICLESETTINGS, - BLF_I18NCONTEXT_ID_GPENCIL); + BLF_I18NCONTEXT_ID_GPENCIL, + BLF_I18NCONTEXT_ID_FREESTYLELINESTYLE); if (newop) { but = uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, @@ -2411,7 +2414,8 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe uiBlockSetEmboss(block, UI_EMBOSS); uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, ptr, "use_textures", i, 0, 0, 0, 0, NULL); } - else if (RNA_struct_is_a(itemptr->type, &RNA_SceneRenderLayer)) { + else if (RNA_struct_is_a(itemptr->type, &RNA_SceneRenderLayer) || + RNA_struct_is_a(itemptr->type, &RNA_FreestyleLineSet)) { uiItemL(sub, name, icon); uiBlockSetEmboss(block, UI_EMBOSS); uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "use", 0, 0, 0, 0, 0, NULL); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 3036961d279..b45d14bfa90 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -349,6 +349,10 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo cp = ts->handle_sel_vect; break; case TH_HANDLE_SEL_ALIGN: cp = ts->handle_sel_align; break; + case TH_FREESTYLE_EDGE_MARK: + cp = ts->freestyle_edge_mark; break; + case TH_FREESTYLE_FACE_MARK: + cp = ts->freestyle_face_mark; break; case TH_SYNTAX_B: cp = ts->syntaxb; break; @@ -728,6 +732,8 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tv3d.button_text_hi, 255, 255, 255, 255); rgba_char_args_set(btheme->tv3d.button_title, 0, 0, 0, 255); rgba_char_args_set(btheme->tv3d.title, 0, 0, 0, 255); + rgba_char_args_set(btheme->tv3d.freestyle_edge_mark, 0x7f, 0xff, 0x7f, 255); + rgba_char_args_set(btheme->tv3d.freestyle_face_mark, 0x7f, 0xff, 0x7f, 51); btheme->tv3d.facedot_size = 4; @@ -1973,6 +1979,19 @@ void init_userdef_do_versions(void) } } + /* Freestyle color settings */ + { + bTheme *btheme; + + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + /* check for alpha == 0 is safe, then color was never set */ + if (btheme->tv3d.freestyle_edge_mark[3] == 0) { + rgba_char_args_set(btheme->tv3d.freestyle_edge_mark, 0x7f, 0xff, 0x7f, 255); + rgba_char_args_set(btheme->tv3d.freestyle_face_mark, 0x7f, 0xff, 0x7f, 51); + } + } + } + /* GL Texture Garbage Collection (variable abused above!) */ if (U.textimeout == 0) { U.texcollectrate = 60; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 6ca7777f8e2..2538ddfc886 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -683,6 +683,7 @@ static EnumPropertyItem prop_similar_types[] = { {SIMEDGE_BEVEL, "BEVEL", 0, "Bevel", ""}, {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""}, {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""}, + {SIMEDGE_FREESTYLE, "FREESTYLE_EDGE", 0, "Freestyle Edge Marks", ""}, {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""}, {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""}, @@ -691,6 +692,7 @@ static EnumPropertyItem prop_similar_types[] = { {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""}, {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""}, {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""}, + {SIMFACE_FREESTYLE, "FREESTYLE_FACE", 0, "Freestyle Face Marks", ""}, {0, NULL, 0, NULL, NULL} }; @@ -865,7 +867,7 @@ static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUS } } else if (em->selectmode & SCE_SELECT_FACE) { - for (a = SIMFACE_MATERIAL; a <= SIMFACE_COPLANAR; a++) { + for (a = SIMFACE_MATERIAL; a <= SIMFACE_FREESTYLE; a++) { RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a); } } @@ -1315,6 +1317,9 @@ 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; + case EDGE_MODE_TAG_FREESTYLE: + BM_elem_flag_set(e, BM_ELEM_FREESTYLE, val); + break; case EDGE_MODE_TAG_CREASE: BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (val) ? 1.0f : 0.0f); break; @@ -1333,6 +1338,8 @@ 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); + case EDGE_MODE_TAG_FREESTYLE: + return !BM_elem_flag_test(e, BM_ELEM_FREESTYLE); case EDGE_MODE_TAG_CREASE: return BM_elem_float_data_get(&bm->edata, e, CD_CREASE) ? TRUE : FALSE; case EDGE_MODE_TAG_BEVEL: @@ -1487,6 +1494,9 @@ static int mouse_mesh_shortest_path_edge(ViewContext *vc) case EDGE_MODE_TAG_BEVEL: me->drawflag |= ME_DRAWBWEIGHTS; break; + case EDGE_MODE_TAG_FREESTYLE: + me->drawflag |= ME_DRAW_FREESTYLE_EDGE; + break; } EDBM_update_generic(em, FALSE, FALSE); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index e2083539392..df2722f1fbc 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5763,3 +5763,107 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot) BMO_SYMMETRIZE_NEGATIVE_X, "Direction", "Which sides to copy from and to"); } + +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; + BMEdge *eed; + BMIter iter; + int clear = RNA_boolean_get(op->ptr, "clear"); + + if (em == NULL) + return OPERATOR_FINISHED; + + /* auto-enable seams drawing */ + if (clear == 0) { + me->drawflag |= ME_DRAW_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); + } + } + 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); + } + } + + DAG_id_tag_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + return OPERATOR_FINISHED; +} + +void MESH_OT_mark_freestyle_edge(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Mark Freestyle Edge"; + ot->description = "(un)mark selected edges as Freestyle feature edges"; + ot->idname = "MESH_OT_mark_freestyle_edge"; + + /* api callbacks */ + ot->exec = edbm_mark_freestyle_edge; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "clear", 0, "Clear", ""); +} + +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; + BMFace *efa; + BMIter iter; + int clear = RNA_boolean_get(op->ptr, "clear"); + + if (em == NULL) return OPERATOR_FINISHED; + + /* auto-enable Freestyle face mark drawing */ + if(!clear) { + me->drawflag |= ME_DRAW_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); + } + } 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); + } + } + + DAG_id_tag_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + return OPERATOR_FINISHED; +} + +void MESH_OT_mark_freestyle_face(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Mark Freestyle Face"; + ot->description = "(un)mark selected faces for exclusion from Freestyle feature edge detection"; + ot->idname = "MESH_OT_mark_freestyle_face"; + + /* api callbacks */ + ot->exec = edbm_mark_freestyle_face_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "clear", 0, "Clear", ""); +} diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index e335c909e8e..043679b9d8a 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -131,6 +131,7 @@ void MESH_OT_select_random(struct wmOperatorType *ot); void MESH_OT_loop_multi_select(struct wmOperatorType *ot); void MESH_OT_mark_seam(struct wmOperatorType *ot); void MESH_OT_mark_sharp(struct wmOperatorType *ot); +void MESH_OT_mark_freestyle_edge(struct wmOperatorType *ot); void MESH_OT_vertices_smooth(struct wmOperatorType *ot); void MESH_OT_vertices_smooth_laplacian(struct wmOperatorType *ot); void MESH_OT_noise(struct wmOperatorType *ot); @@ -180,6 +181,7 @@ void MESH_OT_rip(struct wmOperatorType *ot); void MESH_OT_shape_propagate_to_all(struct wmOperatorType *ot); void MESH_OT_blend_from_shape(struct wmOperatorType *ot); void MESH_OT_sort_elements(struct wmOperatorType *ot); +void MESH_OT_mark_freestyle_face(struct wmOperatorType *ot); /* ******************* mesh_data.c */ diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index a413a60412c..a2ac08268e0 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -118,6 +118,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_faces_shade_smooth); WM_operatortype_append(MESH_OT_faces_shade_flat); WM_operatortype_append(MESH_OT_sort_elements); + WM_operatortype_append(MESH_OT_mark_freestyle_face); WM_operatortype_append(MESH_OT_delete); WM_operatortype_append(MESH_OT_edge_collapse); @@ -133,6 +134,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_loop_multi_select); WM_operatortype_append(MESH_OT_mark_seam); WM_operatortype_append(MESH_OT_mark_sharp); + WM_operatortype_append(MESH_OT_mark_freestyle_edge); WM_operatortype_append(MESH_OT_vertices_smooth); WM_operatortype_append(MESH_OT_vertices_smooth_laplacian); WM_operatortype_append(MESH_OT_noise); diff --git a/source/blender/editors/render/CMakeLists.txt b/source/blender/editors/render/CMakeLists.txt index 3c5fd0b4ef7..c9be7d0e5e0 100644 --- a/source/blender/editors/render/CMakeLists.txt +++ b/source/blender/editors/render/CMakeLists.txt @@ -36,6 +36,7 @@ set(INC set(INC_SYS ${GLEW_INCLUDE_PATH} + ../../freestyle ) set(SRC diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript index c05b542aea8..15bcb9a907f 100644 --- a/source/blender/editors/render/SConscript +++ b/source/blender/editors/render/SConscript @@ -31,7 +31,7 @@ sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' -incs += ' ../../gpu' +incs += ' ../../gpu ../../freestyle' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' incs += ' ../../blenloader ../../bmesh' diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index 18ba2b5abf9..40d0c9536f4 100644 --- a/source/blender/editors/render/render_intern.h +++ b/source/blender/editors/render/render_intern.h @@ -53,6 +53,22 @@ void MATERIAL_OT_paste(struct wmOperatorType *ot); void SCENE_OT_render_layer_add(struct wmOperatorType *ot); void SCENE_OT_render_layer_remove(struct wmOperatorType *ot); +void SCENE_OT_freestyle_module_add(struct wmOperatorType *ot); +void SCENE_OT_freestyle_module_remove(struct wmOperatorType *ot); +void SCENE_OT_freestyle_module_move(struct wmOperatorType *ot); +void SCENE_OT_freestyle_lineset_add(struct wmOperatorType *ot); +void SCENE_OT_freestyle_lineset_copy(struct wmOperatorType *ot); +void SCENE_OT_freestyle_lineset_paste(struct wmOperatorType *ot); +void SCENE_OT_freestyle_lineset_remove(struct wmOperatorType *ot); +void SCENE_OT_freestyle_lineset_move(struct wmOperatorType *ot); +void SCENE_OT_freestyle_linestyle_new(struct wmOperatorType *ot); +void SCENE_OT_freestyle_color_modifier_add(struct wmOperatorType *ot); +void SCENE_OT_freestyle_alpha_modifier_add(struct wmOperatorType *ot); +void SCENE_OT_freestyle_thickness_modifier_add(struct wmOperatorType *ot); +void SCENE_OT_freestyle_geometry_modifier_add(struct wmOperatorType *ot); +void SCENE_OT_freestyle_modifier_remove(struct wmOperatorType *ot); +void SCENE_OT_freestyle_modifier_move(struct wmOperatorType *ot); +void SCENE_OT_freestyle_modifier_copy(struct wmOperatorType *ot); void TEXTURE_OT_slot_copy(struct wmOperatorType *ot); diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c index c9e6dc90515..eb9a4cb30e4 100644 --- a/source/blender/editors/render/render_ops.c +++ b/source/blender/editors/render/render_ops.c @@ -62,6 +62,23 @@ void ED_operatortypes_render(void) WM_operatortype_append(SCENE_OT_render_layer_add); WM_operatortype_append(SCENE_OT_render_layer_remove); + WM_operatortype_append(SCENE_OT_freestyle_module_add); + WM_operatortype_append(SCENE_OT_freestyle_module_remove); + WM_operatortype_append(SCENE_OT_freestyle_module_move); + WM_operatortype_append(SCENE_OT_freestyle_lineset_add); + WM_operatortype_append(SCENE_OT_freestyle_lineset_copy); + WM_operatortype_append(SCENE_OT_freestyle_lineset_paste); + WM_operatortype_append(SCENE_OT_freestyle_lineset_remove); + WM_operatortype_append(SCENE_OT_freestyle_lineset_move); + WM_operatortype_append(SCENE_OT_freestyle_linestyle_new); + WM_operatortype_append(SCENE_OT_freestyle_color_modifier_add); + WM_operatortype_append(SCENE_OT_freestyle_alpha_modifier_add); + WM_operatortype_append(SCENE_OT_freestyle_thickness_modifier_add); + WM_operatortype_append(SCENE_OT_freestyle_geometry_modifier_add); + WM_operatortype_append(SCENE_OT_freestyle_modifier_remove); + WM_operatortype_append(SCENE_OT_freestyle_modifier_move); + WM_operatortype_append(SCENE_OT_freestyle_modifier_copy); + #if (defined(WITH_QUICKTIME) && !defined(USE_QTKIT)) WM_operatortype_append(SCENE_OT_render_data_set_quicktime_codec); #endif diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index eef5e705ce7..928930c61f9 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -55,6 +55,7 @@ #include "BKE_icons.h" #include "BKE_image.h" #include "BKE_library.h" +#include "BKE_linestyle.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_node.h" @@ -69,7 +70,10 @@ #include "GPU_material.h" +#include "FRS_freestyle.h" + #include "RNA_access.h" +#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -570,6 +574,620 @@ void SCENE_OT_render_layer_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int freestyle_module_add_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + + FRS_add_module(&srl->freestyleConfig); + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_module_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Freestyle Module"; + ot->idname = "SCENE_OT_freestyle_module_add"; + ot->description = "Add a style module into the list of modules"; + + /* api callbacks */ + ot->exec = freestyle_module_add_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int freestyle_module_remove_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings); + FreestyleModuleConfig *module = ptr.data; + + FRS_delete_module(&srl->freestyleConfig, module); + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_module_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Freestyle Module"; + ot->idname = "SCENE_OT_freestyle_module_remove"; + ot->description = "Remove the style module from the stack"; + + /* api callbacks */ + ot->exec = freestyle_module_remove_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int freestyle_module_move_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings); + FreestyleModuleConfig *module = ptr.data; + int dir = RNA_enum_get(op->ptr, "direction"); + + if (dir == 1) { + FRS_move_module_up(&srl->freestyleConfig, module); + } + else { + FRS_move_module_down(&srl->freestyleConfig, module); + } + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_module_move(wmOperatorType *ot) +{ + static EnumPropertyItem direction_items[] = { + {1, "UP", 0, "Up", ""}, + {-1, "DOWN", 0, "Down", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Move Freestyle Module"; + ot->idname = "SCENE_OT_freestyle_module_move"; + ot->description = "Change the position of the style module within in the list of style modules"; + + /* api callbacks */ + ot->exec = freestyle_module_move_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to move, UP or DOWN"); +} + +static int freestyle_lineset_add_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + + FRS_add_lineset(&srl->freestyleConfig); + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_lineset_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Line Set"; + ot->idname = "SCENE_OT_freestyle_lineset_add"; + ot->description = "Add a line set into the list of line sets"; + + /* api callbacks */ + ot->exec = freestyle_lineset_add_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int freestyle_active_lineset_poll(bContext *C) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + + return FRS_get_active_lineset(&srl->freestyleConfig) != NULL; +} + +static int freestyle_lineset_copy_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + + FRS_copy_active_lineset(&srl->freestyleConfig); + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_lineset_copy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Copy Line Set"; + ot->idname = "SCENE_OT_freestyle_lineset_copy"; + ot->description = "Copy the active line set to a buffer"; + + /* api callbacks */ + ot->exec = freestyle_lineset_copy_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int freestyle_lineset_paste_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + + FRS_paste_active_lineset(&srl->freestyleConfig); + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_lineset_paste(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Paste Line Set"; + ot->idname = "SCENE_OT_freestyle_lineset_paste"; + ot->description = "Paste the buffer content to the active line set"; + + /* api callbacks */ + ot->exec = freestyle_lineset_paste_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int freestyle_lineset_remove_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + + FRS_delete_active_lineset(&srl->freestyleConfig); + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_lineset_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Line Set"; + ot->idname = "SCENE_OT_freestyle_lineset_remove"; + ot->description = "Remove the active line set from the list of line sets"; + + /* api callbacks */ + ot->exec = freestyle_lineset_remove_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int freestyle_lineset_move_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + int dir = RNA_enum_get(op->ptr, "direction"); + + if (dir == 1) { + FRS_move_active_lineset_up(&srl->freestyleConfig); + } + else { + FRS_move_active_lineset_down(&srl->freestyleConfig); + } + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_lineset_move(wmOperatorType *ot) +{ + static EnumPropertyItem direction_items[] = { + {1, "UP", 0, "Up", ""}, + {-1, "DOWN", 0, "Down", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Move Line Set"; + ot->idname = "SCENE_OT_freestyle_lineset_move"; + ot->description = "Change the position of the active line set within the list of line sets"; + + /* api callbacks */ + ot->exec = freestyle_lineset_move_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to move, UP or DOWN"); +} + +static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + FreestyleLineSet *lineset = FRS_get_active_lineset(&srl->freestyleConfig); + + if (!lineset) { + BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to"); + return OPERATOR_CANCELLED; + } + lineset->linestyle->id.us--; + lineset->linestyle = FRS_copy_linestyle(lineset->linestyle); + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_linestyle_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "New Line Style"; + ot->idname = "SCENE_OT_freestyle_linestyle_new"; + ot->description = "Create a new line style, reusable by multiple line sets"; + + /* api callbacks */ + ot->exec = freestyle_linestyle_new_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int freestyle_color_modifier_add_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + FreestyleLineSet *lineset = FRS_get_active_lineset(&srl->freestyleConfig); + int type = RNA_enum_get(op->ptr, "type"); + + if (!lineset) { + BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to"); + return OPERATOR_CANCELLED; + } + if (FRS_add_linestyle_color_modifier(lineset->linestyle, type) < 0) { + BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type."); + return OPERATOR_CANCELLED; + } + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_color_modifier_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Line Color Modifier"; + ot->idname = "SCENE_OT_freestyle_color_modifier_add"; + ot->description = "Add a line color modifier to the line style associated with the active lineset"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = freestyle_color_modifier_add_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", linestyle_color_modifier_type_items, 0, "Type", ""); +} + +static int freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + FreestyleLineSet *lineset = FRS_get_active_lineset(&srl->freestyleConfig); + int type = RNA_enum_get(op->ptr, "type"); + + if (!lineset) { + BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to"); + return OPERATOR_CANCELLED; + } + if (FRS_add_linestyle_alpha_modifier(lineset->linestyle, type) < 0) { + BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type"); + return OPERATOR_CANCELLED; + } + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_alpha_modifier_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Alpha Transparency Modifier"; + ot->idname = "SCENE_OT_freestyle_alpha_modifier_add"; + ot->description = "Add an alpha transparency modifier to the line style associated with the active lineset"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = freestyle_alpha_modifier_add_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", linestyle_alpha_modifier_type_items, 0, "Type", ""); +} + +static int freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + FreestyleLineSet *lineset = FRS_get_active_lineset(&srl->freestyleConfig); + int type = RNA_enum_get(op->ptr, "type"); + + if (!lineset) { + BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to"); + return OPERATOR_CANCELLED; + } + if (FRS_add_linestyle_thickness_modifier(lineset->linestyle, type) < 0) { + BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type"); + return OPERATOR_CANCELLED; + } + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_thickness_modifier_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Line Thickness Modifier"; + ot->idname = "SCENE_OT_freestyle_thickness_modifier_add"; + ot->description = "Add a line thickness modifier to the line style associated with the active lineset"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = freestyle_thickness_modifier_add_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", linestyle_thickness_modifier_type_items, 0, "Type", ""); +} + +static int freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + FreestyleLineSet *lineset = FRS_get_active_lineset(&srl->freestyleConfig); + int type = RNA_enum_get(op->ptr, "type"); + + if (!lineset) { + BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to"); + return OPERATOR_CANCELLED; + } + if (FRS_add_linestyle_geometry_modifier(lineset->linestyle, type) < 0) { + BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type"); + return OPERATOR_CANCELLED; + } + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_geometry_modifier_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Stroke Geometry Modifier"; + ot->idname = "SCENE_OT_freestyle_geometry_modifier_add"; + ot->description = "Add a stroke geometry modifier to the line style associated with the active lineset"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = freestyle_geometry_modifier_add_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", linestyle_geometry_modifier_type_items, 0, "Type", ""); +} + +static int freestyle_get_modifier_type(PointerRNA *ptr) +{ + if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier)) + return LS_MODIFIER_TYPE_COLOR; + else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier)) + return LS_MODIFIER_TYPE_ALPHA; + else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier)) + return LS_MODIFIER_TYPE_THICKNESS; + else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier)) + return LS_MODIFIER_TYPE_GEOMETRY; + return -1; +} + +static int freestyle_modifier_remove_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + FreestyleLineSet *lineset = FRS_get_active_lineset(&srl->freestyleConfig); + PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier); + LineStyleModifier *modifier = ptr.data; + + if (!lineset) { + BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to"); + return OPERATOR_CANCELLED; + } + + switch (freestyle_get_modifier_type(&ptr)) { + case LS_MODIFIER_TYPE_COLOR: + FRS_remove_linestyle_color_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_ALPHA: + FRS_remove_linestyle_alpha_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_THICKNESS: + FRS_remove_linestyle_thickness_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_GEOMETRY: + FRS_remove_linestyle_geometry_modifier(lineset->linestyle, modifier); + break; + default: + BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier"); + return OPERATOR_CANCELLED; + } + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_modifier_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Modifier"; + ot->idname = "SCENE_OT_freestyle_modifier_remove"; + ot->description = "Remove the modifier from the list of modifiers"; + + /* api callbacks */ + ot->exec = freestyle_modifier_remove_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + FreestyleLineSet *lineset = FRS_get_active_lineset(&srl->freestyleConfig); + PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier); + LineStyleModifier *modifier = ptr.data; + + if (!lineset) { + BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to"); + return OPERATOR_CANCELLED; + } + + switch (freestyle_get_modifier_type(&ptr)) { + case LS_MODIFIER_TYPE_COLOR: + FRS_copy_linestyle_color_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_ALPHA: + FRS_copy_linestyle_alpha_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_THICKNESS: + FRS_copy_linestyle_thickness_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_GEOMETRY: + FRS_copy_linestyle_geometry_modifier(lineset->linestyle, modifier); + break; + default: + BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier"); + return OPERATOR_CANCELLED; + } + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_modifier_copy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Copy Modifier"; + ot->idname = "SCENE_OT_freestyle_modifier_copy"; + ot->description = "Duplicate the modifier within the list of modifiers"; + + /* api callbacks */ + ot->exec = freestyle_modifier_copy_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int freestyle_modifier_move_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + FreestyleLineSet *lineset = FRS_get_active_lineset(&srl->freestyleConfig); + PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier); + LineStyleModifier *modifier = ptr.data; + int dir = RNA_enum_get(op->ptr, "direction"); + + if (!lineset) { + BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to"); + return OPERATOR_CANCELLED; + } + + switch (freestyle_get_modifier_type(&ptr)) { + case LS_MODIFIER_TYPE_COLOR: + FRS_move_linestyle_color_modifier(lineset->linestyle, modifier, dir); + break; + case LS_MODIFIER_TYPE_ALPHA: + FRS_move_linestyle_alpha_modifier(lineset->linestyle, modifier, dir); + break; + case LS_MODIFIER_TYPE_THICKNESS: + FRS_move_linestyle_thickness_modifier(lineset->linestyle, modifier, dir); + break; + case LS_MODIFIER_TYPE_GEOMETRY: + FRS_move_linestyle_geometry_modifier(lineset->linestyle, modifier, dir); + break; + default: + BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier"); + return OPERATOR_CANCELLED; + } + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot) +{ + static EnumPropertyItem direction_items[] = { + {1, "UP", 0, "Up", ""}, + {-1, "DOWN", 0, "Down", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Move Modifier"; + ot->idname = "SCENE_OT_freestyle_modifier_move"; + ot->description = "Move the modifier within the list of modifiers"; + + /* api callbacks */ + ot->exec = freestyle_modifier_move_exec; + ot->poll = freestyle_active_lineset_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to move, UP or DOWN"); +} + static int texture_slot_move(bContext *C, wmOperator *op) { ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data; diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 2a5b64cd6ed..91f069d16de 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -538,6 +538,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma switch (mainb) { case BCONTEXT_SCENE: case BCONTEXT_RENDER: + case BCONTEXT_RENDER_LAYER: found = buttons_context_path_scene(path); break; case BCONTEXT_WORLD: @@ -1043,7 +1044,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout) name = RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf), NULL); if (name) { - if (!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE) && ptr->type == &RNA_Scene) + if (!ELEM3(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE, BCONTEXT_RENDER_LAYER) && ptr->type == &RNA_Scene) uiItemLDrag(row, ptr, "", icon); /* save some space */ else uiItemLDrag(row, ptr, name, icon); diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c index ebba7d92819..3c2d9ac2eee 100644 --- a/source/blender/editors/space_buttons/buttons_header.c +++ b/source/blender/editors/space_buttons/buttons_header.c @@ -128,6 +128,7 @@ void buttons_header_buttons(const bContext *C, ARegion *ar) } (void)0 BUTTON_HEADER_CTX(BCONTEXT_RENDER, ICON_SCENE, N_("Render")); + BUTTON_HEADER_CTX(BCONTEXT_RENDER_LAYER, ICON_RENDERLAYERS, N_("Render Layers")); BUTTON_HEADER_CTX(BCONTEXT_SCENE, ICON_SCENE_DATA, N_("Scene")); BUTTON_HEADER_CTX(BCONTEXT_WORLD, ICON_WORLD, N_("World")); BUTTON_HEADER_CTX(BCONTEXT_OBJECT, ICON_OBJECT_DATA, N_("Object")); diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index c98d213e949..698139e90bf 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -155,6 +155,8 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar) ED_region_panels(C, ar, vertical, "scene", sbuts->mainb); else if (sbuts->mainb == BCONTEXT_RENDER) ED_region_panels(C, ar, vertical, "render", sbuts->mainb); + else if (sbuts->mainb == BCONTEXT_RENDER_LAYER) + ED_region_panels(C, ar, vertical, "render_layer", sbuts->mainb); else if (sbuts->mainb == BCONTEXT_WORLD) ED_region_panels(C, ar, vertical, "world", sbuts->mainb); else if (sbuts->mainb == BCONTEXT_OBJECT) @@ -239,6 +241,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) switch (wmn->data) { case ND_RENDER_OPTIONS: buttons_area_redraw(sa, BCONTEXT_RENDER); + buttons_area_redraw(sa, BCONTEXT_RENDER_LAYER); break; case ND_FRAME: /* any buttons area can have animated properties so redraw all */ @@ -375,6 +378,10 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) ED_area_tag_redraw(sa); sbuts->preview = 1; break; + case NC_LINESTYLE: + ED_area_tag_redraw(sa); + sbuts->preview = 1; + break; } if (wmn->data == ND_KEYS) diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index a49b75477e4..5b21ebf1742 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1162,7 +1162,7 @@ void filelist_from_main(struct FileList *filelist) if (filelist->dir[0] == 0) { /* make directories */ - filelist->numfiles = 24; + filelist->numfiles = 25; filelist->filelist = (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry)); for (a = 0; a < filelist->numfiles; a++) { @@ -1193,6 +1193,7 @@ void filelist_from_main(struct FileList *filelist) filelist->filelist[21].relname = BLI_strdup("Action"); filelist->filelist[22].relname = BLI_strdup("NodeTree"); filelist->filelist[23].relname = BLI_strdup("Speaker"); + filelist->filelist[24].relname = BLI_strdup("FreestyleLineStyle"); filelist_sort(filelist, FILE_SORT_ALPHA); } else { diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index d75946c4317..ad6e66f7a7d 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -142,6 +142,7 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA case ANIMTYPE_DSPART: case ANIMTYPE_DSMBALL: case ANIMTYPE_DSARM: + case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: { /* for these channels, we only do AnimData */ diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index 95e75d0e4fc..cf56f254c36 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -178,6 +178,7 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor case ANIMTYPE_DSMESH: case ANIMTYPE_DSTEX: case ANIMTYPE_DSLAT: + case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: { /* sanity checking... */ diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index d444612cfc5..fd1eb7852c1 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -126,7 +126,7 @@ typedef struct drawDMEdgesSel_userData { } drawDMEdgesSel_userData; typedef struct drawDMFacesSel_userData { - unsigned char *cols[3]; + unsigned char *cols[4]; DerivedMesh *dm; /* BMESH BRANCH ONLY */ BMEditMesh *em; /* BMESH BRANCH ONLY */ @@ -2280,6 +2280,21 @@ static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm) dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em); } +/* 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)) + return DM_DRAW_OPTION_NORMAL; + else + return DM_DRAW_OPTION_SKIP; +} + +static void draw_dm_edges_freestyle(BMEditMesh *em, DerivedMesh *dm) +{ + dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em); +} /* Draw faces with color set based on selection * return 2 for the active face so it renders with stipple enabled */ @@ -2294,11 +2309,11 @@ static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index) if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (efa == data->efa_act) { - glColor4ubv(data->cols[2]); + glColor4ubv(data->cols[3]); return DM_DRAW_OPTION_STIPPLE; } 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 : BM_elem_flag_test(efa, BM_ELEM_FREESTYLE) ? 2 : 0]; if (col[3] == 0) return DM_DRAW_OPTION_SKIP; glColor4ubv(col); @@ -2329,8 +2344,8 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int if (efa == data->efa_act || next_efa == data->efa_act) return 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]; + col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : BM_elem_flag_test(efa, BM_ELEM_FREESTYLE) ? 2 : 0]; + next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : BM_elem_flag_test(next_efa, BM_ELEM_FREESTYLE) ? 2 : 0]; if (col[3] == 0 || next_col[3] == 0) return 0; @@ -2340,14 +2355,15 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int /* also draws the active face */ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, - unsigned char *selCol, unsigned char *actCol, BMFace *efa_act) + unsigned char *selCol, unsigned char *markCol, unsigned char *actCol, BMFace *efa_act) { drawDMFacesSel_userData data; data.dm = dm; data.cols[0] = baseCol; data.em = em; data.cols[1] = selCol; - data.cols[2] = actCol; + data.cols[2] = markCol; + data.cols[3] = actCol; data.efa_act = efa_act; /* double lookup */ data.orig_index_mf_to_mpoly = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); @@ -2884,11 +2900,12 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, } if (me->drawflag & ME_DRAWFACES) { /* transp faces */ - unsigned char col1[4], col2[4], col3[4]; + unsigned char col1[4], col2[4], col3[4], col4[4]; UI_GetThemeColor4ubv(TH_FACE, col1); UI_GetThemeColor4ubv(TH_FACE_SELECT, col2); - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3); + UI_GetThemeColor4ubv(TH_FREESTYLE_FACE_MARK, col3); + UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col4); glEnable(GL_BLEND); glDepthMask(0); /* disable write in zbuffer, needed for nice transp */ @@ -2897,7 +2914,10 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, if (check_object_draw_texture(scene, v3d, dt)) col1[3] = 0; - draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act); + if (!(me->drawflag & ME_DRAW_FREESTYLE_FACE)) + col3[3] = 0; + + draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act); glDisable(GL_BLEND); glDepthMask(1); /* restore write in zbuffer */ @@ -2906,14 +2926,14 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, /* even if draw faces is off it would be nice to draw the stipple face * Make all other faces zero alpha except for the active * */ - unsigned char col1[4], col2[4], col3[4]; - col1[3] = col2[3] = 0; /* don't draw */ - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3); + unsigned char col1[4], col2[4], col3[4], col4[4]; + col1[3] = col2[3] = col3[3] = 0; /* don't draw */ + UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col4); glEnable(GL_BLEND); glDepthMask(0); /* disable write in zbuffer, needed for nice transp */ - draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act); + draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act); glDisable(GL_BLEND); glDepthMask(1); /* restore write in zbuffer */ @@ -2949,6 +2969,16 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, glLineWidth(1); } + if(me->drawflag & ME_DRAW_FREESTYLE_EDGE) { + UI_ThemeColor(TH_FREESTYLE_EDGE_MARK); + glLineWidth(2); + + draw_dm_edges_freestyle(em, cageDM); + + glColor3ub(0,0,0); + glLineWidth(1); + } + if (me->drawflag & ME_DRAWCREASES && CustomData_has_layer(&em->bm->edata, CD_CREASE)) { draw_dm_creases(em, cageDM); } |