diff options
Diffstat (limited to 'source/blender/editors')
29 files changed, 872 insertions, 45 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index df114bab367..07743f3b4bd 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -35,6 +35,7 @@ #include "DNA_armature_types.h" #include "DNA_cachefile_types.h" #include "DNA_camera_types.h" +#include "DNA_hair_types.h" #include "DNA_object_types.h" #include "DNA_particle_types.h" #include "DNA_screen_types.h" @@ -48,6 +49,8 @@ #include "DNA_material_types.h" #include "DNA_meta_types.h" #include "DNA_node_types.h" +#include "DNA_pointcloud_types.h" +#include "DNA_volume_types.h" #include "DNA_world_types.h" #include "DNA_gpencil_types.h" #include "DNA_speaker_types.h" @@ -699,6 +702,12 @@ static int acf_object_icon(bAnimListElem *ale) return ICON_OUTLINER_OB_FONT; case OB_SURF: return ICON_OUTLINER_OB_SURFACE; + case OB_HAIR: + return ICON_OUTLINER_OB_HAIR; + case OB_POINTCLOUD: + return ICON_OUTLINER_OB_POINTCLOUD; + case OB_VOLUME: + return ICON_OUTLINER_OB_VOLUME; case OB_EMPTY: return ICON_OUTLINER_OB_EMPTY; case OB_GPENCIL: @@ -2785,6 +2794,244 @@ static bAnimChannelType ACF_DSSPK = { acf_dsspk_setting_ptr, /* pointer for setting */ }; +/* Hair Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dshair_icon(bAnimListElem *UNUSED(ale)) +{ + return ICON_HAIR_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dshair_setting_flag(bAnimContext *UNUSED(ac), + eAnimChannel_Settings setting, + bool *neg) +{ + /* clear extra return data first */ + *neg = false; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return VO_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 = true; + 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_dshair_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type) +{ + Hair *hair = (Hair *)ale->data; + + /* clear extra return data first */ + *type = 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return GET_ACF_FLAG_PTR(hair->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 (hair->adt) + return GET_ACF_FLAG_PTR(hair->adt->flag, type); + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* hair expander type define */ +static bAnimChannelType ACF_DSHAIR = { + "Hair Expander", /* type name */ + ACHANNEL_ROLE_EXPANDER, /* role */ + + 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_name_prop, /* name prop */ + acf_dshair_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dshair_setting_flag, /* flag for setting */ + acf_dshair_setting_ptr /* pointer for setting */ +}; + +/* PointCloud Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dspointcloud_icon(bAnimListElem *UNUSED(ale)) +{ + return ICON_POINTCLOUD_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dspointcloud_setting_flag(bAnimContext *UNUSED(ac), + eAnimChannel_Settings setting, + bool *neg) +{ + /* clear extra return data first */ + *neg = false; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return VO_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 = true; + 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_dspointcloud_setting_ptr(bAnimListElem *ale, + eAnimChannel_Settings setting, + short *type) +{ + PointCloud *pointcloud = (PointCloud *)ale->data; + + /* clear extra return data first */ + *type = 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return GET_ACF_FLAG_PTR(pointcloud->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 (pointcloud->adt) + return GET_ACF_FLAG_PTR(pointcloud->adt->flag, type); + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* pointcloud expander type define */ +static bAnimChannelType ACF_DSPOINTCLOUD = { + "PointCloud Expander", /* type name */ + ACHANNEL_ROLE_EXPANDER, /* role */ + + 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_name_prop, /* name prop */ + acf_dspointcloud_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dspointcloud_setting_flag, /* flag for setting */ + acf_dspointcloud_setting_ptr /* pointer for setting */ +}; + +/* Volume Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dsvolume_icon(bAnimListElem *UNUSED(ale)) +{ + return ICON_VOLUME_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dsvolume_setting_flag(bAnimContext *UNUSED(ac), + eAnimChannel_Settings setting, + bool *neg) +{ + /* clear extra return data first */ + *neg = false; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return VO_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 = true; + 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_dsvolume_setting_ptr(bAnimListElem *ale, + eAnimChannel_Settings setting, + short *type) +{ + Volume *volume = (Volume *)ale->data; + + /* clear extra return data first */ + *type = 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return GET_ACF_FLAG_PTR(volume->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 (volume->adt) + return GET_ACF_FLAG_PTR(volume->adt->flag, type); + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* volume expander type define */ +static bAnimChannelType ACF_DSVOLUME = { + "Volume Expander", /* type name */ + ACHANNEL_ROLE_EXPANDER, /* role */ + + 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_name_prop, /* name prop */ + acf_dsvolume_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dsvolume_setting_flag, /* flag for setting */ + acf_dsvolume_setting_ptr /* pointer for setting */ +}; + /* GPencil Expander ------------------------------------------- */ // TODO: just get this from RNA? @@ -3780,24 +4027,27 @@ static void ANIM_init_channel_typeinfo_data(void) animchannelTypeInfo[type++] = &ACF_FILLACTD; /* Object Action Expander */ animchannelTypeInfo[type++] = &ACF_FILLDRIVERS; /* Drivers Expander */ - animchannelTypeInfo[type++] = &ACF_DSMAT; /* Material Channel */ - animchannelTypeInfo[type++] = &ACF_DSLIGHT; /* Light Channel */ - animchannelTypeInfo[type++] = &ACF_DSCAM; /* Camera Channel */ - animchannelTypeInfo[type++] = &ACF_DSCACHEFILE; /* CacheFile Channel */ - animchannelTypeInfo[type++] = &ACF_DSCUR; /* Curve Channel */ - animchannelTypeInfo[type++] = &ACF_DSSKEY; /* ShapeKey Channel */ - animchannelTypeInfo[type++] = &ACF_DSWOR; /* World Channel */ - animchannelTypeInfo[type++] = &ACF_DSNTREE; /* NodeTree Channel */ - animchannelTypeInfo[type++] = &ACF_DSPART; /* Particle Channel */ - animchannelTypeInfo[type++] = &ACF_DSMBALL; /* MetaBall Channel */ - animchannelTypeInfo[type++] = &ACF_DSARM; /* Armature Channel */ - animchannelTypeInfo[type++] = &ACF_DSMESH; /* Mesh Channel */ - animchannelTypeInfo[type++] = &ACF_DSTEX; /* Texture Channel */ - animchannelTypeInfo[type++] = &ACF_DSLAT; /* Lattice Channel */ - animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */ - animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */ - animchannelTypeInfo[type++] = &ACF_DSGPENCIL; /* GreasePencil Channel */ - animchannelTypeInfo[type++] = &ACF_DSMCLIP; /* MovieClip Channel */ + animchannelTypeInfo[type++] = &ACF_DSMAT; /* Material Channel */ + animchannelTypeInfo[type++] = &ACF_DSLIGHT; /* Light Channel */ + animchannelTypeInfo[type++] = &ACF_DSCAM; /* Camera Channel */ + animchannelTypeInfo[type++] = &ACF_DSCACHEFILE; /* CacheFile Channel */ + animchannelTypeInfo[type++] = &ACF_DSCUR; /* Curve Channel */ + animchannelTypeInfo[type++] = &ACF_DSSKEY; /* ShapeKey Channel */ + animchannelTypeInfo[type++] = &ACF_DSWOR; /* World Channel */ + animchannelTypeInfo[type++] = &ACF_DSNTREE; /* NodeTree Channel */ + animchannelTypeInfo[type++] = &ACF_DSPART; /* Particle Channel */ + animchannelTypeInfo[type++] = &ACF_DSMBALL; /* MetaBall Channel */ + animchannelTypeInfo[type++] = &ACF_DSARM; /* Armature Channel */ + animchannelTypeInfo[type++] = &ACF_DSMESH; /* Mesh Channel */ + animchannelTypeInfo[type++] = &ACF_DSTEX; /* Texture Channel */ + animchannelTypeInfo[type++] = &ACF_DSLAT; /* Lattice Channel */ + animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */ + animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */ + animchannelTypeInfo[type++] = &ACF_DSGPENCIL; /* GreasePencil Channel */ + animchannelTypeInfo[type++] = &ACF_DSMCLIP; /* MovieClip Channel */ + animchannelTypeInfo[type++] = &ACF_DSHAIR; /* Hair Channel */ + animchannelTypeInfo[type++] = &ACF_DSPOINTCLOUD; /* PointCloud Channel */ + animchannelTypeInfo[type++] = &ACF_DSVOLUME; /* Volume 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 8b5e22db61a..791545f216a 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -135,7 +135,10 @@ void ANIM_set_active_channel(bAnimContext *ac, case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: case ANIMTYPE_DSGPENCIL: - case ANIMTYPE_DSMCLIP: { + case ANIMTYPE_DSMCLIP: + case ANIMTYPE_DSHAIR: + case ANIMTYPE_DSPOINTCLOUD: + case ANIMTYPE_DSVOLUME: { /* need to verify that this data is valid for now */ if (ale->adt) { ACHANNEL_SET_FLAG(ale->adt, ACHANNEL_SETFLAG_CLEAR, ADT_UI_ACTIVE); @@ -188,7 +191,10 @@ void ANIM_set_active_channel(bAnimContext *ac, case ANIMTYPE_DSNTREE: case ANIMTYPE_DSTEX: case ANIMTYPE_DSGPENCIL: - case ANIMTYPE_DSMCLIP: { + case ANIMTYPE_DSMCLIP: + case ANIMTYPE_DSHAIR: + case ANIMTYPE_DSPOINTCLOUD: + case ANIMTYPE_DSVOLUME: { /* need to verify that this data is valid for now */ if (ale && ale->adt) { ale->adt->flag |= ADT_UI_ACTIVE; @@ -323,7 +329,10 @@ void ANIM_deselect_anim_channels( case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: case ANIMTYPE_DSGPENCIL: - case ANIMTYPE_DSMCLIP: { + case ANIMTYPE_DSMCLIP: + case ANIMTYPE_DSHAIR: + case ANIMTYPE_DSPOINTCLOUD: + case ANIMTYPE_DSVOLUME: { if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) { sel = ACHANNEL_SETFLAG_CLEAR; } @@ -416,7 +425,10 @@ void ANIM_deselect_anim_channels( case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: case ANIMTYPE_DSGPENCIL: - case ANIMTYPE_DSMCLIP: { + case ANIMTYPE_DSMCLIP: + case ANIMTYPE_DSHAIR: + case ANIMTYPE_DSPOINTCLOUD: + case ANIMTYPE_DSVOLUME: { /* need to verify that this data is valid for now */ if (ale->adt) { ACHANNEL_SET_FLAG(ale->adt, sel, ADT_UI_SELECTED); @@ -2949,7 +2961,10 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index, case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: case ANIMTYPE_DSGPENCIL: - case ANIMTYPE_DSMCLIP: { + case ANIMTYPE_DSMCLIP: + case ANIMTYPE_DSHAIR: + case ANIMTYPE_DSPOINTCLOUD: + case ANIMTYPE_DSVOLUME: { /* sanity checking... */ if (ale->adt) { /* select/deselect */ diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 8dfc9cd8d1a..0895bd4f8a2 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -46,6 +46,7 @@ #include "DNA_armature_types.h" #include "DNA_camera_types.h" #include "DNA_cachefile_types.h" +#include "DNA_hair_types.h" #include "DNA_light_types.h" #include "DNA_lattice_types.h" #include "DNA_linestyle_types.h" @@ -58,11 +59,13 @@ #include "DNA_node_types.h" #include "DNA_object_force_types.h" #include "DNA_particle_types.h" +#include "DNA_pointcloud_types.h" #include "DNA_space_types.h" #include "DNA_sequence_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_speaker_types.h" +#include "DNA_volume_types.h" #include "DNA_world_types.h" #include "DNA_gpencil_types.h" #include "DNA_brush_types.h" @@ -787,6 +790,42 @@ static bAnimListElem *make_new_animlistelem(void *data, ale->adt = BKE_animdata_from_id(data); break; } + case ANIMTYPE_DSHAIR: { + Hair *hair = (Hair *)data; + AnimData *adt = hair->adt; + + ale->flag = FILTER_HAIR_OBJD(hair); + + ale->key_data = (adt) ? adt->action : NULL; + ale->datatype = ALE_ACT; + + ale->adt = BKE_animdata_from_id(data); + break; + } + case ANIMTYPE_DSPOINTCLOUD: { + PointCloud *pointcloud = (PointCloud *)data; + AnimData *adt = pointcloud->adt; + + ale->flag = FILTER_POINTS_OBJD(pointcloud); + + ale->key_data = (adt) ? adt->action : NULL; + ale->datatype = ALE_ACT; + + ale->adt = BKE_animdata_from_id(data); + break; + } + case ANIMTYPE_DSVOLUME: { + Volume *volume = (Volume *)data; + AnimData *adt = volume->adt; + + ale->flag = FILTER_VOLUME_OBJD(volume); + + ale->key_data = (adt) ? adt->action : NULL; + ale->datatype = ALE_ACT; + + ale->adt = BKE_animdata_from_id(data); + break; + } case ANIMTYPE_DSSKEY: { Key *key = (Key *)data; AnimData *adt = key->adt; @@ -2544,6 +2583,39 @@ static size_t animdata_filter_ds_obdata( expanded = FILTER_SPK_OBJD(spk); break; } + case OB_HAIR: /* ---------- Hair ----------- */ + { + Hair *hair = (Hair *)ob->data; + + if (ads->filterflag2 & ADS_FILTER_NOHAIR) + return 0; + + type = ANIMTYPE_DSHAIR; + expanded = FILTER_HAIR_OBJD(hair); + break; + } + case OB_POINTCLOUD: /* ---------- PointCloud ----------- */ + { + PointCloud *pointcloud = (PointCloud *)ob->data; + + if (ads->filterflag2 & ADS_FILTER_NOPOINTCLOUD) + return 0; + + type = ANIMTYPE_DSPOINTCLOUD; + expanded = FILTER_POINTS_OBJD(pointcloud); + break; + } + case OB_VOLUME: /* ---------- Volume ----------- */ + { + Volume *volume = (Volume *)ob->data; + + if (ads->filterflag2 & ADS_FILTER_NOVOLUME) + return 0; + + type = ANIMTYPE_DSVOLUME; + expanded = FILTER_VOLUME_OBJD(volume); + break; + } } /* add object data animation channels */ diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 2e810297138..7f4c3470020 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -226,6 +226,9 @@ typedef enum eAnim_ChannelType { ANIMTYPE_DSSPK, ANIMTYPE_DSGPENCIL, ANIMTYPE_DSMCLIP, + ANIMTYPE_DSHAIR, + ANIMTYPE_DSPOINTCLOUD, + ANIMTYPE_DSVOLUME, ANIMTYPE_SHAPEKEY, @@ -350,6 +353,9 @@ typedef enum eAnimFilter_Flags { #define FILTER_MESH_OBJD(me) (CHECK_TYPE_INLINE(me, Mesh *), ((me->flag & ME_DS_EXPAND))) #define FILTER_LATTICE_OBJD(lt) (CHECK_TYPE_INLINE(lt, Lattice *), ((lt->flag & LT_DS_EXPAND))) #define FILTER_SPK_OBJD(spk) (CHECK_TYPE_INLINE(spk, Speaker *), ((spk->flag & SPK_DS_EXPAND))) +#define FILTER_HAIR_OBJD(ha) (CHECK_TYPE_INLINE(ha, Hair *), ((ha->flag & HA_DS_EXPAND))) +#define FILTER_POINTS_OBJD(pt) (CHECK_TYPE_INLINE(pt, PointCloud *), ((pt->flag & PT_DS_EXPAND))) +#define FILTER_VOLUME_OBJD(vo) (CHECK_TYPE_INLINE(vo, Volume *), ((vo->flag & VO_DS_EXPAND))) /* Variable use expanders */ #define FILTER_NTREE_DATA(ntree) \ (CHECK_TYPE_INLINE(ntree, bNodeTree *), ((ntree->flag & NTREE_DS_EXPAND))) diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 6739f7cb12c..6fdef4a06e0 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -745,21 +745,22 @@ DEF_ICON_BLANK(252b) DEF_ICON_BLANK(252c) DEF_ICON(LAYER_USED) DEF_ICON(LAYER_ACTIVE) -/* available */ DEF_ICON_BLANK(254) DEF_ICON_BLANK(255) DEF_ICON_BLANK(256) DEF_ICON_BLANK(257) DEF_ICON_BLANK(257b) -DEF_ICON_BLANK(258) -DEF_ICON_BLANK(259) -DEF_ICON_BLANK(260) -DEF_ICON_BLANK(261) -DEF_ICON_BLANK(262) -DEF_ICON_BLANK(263) -DEF_ICON_BLANK(264) -DEF_ICON_BLANK(265) -DEF_ICON_BLANK(266) + +/* ADDITIONAL OBJECT TYPES */ +DEF_ICON_OBJECT(OUTLINER_OB_HAIR) +DEF_ICON_OBJECT_DATA(OUTLINER_DATA_HAIR) +DEF_ICON_OBJECT_DATA(HAIR_DATA) +DEF_ICON_OBJECT(OUTLINER_OB_POINTCLOUD) +DEF_ICON_OBJECT_DATA(OUTLINER_DATA_POINTCLOUD) +DEF_ICON_OBJECT_DATA(POINTCLOUD_DATA) +DEF_ICON_OBJECT(OUTLINER_OB_VOLUME) +DEF_ICON_OBJECT_DATA(OUTLINER_DATA_VOLUME) +DEF_ICON_OBJECT_DATA(VOLUME_DATA) DEF_ICON_BLANK(267) DEF_ICON_BLANK(268) DEF_ICON_BLANK(269) diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index a37b49f5b6e..ed4131440d5 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -2340,6 +2340,12 @@ int UI_idcode_icon_get(const int idcode) return ICON_TEXT; case ID_VF: return ICON_FONT_DATA; + case ID_HA: + return ICON_HAIR_DATA; + case ID_PT: + return ICON_POINTCLOUD_DATA; + case ID_VO: + return ICON_VOLUME_DATA; case ID_WO: return ICON_WORLD_DATA; case ID_WS: diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index f11e3a1f5f0..cb55c639d91 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -668,6 +668,12 @@ static const char *template_id_browse_tip(const StructRNA *type) return N_("Browse Workspace to be linked"); case ID_LP: return N_("Browse LightProbe to be linked"); + case ID_HA: + return N_("Browse Hair Data to be linked"); + case ID_PT: + return N_("Browse Point Cloud Data to be linked"); + case ID_VO: + return N_("Browse Volume Data to be linked"); } } return N_("Browse ID data to be linked"); @@ -730,7 +736,13 @@ static uiBut *template_id_def_new_but(uiBlock *block, BLT_I18NCONTEXT_ID_GPENCIL, BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE, BLT_I18NCONTEXT_ID_WORKSPACE, - BLT_I18NCONTEXT_ID_LIGHTPROBE, ); + BLT_I18NCONTEXT_ID_LIGHTPROBE, + BLT_I18NCONTEXT_ID_HAIR, + BLT_I18NCONTEXT_ID_POINTCLOUD, + BLT_I18NCONTEXT_ID_VOLUME, ); + /* Note: BLT_I18N_MSGID_MULTI_CTXT takes a maximum number of parameters, + * check the definition to see if a new call must be added when the limit + * is exceeded. */ if (newop) { but = uiDefIconTextButO(block, diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 69abe475fed..a5b6fa55aa9 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -65,6 +65,7 @@ set(SRC object_transform.c object_utils.c object_vgroup.c + object_volume.c object_warp.c object_intern.h @@ -88,4 +89,8 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() +if(WITH_NEW_OBJECT_TYPES) + add_definitions(-DWITH_NEW_OBJECT_TYPES) +endif() + blender_add_lib(bf_editor_object "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 17b6bfdb956..832854ec4cc 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -65,6 +65,7 @@ #include "BKE_effect.h" #include "BKE_font.h" #include "BKE_gpencil.h" +#include "BKE_hair.h" #include "BKE_key.h" #include "BKE_light.h" #include "BKE_lattice.h" @@ -81,9 +82,11 @@ #include "BKE_nla.h" #include "BKE_object.h" #include "BKE_particle.h" +#include "BKE_pointcloud.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_speaker.h" +#include "BKE_volume.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -1459,9 +1462,82 @@ void OBJECT_OT_speaker_add(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Delete Object Operator +/** \name Add Hair Operator + * \{ */ + +static int object_hair_add_exec(bContext *C, wmOperator *op) +{ + ushort local_view_bits; + float loc[3], rot[3]; + + if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &local_view_bits, NULL)) { + return OPERATOR_CANCELLED; + } + Object *object = ED_object_add_type(C, OB_HAIR, NULL, loc, rot, false, local_view_bits); + object->dtx |= OB_DRAWBOUNDOX; /* TODO: remove once there is actual drawing. */ + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_hair_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Hair"; + ot->description = "Add a hair object to the scene"; + ot->idname = "OBJECT_OT_hair_add"; + + /* api callbacks */ + ot->exec = object_hair_add_exec; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ED_object_add_generic_props(ot, false); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Add Point Cloud Operator * \{ */ +static int object_pointcloud_add_exec(bContext *C, wmOperator *op) +{ + ushort local_view_bits; + float loc[3], rot[3]; + + if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &local_view_bits, NULL)) { + return OPERATOR_CANCELLED; + } + Object *object = ED_object_add_type(C, OB_POINTCLOUD, NULL, loc, rot, false, local_view_bits); + object->dtx |= OB_DRAWBOUNDOX; /* TODO: remove once there is actual drawing. */ + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_pointcloud_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Point Cloud"; + ot->description = "Add a point cloud object to the scene"; + ot->idname = "OBJECT_OT_pointcloud_add"; + + /* api callbacks */ + ot->exec = object_pointcloud_add_exec; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ED_object_add_generic_props(ot, false); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Delete Object Operator + * \{ */ /* remove base from a specific scene */ /* note: now unlinks constraints as well */ void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 352ba744d92..c1cb0d6cef0 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -111,6 +111,8 @@ void OBJECT_OT_light_add(struct wmOperatorType *ot); void OBJECT_OT_effector_add(struct wmOperatorType *ot); void OBJECT_OT_camera_add(struct wmOperatorType *ot); void OBJECT_OT_speaker_add(struct wmOperatorType *ot); +void OBJECT_OT_hair_add(struct wmOperatorType *ot); +void OBJECT_OT_pointcloud_add(struct wmOperatorType *ot); void OBJECT_OT_collection_instance_add(struct wmOperatorType *ot); void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot); @@ -120,6 +122,10 @@ void OBJECT_OT_join(struct wmOperatorType *ot); void OBJECT_OT_join_shapes(struct wmOperatorType *ot); void OBJECT_OT_convert(struct wmOperatorType *ot); +/* object_volume.c */ +void OBJECT_OT_volume_add(struct wmOperatorType *ot); +void OBJECT_OT_volume_import(struct wmOperatorType *ot); + /* object_hook.c */ void OBJECT_OT_hook_add_selob(struct wmOperatorType *ot); void OBJECT_OT_hook_add_newob(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 31c4f96693c..7c74213608c 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -53,6 +53,7 @@ #include "BKE_effect.h" #include "BKE_global.h" #include "BKE_gpencil_modifier.h" +#include "BKE_hair.h" #include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_lib_id.h" @@ -67,9 +68,11 @@ #include "BKE_ocean.h" #include "BKE_paint.h" #include "BKE_particle.h" +#include "BKE_pointcloud.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_softbody.h" +#include "BKE_volume.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -114,6 +117,15 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object * else if (ob->type == OB_GPENCIL) { BKE_gpencil_modifiers_calc(depsgraph, scene_eval, ob_eval); } + else if (ob->type == OB_HAIR) { + BKE_hair_data_update(depsgraph, scene_eval, ob); + } + else if (ob->type == OB_POINTCLOUD) { + BKE_pointcloud_data_update(depsgraph, scene_eval, ob); + } + else if (ob->type == OB_VOLUME) { + BKE_volume_data_update(depsgraph, scene_eval, ob); + } } static void object_force_modifier_bind_simple_options(Depsgraph *depsgraph, @@ -654,6 +666,7 @@ static int modifier_apply_shape(Main *bmain, BKE_id_free(NULL, mesh_applied); } else { + /* TODO: implement for hair, pointclouds and volumes. */ BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); return 0; } @@ -732,6 +745,7 @@ static int modifier_apply_obdata( DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); } else { + /* TODO: implement for hair, pointclouds and volumes. */ BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); return 0; } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index f6b08b953a4..52273b887dd 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -109,6 +109,12 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_light_add); WM_operatortype_append(OBJECT_OT_camera_add); WM_operatortype_append(OBJECT_OT_speaker_add); +#ifdef WITH_NEW_OBJECT_TYPES + WM_operatortype_append(OBJECT_OT_hair_add); + WM_operatortype_append(OBJECT_OT_pointcloud_add); +#endif + WM_operatortype_append(OBJECT_OT_volume_add); + WM_operatortype_append(OBJECT_OT_volume_import); WM_operatortype_append(OBJECT_OT_add); WM_operatortype_append(OBJECT_OT_add_named); WM_operatortype_append(OBJECT_OT_effector_add); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 29bf9e88853..836e3bf7a44 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -66,6 +66,7 @@ #include "BKE_editmesh.h" #include "BKE_gpencil.h" #include "BKE_fcurve.h" +#include "BKE_hair.h" #include "BKE_idprop.h" #include "BKE_light.h" #include "BKE_lattice.h" @@ -82,10 +83,12 @@ #include "BKE_modifier.h" #include "BKE_node.h" #include "BKE_object.h" +#include "BKE_pointcloud.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_speaker.h" #include "BKE_texture.h" +#include "BKE_volume.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -1900,6 +1903,15 @@ static void single_obdata_users( case OB_GPENCIL: ob->data = ID_NEW_SET(ob->data, BKE_gpencil_copy(bmain, ob->data)); break; + case OB_HAIR: + ob->data = ID_NEW_SET(ob->data, BKE_hair_copy(bmain, ob->data)); + break; + case OB_POINTCLOUD: + ob->data = ID_NEW_SET(ob->data, BKE_pointcloud_copy(bmain, ob->data)); + break; + case OB_VOLUME: + ob->data = ID_NEW_SET(ob->data, BKE_volume_copy(bmain, ob->data)); + break; default: printf("ERROR %s: can't copy %s\n", __func__, id->name); BLI_assert(!"This should never happen."); diff --git a/source/blender/editors/object/object_volume.c b/source/blender/editors/object/object_volume.c new file mode 100644 index 00000000000..64482a0bcf6 --- /dev/null +++ b/source/blender/editors/object/object_volume.c @@ -0,0 +1,193 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup edobj + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_fileops.h" +#include "BLI_listbase.h" +#include "BLI_math_base.h" +#include "BLI_path_util.h" +#include "BLI_string.h" + +#include "DNA_object_types.h" +#include "DNA_volume_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "BKE_context.h" +#include "BKE_lib_id.h" +#include "BKE_main.h" +#include "BKE_report.h" +#include "BKE_volume.h" + +#include "WM_types.h" +#include "WM_api.h" + +#include "ED_image.h" +#include "ED_object.h" +#include "ED_screen.h" + +#include "object_intern.h" + +/* Volume Add */ + +static Object *object_volume_add(bContext *C, wmOperator *op, const char *name) +{ + ushort local_view_bits; + float loc[3], rot[3]; + + if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &local_view_bits, NULL)) { + return false; + } + return ED_object_add_type(C, OB_VOLUME, name, loc, rot, false, local_view_bits); +} + +static int object_volume_add_exec(bContext *C, wmOperator *op) +{ + return (object_volume_add(C, op, NULL) != NULL) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; +} + +void OBJECT_OT_volume_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Volume"; + ot->description = "Add a volume object to the scene"; + ot->idname = "OBJECT_OT_volume_add"; + + /* api callbacks */ + ot->exec = object_volume_add_exec; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ED_object_add_generic_props(ot, false); +} + +/* Volume Import */ + +static int volume_import_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); + bool imported = false; + + ListBase ranges = ED_image_filesel_detect_sequences(bmain, op, false); + for (ImageFrameRange *range = ranges.first; range; range = range->next) { + char filename[FILE_MAX]; + BLI_split_file_part(range->filepath, filename, sizeof(filename)); + BLI_path_extension_replace(filename, sizeof(filename), ""); + + Object *object = object_volume_add(C, op, filename); + Volume *volume = (Volume *)object->data; + + STRNCPY(volume->filepath, range->filepath); + if (is_relative_path) { + BLI_path_rel(volume->filepath, BKE_main_blendfile_path(bmain)); + } + + volume->is_sequence = (range->length > 1); + volume->frame_duration = (volume->is_sequence) ? range->length : 0; + volume->frame_start = 1; + volume->frame_offset = (volume->is_sequence) ? range->offset - 1 : 0; + + if (!BKE_volume_load(volume, bmain)) { + BKE_reportf(op->reports, + RPT_WARNING, + "Volume \"%s\" failed to load: %s", + filename, + BKE_volume_grids_error_msg(volume)); + BKE_id_delete(bmain, &object->id); + BKE_id_delete(bmain, &volume->id); + continue; + } + else if (BKE_volume_is_points_only(volume)) { + BKE_reportf(op->reports, + RPT_WARNING, + "Volume \"%s\" contains points, only voxel grids are supported", + filename); + BKE_id_delete(bmain, &object->id); + BKE_id_delete(bmain, &volume->id); + continue; + } + + if (BKE_volume_is_y_up(volume)) { + object->rot[0] += M_PI_2; + } + + imported = true; + } + BLI_freelistN(&ranges); + + return (imported) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; +} + +static int volume_import_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (RNA_struct_property_is_set(op->ptr, "filepath")) { + return volume_import_exec(C, op); + } + + RNA_string_set(op->ptr, "filepath", U.textudir); + WM_event_add_fileselect(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +/* called by other space types too */ +void OBJECT_OT_volume_import(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Import OpenVDB Volume"; + ot->description = "Import OpenVDB volume file"; + ot->idname = "OBJECT_OT_volume_import"; + + /* api callbacks */ + ot->exec = volume_import_exec; + ot->invoke = volume_import_invoke; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_filesel(ot, + FILE_TYPE_FOLDER | FILE_TYPE_VOLUME, + FILE_SPECIAL, + FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES | + WM_FILESEL_RELPATH, + FILE_DEFAULTDISPLAY, + FILE_SORT_ALPHA); + + RNA_def_boolean( + ot->srna, + "use_sequence_detection", + true, + "Detect Sequences", + "Automatically detect animated sequences in selected volume files (based on file names)"); + + ED_object_add_generic_props(ot, false); +} diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 4fa1903758f..c48d5917ec2 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -628,6 +628,9 @@ static int gather_frames_to_render_for_id(LibraryIDLinkCallbackData *cb_data) case ID_MC: /* MovieClip */ case ID_MSK: /* Mask */ case ID_LP: /* LightProbe */ + case ID_HA: /* Hair */ + case ID_PT: /* PointCloud */ + case ID_VO: /* Volume */ break; /* Blacklist: */ diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index 25ff6bbd098..c3b7d65689f 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -54,4 +54,8 @@ if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() +if(WITH_NEW_OBJECT_TYPES) + add_definitions(-DWITH_NEW_OBJECT_TYPES) +endif() + blender_add_lib(bf_editor_space_buttons "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 035239cc7d0..21dfb3df771 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -251,6 +251,17 @@ static int buttons_context_path_data(ButsContextPath *path, int type) else if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) { return 1; } +#ifdef WITH_NEW_OBJECT_TYPES + else if (RNA_struct_is_a(ptr->type, &RNA_Hair) && (type == -1 || type == OB_HAIR)) { + return 1; + } + else if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) { + return 1; + } +#endif + else if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) { + return 1; + } /* try to get an object in the path, no pinning supported here */ else if (buttons_context_path_object(path)) { ob = path->ptr[path->len - 1].data; @@ -274,7 +285,16 @@ static int buttons_context_path_modifier(ButsContextPath *path) if (buttons_context_path_object(path)) { ob = path->ptr[path->len - 1].data; - if (ob && ELEM(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_LATTICE, OB_GPENCIL)) { + if (ob && ELEM(ob->type, + OB_MESH, + OB_CURVE, + OB_FONT, + OB_SURF, + OB_LATTICE, + OB_GPENCIL, + OB_HAIR, + OB_POINTCLOUD, + OB_VOLUME)) { return 1; } } @@ -776,6 +796,11 @@ const char *buttons_context_dir[] = { "line_style", "collection", "gpencil", +#ifdef WITH_NEW_OBJECT_TYPES + "hair", + "pointcloud", +#endif + "volume", NULL, }; @@ -853,6 +878,20 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r set_pointer_type(path, result, &RNA_LightProbe); return 1; } +#ifdef WITH_NEW_OBJECT_TYPES + else if (CTX_data_equals(member, "hair")) { + set_pointer_type(path, result, &RNA_Hair); + return 1; + } + else if (CTX_data_equals(member, "pointcloud")) { + set_pointer_type(path, result, &RNA_PointCloud); + return 1; + } +#endif + else if (CTX_data_equals(member, "volume")) { + set_pointer_type(path, result, &RNA_Volume); + return 1; + } else if (CTX_data_equals(member, "material")) { set_pointer_type(path, result, &RNA_Material); return 1; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 188f3417ddc..1fc0866bd9f 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1080,6 +1080,9 @@ static int filelist_geticon_ex(FileDirEntry *file, else if (typeflag & FILE_TYPE_USD) { return ICON_FILE_3D; } + else if (typeflag & FILE_TYPE_VOLUME) { + return ICON_FILE_VOLUME; + } else if (typeflag & FILE_TYPE_OBJECT_IO) { return ICON_FILE_3D; } @@ -2236,6 +2239,9 @@ int ED_path_extension_type(const char *path) else if (BLI_path_extension_check_n(path, ".usd", ".usda", ".usdc", NULL)) { return FILE_TYPE_USD; } + else if (BLI_path_extension_check(path, ".vdb")) { + return FILE_TYPE_VOLUME; + } else if (BLI_path_extension_check(path, ".zip")) { return FILE_TYPE_ARCHIVE; } @@ -2298,6 +2304,8 @@ int ED_file_extension_icon(const char *path) return ICON_FILE_TEXT; case FILE_TYPE_ARCHIVE: return ICON_FILE_ARCHIVE; + case FILE_TYPE_VOLUME: + return ICON_FILE_VOLUME; default: return ICON_FILE_BLANK; } @@ -2625,9 +2633,9 @@ static void filelist_readjob_main_rec(Main *bmain, FileList *filelist) if (filelist->dir[0] == 0) { /* make directories */ # ifdef WITH_FREESTYLE - filelist->filelist.nbr_entries = 24; + filelist->filelist.nbr_entries = 27; # else - filelist->filelist.nbr_entries = 23; + filelist->filelist.nbr_entries = 26; # endif filelist_resize(filelist, filelist->filelist.nbr_entries); @@ -2658,8 +2666,11 @@ static void filelist_readjob_main_rec(Main *bmain, FileList *filelist) filelist->filelist.entries[20].entry->relpath = BLI_strdup("Action"); filelist->filelist.entries[21].entry->relpath = BLI_strdup("NodeTree"); filelist->filelist.entries[22].entry->relpath = BLI_strdup("Speaker"); + filelist->filelist.entries[23].entry->relpath = BLI_strdup("Hair"); + filelist->filelist.entries[24].entry->relpath = BLI_strdup("Point Cloud"); + filelist->filelist.entries[25].entry->relpath = BLI_strdup("Volume"); # ifdef WITH_FREESTYLE - filelist->filelist.entries[23].entry->relpath = BLI_strdup("FreestyleLineStyle"); + filelist->filelist.entries[26].entry->relpath = BLI_strdup("FreestyleLineStyle"); # endif } else { diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index d07db12eeac..6c0f79f0f5c 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -218,6 +218,9 @@ short ED_fileselect_set_params(SpaceFile *sfile) if ((prop = RNA_struct_find_property(op->ptr, "filter_usd"))) { params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_USD : 0; } + if ((prop = RNA_struct_find_property(op->ptr, "filter_volume"))) { + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_VOLUME : 0; + } if ((prop = RNA_struct_find_property(op->ptr, "filter_glob"))) { /* Protection against pyscripts not setting proper size limit... */ char *tmp = RNA_property_string_get_alloc( diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index d00083d343b..dd74e1a8ccc 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -204,6 +204,11 @@ static void stats_object(Object *ob, SceneStats *stats, GSet *objects_gset) } break; } + case OB_HAIR: + case OB_POINTCLOUD: + case OB_VOLUME: { + break; + } } } diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 4277e579274..315fa1d12aa 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -140,7 +140,10 @@ bool nla_panel_context(const bContext *C, case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: case ANIMTYPE_DSGPENCIL: - case ANIMTYPE_PALETTE: { + case ANIMTYPE_PALETTE: + case ANIMTYPE_DSHAIR: + case ANIMTYPE_DSPOINTCLOUD: + case ANIMTYPE_DSVOLUME: { /* for these channels, we only do AnimData */ if (ale->adt && adt_ptr) { ID *id; diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index cf3e889b26c..b97267dc2a8 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -190,7 +190,10 @@ static int mouse_nla_channels( case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: case ANIMTYPE_DSGPENCIL: - case ANIMTYPE_PALETTE: { + case ANIMTYPE_PALETTE: + case ANIMTYPE_DSHAIR: + case ANIMTYPE_DSPOINTCLOUD: + case ANIMTYPE_DSVOLUME: { /* sanity checking... */ if (ale->adt) { /* select/deselect */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index f679bcc4e15..677a7cac745 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -446,8 +446,17 @@ void ED_node_shader_default(const bContext *C, ID *id) if (GS(id->name) == ID_MA) { /* Materials */ + Object *ob = CTX_data_active_object(C); Material *ma = (Material *)id; - Material *ma_default = BKE_material_default_surface(); + Material *ma_default; + + if (ob && ob->type == OB_VOLUME) { + ma_default = BKE_material_default_volume(); + } + else { + ma_default = BKE_material_default_surface(); + } + ma->nodetree = ntreeCopyTree(bmain, ma_default->nodetree); ntreeUpdateTree(bmain, ma->nodetree); } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 1b34f85f800..83ddbe63e9c 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -2418,6 +2418,15 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) case OB_LIGHTPROBE: data.icon = ICON_OUTLINER_OB_LIGHTPROBE; break; + case OB_HAIR: + data.icon = ICON_OUTLINER_OB_HAIR; + break; + case OB_POINTCLOUD: + data.icon = ICON_OUTLINER_OB_POINTCLOUD; + break; + case OB_VOLUME: + data.icon = ICON_OUTLINER_OB_VOLUME; + break; case OB_EMPTY: if (ob->instance_collection && (ob->transflag & OB_DUPLICOLLECTION)) { data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE; @@ -2515,6 +2524,15 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) case ID_GR: data.icon = ICON_GROUP; break; + case ID_HA: + data.icon = ICON_OUTLINER_DATA_HAIR; + break; + case ID_PT: + data.icon = ICON_OUTLINER_DATA_POINTCLOUD; + break; + case ID_VO: + data.icon = ICON_OUTLINER_DATA_VOLUME; + break; case ID_LI: if (tselem->id->tag & LIB_TAG_MISSING) { data.icon = ICON_LIBRARY_DATA_BROKEN; diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 1d39dc156b2..fb40ae195ef 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -105,7 +105,10 @@ typedef struct TreeElementIcon { ID_PA, \ ID_GD, \ ID_LS, \ - ID_LP) || /* Only in 'blendfile' mode ... :/ */ \ + ID_LP, \ + ID_HA, \ + ID_PT, \ + ID_VO) || /* Only in 'blendfile' mode ... :/ */ \ ELEM(GS((_id)->name), \ ID_SCR, \ ID_WM, \ diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index a99e1b63119..5bb0d626c2f 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -27,13 +27,16 @@ #include "DNA_armature_types.h" #include "DNA_collection_types.h" #include "DNA_gpencil_types.h" +#include "DNA_hair_types.h" #include "DNA_light_types.h" #include "DNA_linestyle_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meta_types.h" +#include "DNA_pointcloud_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_volume_types.h" #include "DNA_world_types.h" #include "DNA_object_types.h" #include "DNA_constraint_types.h" @@ -153,6 +156,9 @@ static void set_operation_types(SpaceOutliner *soops, case ID_CF: case ID_WS: case ID_LP: + case ID_HA: + case ID_PT: + case ID_VO: is_standard_id = true; break; case ID_WM: @@ -230,6 +236,21 @@ static void unlink_material_cb(bContext *UNUSED(C), totcol = mb->totcol; matar = mb->mat; } + else if (GS(tsep->id->name) == ID_HA) { + Hair *hair = (Hair *)tsep->id; + totcol = hair->totcol; + matar = hair->mat; + } + else if (GS(tsep->id->name) == ID_PT) { + PointCloud *pointcloud = (PointCloud *)tsep->id; + totcol = pointcloud->totcol; + matar = pointcloud->mat; + } + else if (GS(tsep->id->name) == ID_VO) { + Volume *volume = (Volume *)tsep->id; + totcol = volume->totcol; + matar = volume->mat; + } else { BLI_assert(0); } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index b8cbb6bb0e3..b942021ca33 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -33,6 +33,7 @@ #include "DNA_cachefile_types.h" #include "DNA_collection_types.h" #include "DNA_gpencil_types.h" +#include "DNA_hair_types.h" #include "DNA_key_types.h" #include "DNA_light_types.h" #include "DNA_material_types.h" @@ -40,7 +41,9 @@ #include "DNA_meta_types.h" #include "DNA_lightprobe_types.h" #include "DNA_particle_types.h" +#include "DNA_pointcloud_types.h" #include "DNA_scene_types.h" +#include "DNA_volume_types.h" #include "DNA_world_types.h" #include "DNA_sequence_types.h" #include "DNA_speaker_types.h" @@ -750,6 +753,25 @@ static void outliner_add_id_contents(SpaceOutliner *soops, Collection *collection = (Collection *)id; outliner_add_collection_recursive(soops, collection, te); } + break; + } + case ID_HA: { + Hair *hair = (Hair *)id; + if (outliner_animdata_test(hair->adt)) + outliner_add_element(soops, &te->subtree, hair, te, TSE_ANIM_DATA, 0); + break; + } + case ID_PT: { + PointCloud *pointcloud = (PointCloud *)id; + if (outliner_animdata_test(pointcloud->adt)) + outliner_add_element(soops, &te->subtree, pointcloud, te, TSE_ANIM_DATA, 0); + break; + } + case ID_VO: { + Volume *volume = (Volume *)id; + if (outliner_animdata_test(volume->adt)) + outliner_add_element(soops, &te->subtree, volume, te, TSE_ANIM_DATA, 0); + break; } default: break; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index f16e19c598e..0f5607bc8cd 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -559,6 +559,14 @@ static bool view3d_ima_empty_drop_poll(bContext *C, return false; } +static bool view3d_volume_drop_poll(bContext *UNUSED(C), + wmDrag *drag, + const wmEvent *UNUSED(event), + const char **UNUSED(tooltip)) +{ + return (drag->type == WM_DRAG_PATH) && (drag->icon == ICON_FILE_VOLUME); +} + static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop) { ID *id = WM_drag_ID(drag, ID_OB); @@ -626,6 +634,7 @@ static void view3d_dropboxes(void) lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy); WM_dropbox_add( lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy); + WM_dropbox_add(lb, "OBJECT_OT_volume_import", view3d_volume_drop_poll, view3d_id_path_drop_copy); WM_dropbox_add(lb, "OBJECT_OT_collection_instance_add", view3d_collection_drop_poll, diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 9b02ea7238c..54f00b67898 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1591,8 +1591,8 @@ static void view3d_panel_transform(const bContext *C, Panel *pa) RNA_id_pointer_create(&ob->id, &obptr); v3d_transform_butsR(col, &obptr); - /* dimensions and editmode just happen to be the same checks */ - if (OB_TYPE_SUPPORT_EDITMODE(ob->type)) { + /* Dimensions and editmode are mostly the same check. */ + if (OB_TYPE_SUPPORT_EDITMODE(ob->type) || ELEM(ob->type, OB_VOLUME, OB_HAIR, OB_POINTCLOUD)) { View3D *v3d = CTX_wm_view3d(C); v3d_object_dimension_buts(NULL, col, v3d, ob); } |