diff options
Diffstat (limited to 'source/blender/editors/space_view3d/space_view3d.c')
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 611 |
1 files changed, 319 insertions, 292 deletions
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 833d54efd75..4f960959abf 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -43,31 +43,40 @@ #include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" +#include "BKE_curve.h" #include "BKE_icons.h" +#include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_mball.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_scene.h" #include "BKE_screen.h" +#include "BKE_workspace.h" #include "ED_space_api.h" #include "ED_screen.h" +#include "ED_transform.h" -#include "GPU_compositing.h" #include "GPU_framebuffer.h" #include "GPU_material.h" +#include "GPU_viewport.h" +#include "GPU_matrix.h" -#include "BIF_gl.h" +#include "DRW_engine.h" #include "WM_api.h" #include "WM_types.h" +#include "WM_message.h" +#include "WM_toolsystem.h" #include "RE_engine.h" #include "RE_pipeline.h" #include "RNA_access.h" +#include "UI_interface.h" #include "UI_resources.h" #ifdef WITH_PYTHON @@ -106,17 +115,17 @@ ARegion *view3d_has_buttons_region(ScrArea *sa) ARegion *view3d_has_tools_region(ScrArea *sa) { - ARegion *ar, *artool = NULL, *arprops = NULL, *arhead; + ARegion *ar, *artool = NULL, *arhead; for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->regiontype == RGN_TYPE_TOOLS) artool = ar; - if (ar->regiontype == RGN_TYPE_TOOL_PROPS) - arprops = ar; } /* tool region hide/unhide also hides props */ - if (arprops && artool) return artool; + if (artool) { + return artool; + } if (artool == NULL) { /* add subdiv level; after header */ @@ -135,15 +144,6 @@ ARegion *view3d_has_tools_region(ScrArea *sa) artool->flag = RGN_FLAG_HIDDEN; } - if (arprops == NULL) { - /* add extra subdivided region for tool properties */ - arprops = MEM_callocN(sizeof(ARegion), "tool props for view3d"); - - BLI_insertlinkafter(&sa->regionbase, artool, arprops); - arprops->regiontype = RGN_TYPE_TOOL_PROPS; - arprops->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV; - } - return artool; } @@ -250,7 +250,7 @@ void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d) /* we have to multiply instead of loading viewmatob to make * it work with duplis using displists, otherwise it will * override the dupli-matrix */ - glMultMatrixf(ob->obmat); + gpuMultMatrix(ob->obmat); } #ifdef DEBUG @@ -283,8 +283,6 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar) BPy_END_ALLOW_THREADS; #endif - if (rv3d->render_engine->re) - RE_Database_Free(rv3d->render_engine->re); RE_engine_free(rv3d->render_engine); rv3d->render_engine = NULL; } @@ -298,17 +296,18 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa) ARegion *ar; for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->regiondata) + if ((ar->regiontype == RGN_TYPE_WINDOW) && ar->regiondata) { ED_view3d_stop_render_preview(wm, ar); + break; + } } } } /* ******************** default callbacks for view3d space ***************** */ -static SpaceLink *view3d_new(const bContext *C) +static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene) { - Scene *scene = CTX_data_scene(C); ARegion *ar; View3D *v3d; RegionView3D *rv3d; @@ -325,19 +324,31 @@ static SpaceLink *view3d_new(const bContext *C) v3d->gridlines = 16; v3d->gridsubdiv = 10; v3d->drawtype = OB_SOLID; + v3d->shading.flag = V3D_SHADING_SPECULAR_HIGHLIGHT; + v3d->shading.light = V3D_LIGHTING_STUDIO; + v3d->shading.shadow_intensity = 0.5f; + v3d->shading.xray_alpha = 0.5f; + v3d->shading.cavity_valley_factor = 1.0f; + v3d->shading.cavity_ridge_factor = 1.0f; + copy_v3_fl(v3d->shading.single_color, 0.8f); + + v3d->overlay.flag = V3D_OVERLAY_LOOK_DEV; + v3d->overlay.wireframe_threshold = 0.5f; + v3d->overlay.bone_selection_alpha = 0.5f; + v3d->overlay.texture_paint_mode_opacity = 0.8; + v3d->overlay.weight_paint_mode_opacity = 0.8; + v3d->overlay.vertex_paint_mode_opacity = 0.8; v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR; v3d->flag = V3D_SELECT_OUTLINE; v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL; - v3d->lens = 35.0f; + v3d->lens = 50.0f; v3d->near = 0.01f; v3d->far = 1000.0f; - v3d->twflag |= U.tw_flag & V3D_USE_MANIPULATOR; - v3d->twtype = V3D_MANIP_TRANSLATE; - v3d->around = V3D_AROUND_CENTER_MEAN; + v3d->twflag |= U.manipulator_flag & V3D_MANIPULATOR_DRAW; v3d->bundle_size = 0.2f; v3d->bundle_drawtype = OB_PLAINAXES; @@ -353,7 +364,7 @@ static SpaceLink *view3d_new(const bContext *C) BLI_addtail(&v3d->regionbase, ar); ar->regiontype = RGN_TYPE_HEADER; - ar->alignment = RGN_ALIGN_BOTTOM; + ar->alignment = RGN_ALIGN_TOP; /* tool shelf */ ar = MEM_callocN(sizeof(ARegion), "toolshelf for view3d"); @@ -363,14 +374,6 @@ static SpaceLink *view3d_new(const bContext *C) ar->alignment = RGN_ALIGN_LEFT; ar->flag = RGN_FLAG_HIDDEN; - /* tool properties */ - ar = MEM_callocN(sizeof(ARegion), "tool properties for view3d"); - - BLI_addtail(&v3d->regionbase, ar); - ar->regiontype = RGN_TYPE_TOOL_PROPS; - ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV; - ar->flag = RGN_FLAG_HIDDEN; - /* buttons/list view */ ar = MEM_callocN(sizeof(ARegion), "buttons for view3d"); @@ -399,30 +402,11 @@ static SpaceLink *view3d_new(const bContext *C) static void view3d_free(SpaceLink *sl) { View3D *vd = (View3D *) sl; - BGpic *bgpic; - - for (bgpic = vd->bgpicbase.first; bgpic; bgpic = bgpic->next) { - if (bgpic->source == V3D_BGPIC_IMAGE) { - id_us_min((ID *)bgpic->ima); - } - else if (bgpic->source == V3D_BGPIC_MOVIE) { - id_us_min((ID *)bgpic->clip); - } - } - BLI_freelistN(&vd->bgpicbase); if (vd->localvd) MEM_freeN(vd->localvd); if (vd->properties_storage) MEM_freeN(vd->properties_storage); - /* matcap material, its preview rect gets freed via icons */ - if (vd->defmaterial) { - if (vd->defmaterial->gpumaterial.first) - GPU_material_free(&vd->defmaterial->gpumaterial); - BKE_previewimg_free(&vd->defmaterial->preview); - MEM_freeN(vd->defmaterial); - } - if (vd->fx_settings.ssao) MEM_freeN(vd->fx_settings.ssao); if (vd->fx_settings.dof) @@ -440,7 +424,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) { View3D *v3do = (View3D *)sl; View3D *v3dn = MEM_dupallocN(sl); - BGpic *bgpic; /* clear or remove stuff from old */ @@ -455,18 +438,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) /* copy or clear inside new stuff */ - v3dn->defmaterial = NULL; - - BLI_duplicatelist(&v3dn->bgpicbase, &v3do->bgpicbase); - for (bgpic = v3dn->bgpicbase.first; bgpic; bgpic = bgpic->next) { - if (bgpic->source == V3D_BGPIC_IMAGE) { - id_us_plus((ID *)bgpic->ima); - } - else if (bgpic->source == V3D_BGPIC_MOVIE) { - id_us_plus((ID *)bgpic->clip); - } - } - v3dn->properties_storage = NULL; if (v3dn->fx_settings.dof) v3dn->fx_settings.dof = MEM_dupallocN(v3do->fx_settings.dof); @@ -482,6 +453,13 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar) ListBase *lb; wmKeyMap *keymap; + if (ar->manipulator_map == NULL) { + ar->manipulator_map = WM_manipulatormap_new_from_type( + &(const struct wmManipulatorMapType_Params) {SPACE_VIEW3D, RGN_TYPE_WINDOW}); + } + + WM_manipulatormap_add_handlers(ar, ar->manipulator_map); + /* object ops. */ /* important to be before Pose keymap since they can both be enabled at once */ @@ -572,11 +550,6 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar) GPU_offscreen_free(rv3d->gpuoffscreen); rv3d->gpuoffscreen = NULL; } - - if (rv3d->compositor) { - GPU_fx_compositor_destroy(rv3d->compositor); - rv3d->compositor = NULL; - } } static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) @@ -589,7 +562,7 @@ static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent return 0; } -static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static int view3d_collection_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_ID) { ID *id = drag->poin; @@ -664,7 +637,7 @@ static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop) RNA_string_set(drop->ptr, "name", id->name + 2); } -static void view3d_group_drop_copy(wmDrag *drag, wmDropBox *drop) +static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop) { ID *id = drag->poin; @@ -704,9 +677,32 @@ static void view3d_dropboxes(void) WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_mesh_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, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy); - WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy); + WM_dropbox_add(lb, "OBJECT_OT_collection_instance_add", view3d_collection_drop_poll, view3d_collection_drop_copy); } +static void view3d_widgets(void) +{ + wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure( + &(const struct wmManipulatorMapType_Params){SPACE_VIEW3D, RGN_TYPE_WINDOW}); + + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_spot); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_area); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_target); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_force_field); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera_view); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_empty_image); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_armature_spline); + + WM_manipulatorgrouptype_append(TRANSFORM_WGT_manipulator); + WM_manipulatorgrouptype_append(VIEW3D_WGT_xform_cage); + + WM_manipulatorgrouptype_append(VIEW3D_WGT_ruler); + WM_manipulatortype_append(VIEW3D_WT_ruler_item); + + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_navigate); + WM_manipulatortype_append(VIEW3D_WT_navigate_rotate); +} /* type callback, not region itself */ @@ -731,9 +727,6 @@ static void view3d_main_region_free(ARegion *ar) if (rv3d->gpuoffscreen) { GPU_offscreen_free(rv3d->gpuoffscreen); } - if (rv3d->compositor) { - GPU_fx_compositor_destroy(rv3d->compositor); - } MEM_freeN(rv3d); ar->regiondata = NULL; @@ -757,33 +750,21 @@ static void *view3d_main_region_duplicate(void *poin) new->render_engine = NULL; new->sms = NULL; new->smooth_timer = NULL; - new->compositor = NULL; return new; } return NULL; } -static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene) +static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, const Scene *UNUSED(scene)) { wmWindow *win = wmn->wm->winactive; - ScrArea *sa; unsigned int lay_used = 0; - Base *base; if (!win) return; - base = scene->base.first; - while (base) { - lay_used |= base->lay & ((1 << 20) - 1); /* ignore localview */ - - if (lay_used == (1 << 20) - 1) - break; - - base = base->next; - } - - for (sa = win->screen->areabase.first; sa; sa = sa->next) { + const bScreen *screen = WM_window_get_active_screen(win); + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { if (sa->spacetype == SPACE_VIEW3D) { if (BLI_findindex(&sa->regionbase, ar) != -1) { View3D *v3d = sa->spacedata.first; @@ -794,13 +775,21 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene } } -static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *wmn) +static void view3d_main_region_listener( + bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar, + wmNotifier *wmn, const Scene *scene) { - Scene *scene = sc->scene; View3D *v3d = sa->spacedata.first; + RegionView3D *rv3d = ar->regiondata; + wmManipulatorMap *mmap = ar->manipulator_map; /* context changes */ switch (wmn->category) { + case NC_WM: + if (ELEM(wmn->data, ND_UNDO)) { + WM_manipulatormap_tag_refresh(mmap); + } + break; case NC_ANIMATION: switch (wmn->data) { case ND_KEYFRAME_PROP: @@ -820,21 +809,31 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w break; case NC_SCENE: switch (wmn->data) { + case ND_SCENEBROWSE: case ND_LAYER_CONTENT: if (wmn->reference) view3d_recalc_used_layers(ar, wmn, wmn->reference); ED_region_tag_redraw(ar); + WM_manipulatormap_tag_refresh(mmap); + break; + case ND_LAYER: + if (wmn->reference) { + BKE_screen_view3d_sync(v3d, wmn->reference); + } + ED_region_tag_redraw(ar); + WM_manipulatormap_tag_refresh(mmap); break; - case ND_FRAME: - case ND_TRANSFORM: case ND_OB_ACTIVE: case ND_OB_SELECT: + ATTR_FALLTHROUGH; + case ND_FRAME: + case ND_TRANSFORM: case ND_OB_VISIBLE: - case ND_LAYER: case ND_RENDER_OPTIONS: case ND_MARKERS: case ND_MODE: ED_region_tag_redraw(ar); + WM_manipulatormap_tag_refresh(mmap); break; case ND_WORLD: /* handled by space_view3d_listener() for v3d access */ @@ -842,7 +841,6 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w case ND_DRAW_RENDER_VIEWPORT: { if (v3d->camera && (scene == wmn->reference)) { - RegionView3D *rv3d = ar->regiondata; if (rv3d->persp == RV3D_CAMOB) { ED_region_tag_redraw(ar); } @@ -867,6 +865,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w case ND_POINTCACHE: case ND_LOD: ED_region_tag_redraw(ar); + WM_manipulatormap_tag_refresh(mmap); break; } switch (wmn->action) { @@ -877,9 +876,13 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w break; case NC_GEOM: switch (wmn->data) { + case ND_SELECT: + { + WM_manipulatormap_tag_refresh(mmap); + ATTR_FALLTHROUGH; + } case ND_DATA: case ND_VERTEX_GROUP: - case ND_SELECT: ED_region_tag_redraw(ar); break; } @@ -894,7 +897,6 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w case ND_DRAW_RENDER_VIEWPORT: { if (v3d->camera && (v3d->camera->data == wmn->reference)) { - RegionView3D *rv3d = ar->regiondata; if (rv3d->persp == RV3D_CAMOB) { ED_region_tag_redraw(ar); } @@ -923,21 +925,13 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w switch (wmn->data) { case ND_SHADING: case ND_NODES: - { -#ifdef WITH_LEGACY_DEPSGRAPH - Object *ob = OBACT; - if ((v3d->drawtype == OB_MATERIAL) || - (ob && (ob->mode == OB_MODE_TEXTURE_PAINT)) || - (v3d->drawtype == OB_TEXTURE && - (scene->gm.matmode == GAME_MAT_GLSL || - BKE_scene_use_new_shading_nodes(scene))) || - !DEG_depsgraph_use_legacy()) -#endif - { - ED_region_tag_redraw(ar); - } + /* TODO(sergey) This is a bit too much updates, but needed to + * have proper material drivers update in the viewport. + * + * How to solve? + */ + ED_region_tag_redraw(ar); break; - } case ND_SHADING_DRAW: case ND_SHADING_LINKS: ED_region_tag_redraw(ar); @@ -949,20 +943,23 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w case ND_WORLD_DRAW: /* handled by space_view3d_listener() for v3d access */ break; + case ND_WORLD: + /* Needed for updating world materials */ + ED_region_tag_redraw(ar); + break; } break; case NC_LAMP: switch (wmn->data) { case ND_LIGHTING: - if ((v3d->drawtype == OB_MATERIAL) || - (v3d->drawtype == OB_TEXTURE && (scene->gm.matmode == GAME_MAT_GLSL)) || - !DEG_depsgraph_use_legacy()) - { - ED_region_tag_redraw(ar); - } + /* TODO(sergey): This is a bit too much, but needed to + * handle updates from new depsgraph. + */ + ED_region_tag_redraw(ar); break; case ND_LIGHTING_DRAW: ED_region_tag_redraw(ar); + WM_manipulatormap_tag_refresh(mmap); break; } break; @@ -982,10 +979,10 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w case NC_SPACE: if (wmn->data == ND_SPACE_VIEW3D) { if (wmn->subtype == NS_VIEW3D_GPU) { - RegionView3D *rv3d = ar->regiondata; rv3d->rflag |= RV3D_GPULIGHT_UPDATE; } ED_region_tag_redraw(ar); + WM_manipulatormap_tag_refresh(mmap); } break; case NC_ID: @@ -998,15 +995,13 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w case ND_SKETCH: ED_region_tag_redraw(ar); break; - case ND_SCREENBROWSE: - case ND_SCREENDELETE: - case ND_SCREENSET: - /* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */ - /* updates used layers only for View3D in active screen */ - if (wmn->reference) { - bScreen *sc_ref = wmn->reference; - view3d_recalc_used_layers(ar, wmn, sc_ref->scene); - } + case ND_LAYOUTBROWSE: + case ND_LAYOUTDELETE: + case ND_LAYOUTSET: + WM_manipulatormap_tag_refresh(mmap); + ED_region_tag_redraw(ar); + break; + case ND_LAYER: ED_region_tag_redraw(ar); break; } @@ -1020,12 +1015,118 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w } } +static void view3d_main_region_message_subscribe( + const struct bContext *C, + struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene), + struct bScreen *UNUSED(screen), struct ScrArea *sa, struct ARegion *ar, + struct wmMsgBus *mbus) +{ + /* Developer note: there are many properties that impact 3D view drawing, + * so instead of subscribing to individual properties, just subscribe to types + * accepting some redundant redraws. + * + * For other space types we might try avoid this, keep the 3D view as an exceptional case! */ + wmMsgParams_RNA msg_key_params = {{{0}}}; + + /* Only subscribe to types. */ + StructRNA *type_array[] = { + &RNA_Window, + + /* These object have properties that impact drawing. */ + &RNA_AreaLamp, + &RNA_Camera, + &RNA_Lamp, + &RNA_Speaker, + &RNA_SunLamp, + + /* General types the 3D view depends on. */ + &RNA_Object, + &RNA_UnitSettings, /* grid-floor */ + + &RNA_View3DOverlay, + &RNA_View3DShading, + &RNA_World, + }; + + wmMsgSubscribeValue msg_sub_value_region_tag_redraw = { + .owner = ar, + .user_data = ar, + .notify = ED_region_do_msg_notify_tag_redraw, + }; + + for (int i = 0; i < ARRAY_SIZE(type_array); i++) { + msg_key_params.ptr.type = type_array[i]; + WM_msg_subscribe_rna_params( + mbus, + &msg_key_params, + &msg_sub_value_region_tag_redraw, + __func__); + } + + /* Subscribe to a handful of other properties. */ + RegionView3D *rv3d = ar->regiondata; + + WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, engine, &msg_sub_value_region_tag_redraw); + WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_x, &msg_sub_value_region_tag_redraw); + WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_y, &msg_sub_value_region_tag_redraw); + WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_x, &msg_sub_value_region_tag_redraw); + WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_y, &msg_sub_value_region_tag_redraw); + if (rv3d->persp == RV3D_CAMOB) { + WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, use_border, &msg_sub_value_region_tag_redraw); + } + + WM_msg_subscribe_rna_anon_type(mbus, SceneEEVEE, &msg_sub_value_region_tag_redraw); + WM_msg_subscribe_rna_anon_type(mbus, SceneDisplay, &msg_sub_value_region_tag_redraw); + WM_msg_subscribe_rna_anon_type(mbus, ObjectDisplay, &msg_sub_value_region_tag_redraw); + + ViewLayer *view_layer = CTX_data_view_layer(C); + Object *obact = OBACT(view_layer); + if (obact != NULL) { + switch (obact->mode) { + case OB_MODE_PARTICLE_EDIT: + WM_msg_subscribe_rna_anon_type(mbus, ParticleEdit, &msg_sub_value_region_tag_redraw); + break; + default: + break; + } + } + + { + wmMsgSubscribeValue msg_sub_value_region_tag_refresh = { + .owner = ar, + .user_data = sa, + .notify = WM_toolsystem_do_msg_notify_tag_refresh, + }; + WM_msg_subscribe_rna_anon_prop( + mbus, Object, mode, + &msg_sub_value_region_tag_refresh); + } +} + +static void view3d_tools_region_message_subscribe( + const struct bContext *UNUSED(C), + struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene), + struct bScreen *UNUSED(screen), struct ScrArea *UNUSED(sa), struct ARegion *ar, + struct wmMsgBus *mbus) +{ + wmMsgSubscribeValue msg_sub_value_region_tag_redraw = { + .owner = ar, + .user_data = ar, + .notify = ED_region_do_msg_notify_tag_redraw, + }; + WM_msg_subscribe_rna_anon_prop(mbus, WorkSpace, tools, &msg_sub_value_region_tag_redraw); +} + /* concept is to retrieve cursor type context-less */ -static void view3d_main_region_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar)) +static void view3d_main_region_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) { - Scene *scene = win->screen->scene; + if (WM_cursor_set_from_tool(win, sa, ar)) { + return; + } - if (scene->obedit) { + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer); + if (obedit) { WM_cursor_set(win, CURSOR_EDIT); } else { @@ -1048,7 +1149,9 @@ static void view3d_header_region_draw(const bContext *C, ARegion *ar) ED_region_header(C, ar); } -static void view3d_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn) +static void view3d_header_region_listener( + bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, + wmNotifier *wmn, const Scene *UNUSED(scene)) { /* context changes */ switch (wmn->category) { @@ -1078,6 +1181,36 @@ static void view3d_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(s } } +static void view3d_header_region_message_subscribe( + const struct bContext *UNUSED(C), + struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene), + struct bScreen *UNUSED(screen), struct ScrArea *UNUSED(sa), struct ARegion *ar, + struct wmMsgBus *mbus) +{ + wmMsgParams_RNA msg_key_params = {{{0}}}; + + /* Only subscribe to types. */ + StructRNA *type_array[] = { + &RNA_View3DShading, + }; + + wmMsgSubscribeValue msg_sub_value_region_tag_redraw = { + .owner = ar, + .user_data = ar, + .notify = ED_region_do_msg_notify_tag_redraw, + }; + + for (int i = 0; i < ARRAY_SIZE(type_array); i++) { + msg_key_params.ptr.type = type_array[i]; + WM_msg_subscribe_rna_params( + mbus, + &msg_key_params, + &msg_sub_value_region_tag_redraw, + __func__); + } +} + + /* add handlers, stuff you only do once or on area/region changes */ static void view3d_buttons_region_init(wmWindowManager *wm, ARegion *ar) { @@ -1091,10 +1224,12 @@ static void view3d_buttons_region_init(wmWindowManager *wm, ARegion *ar) static void view3d_buttons_region_draw(const bContext *C, ARegion *ar) { - ED_region_panels(C, ar, NULL, -1, true); + ED_region_panels(C, ar); } -static void view3d_buttons_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn) +static void view3d_buttons_region_listener( + bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, + wmNotifier *wmn, const Scene *UNUSED(scene)) { /* context changes */ switch (wmn->category) { @@ -1184,6 +1319,27 @@ static void view3d_buttons_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED( } } +static int view3d_tools_region_snap_size(const ARegion *ar, int size, int axis) +{ + if (axis == 0) { + /* Note, this depends on the icon size: see #ICON_DEFAULT_HEIGHT_TOOLBAR. */ + const float snap_units[] = {2 + 0.8f, 4 + 0.8f}; + const float aspect = BLI_rctf_size_x(&ar->v2d.cur) / (BLI_rcti_size_x(&ar->v2d.mask) + 1); + int best_diff = INT_MAX; + int best_size = size; + for (uint i = 0; i < ARRAY_SIZE(snap_units); i += 1) { + const int test_size = (snap_units[i] * U.widget_unit) / (UI_DPI_FAC * aspect); + const int test_diff = ABS(test_size - size); + if (test_diff < best_diff) { + best_size = test_size; + best_diff = test_diff; + } + } + return best_size; + } + return size; +} + /* add handlers, stuff you only do once or on area/region changes */ static void view3d_tools_region_init(wmWindowManager *wm, ARegion *ar) { @@ -1197,30 +1353,13 @@ static void view3d_tools_region_init(wmWindowManager *wm, ARegion *ar) static void view3d_tools_region_draw(const bContext *C, ARegion *ar) { - ED_region_panels(C, ar, CTX_data_mode_string(C), -1, true); -} - -static void view3d_props_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn) -{ - /* context changes */ - switch (wmn->category) { - case NC_WM: - if (wmn->data == ND_HISTORY) - ED_region_tag_redraw(ar); - break; - case NC_SCENE: - if (wmn->data == ND_MODE) - ED_region_tag_redraw(ar); - break; - case NC_SPACE: - if (wmn->data == ND_SPACE_VIEW3D) - ED_region_tag_redraw(ar); - break; - } + ED_region_panels_ex(C, ar, (const char * []){CTX_data_mode_string(C), NULL}, -1, true); } /* area (not region) level listener */ -static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNotifier *wmn) +static void space_view3d_listener( + bScreen *UNUSED(sc), ScrArea *sa, struct wmNotifier *wmn, Scene *UNUSED(scene), + WorkSpace *UNUSED(workspace)) { View3D *v3d = sa->spacedata.first; @@ -1255,8 +1394,6 @@ static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNot } const char *view3d_context_dir[] = { - "selected_objects", "selected_bases", "selected_editable_objects", - "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases", "active_base", "active_object", NULL }; @@ -1267,109 +1404,27 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes if (CTX_data_dir(member)) { CTX_data_dir_set(result, view3d_context_dir); } - else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) { - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - const unsigned int lay = v3d ? v3d->lay : scene->lay; - Base *base; - const bool selected_objects = CTX_data_equals(member, "selected_objects"); - - for (base = scene->base.first; base; base = base->next) { - if ((base->flag & SELECT) && (base->lay & lay)) { - if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) { - if (selected_objects) - CTX_data_id_list_add(result, &base->object->id); - else - CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); - } - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) { - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - const unsigned int lay = v3d ? v3d->lay : scene->lay; - Base *base; - const bool selected_editable_objects = CTX_data_equals(member, "selected_editable_objects"); - - for (base = scene->base.first; base; base = base->next) { - if ((base->flag & SELECT) && (base->lay & lay)) { - if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) { - if (0 == BKE_object_is_libdata(base->object)) { - if (selected_editable_objects) - CTX_data_id_list_add(result, &base->object->id); - else - CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); - } - } - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) { - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - const unsigned int lay = v3d ? v3d->lay : scene->lay; - Base *base; - const bool visible_objects = CTX_data_equals(member, "visible_objects"); - - for (base = scene->base.first; base; base = base->next) { - if (base->lay & lay) { - if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) { - if (visible_objects) - CTX_data_id_list_add(result, &base->object->id); - else - CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); - } - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) { - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - const unsigned int lay = v3d ? v3d->lay : scene->lay; - Base *base; - const bool selectable_objects = CTX_data_equals(member, "selectable_objects"); - - for (base = scene->base.first; base; base = base->next) { - if (base->lay & lay) { - if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0 && (base->object->restrictflag & OB_RESTRICT_SELECT) == 0) { - if (selectable_objects) - CTX_data_id_list_add(result, &base->object->id); - else - CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); - } - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } else if (CTX_data_equals(member, "active_base")) { - View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); - const unsigned int lay = v3d ? v3d->lay : scene->lay; - if (scene->basact && (scene->basact->lay & lay)) { - Object *ob = scene->basact->object; + ViewLayer *view_layer = CTX_data_view_layer(C); + if (view_layer->basact) { + Object *ob = view_layer->basact->object; /* if hidden but in edit mode, we still display, can happen with animation */ - if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT)) - CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, scene->basact); + if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT)) { + CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact); + } } return 1; } else if (CTX_data_equals(member, "active_object")) { - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - const unsigned int lay = v3d ? v3d->lay : scene->lay; - if (scene->basact && (scene->basact->lay & lay)) { - Object *ob = scene->basact->object; - if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT)) - CTX_data_id_pointer_set(result, &scene->basact->object->id); + ViewLayer *view_layer = CTX_data_view_layer(C); + if (view_layer->basact) { + Object *ob = view_layer->basact->object; + /* if hidden but in edit mode, we still display, can happen with animation */ + if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT) != 0) { + CTX_data_id_pointer_set(result, &ob->id); + } } return 1; @@ -1410,8 +1465,6 @@ static void view3d_id_remap(ScrArea *sa, SpaceLink *slink, ID *old_id, ID *new_i /* Values in local-view aren't used, see: T52663 */ if (is_local == false) { - /* Skip 'v3d->defmaterial', it's not library data. */ - if ((ID *)v3d->ob_centre == old_id) { v3d->ob_centre = (Object *)new_id; /* Otherwise, bonename may remain valid... We could be smart and check this, too? */ @@ -1419,21 +1472,6 @@ static void view3d_id_remap(ScrArea *sa, SpaceLink *slink, ID *old_id, ID *new_i v3d->ob_centre_bone[0] = '\0'; } } - - if (ELEM(GS(old_id->name), ID_IM, ID_MC)) { - for (BGpic *bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { - if ((ID *)bgpic->ima == old_id) { - bgpic->ima = (Image *)new_id; - id_us_min(old_id); - id_us_plus(new_id); - } - if ((ID *)bgpic->clip == old_id) { - bgpic->clip = (MovieClip *)new_id; - id_us_min(old_id); - id_us_plus(new_id); - } - } - } } if (is_local) { @@ -1459,6 +1497,7 @@ void ED_spacetype_view3d(void) st->operatortypes = view3d_operatortypes; st->keymap = view3d_keymap; st->dropboxes = view3d_dropboxes; + st->manipulators = view3d_widgets; st->context = view3d_context; st->id_remap = view3d_id_remap; @@ -1472,6 +1511,7 @@ void ED_spacetype_view3d(void) art->free = view3d_main_region_free; art->duplicate = view3d_main_region_duplicate; art->listener = view3d_main_region_listener; + art->message_subscribe = view3d_main_region_message_subscribe; art->cursor = view3d_main_region_cursor; art->lock = 1; /* can become flag, see BKE_spacedata_draw_locks */ BLI_addhead(&st->regiontypes, art); @@ -1495,29 +1535,12 @@ void ED_spacetype_view3d(void) art->prefsizey = 50; /* XXX */ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; art->listener = view3d_buttons_region_listener; + art->message_subscribe = view3d_tools_region_message_subscribe; + art->snap_size = view3d_tools_region_snap_size; art->init = view3d_tools_region_init; art->draw = view3d_tools_region_draw; BLI_addhead(&st->regiontypes, art); -#if 0 - /* unfinished still */ - view3d_toolshelf_register(art); -#endif - - /* regions: tool properties */ - art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tool properties region"); - art->regionid = RGN_TYPE_TOOL_PROPS; - art->prefsizex = 0; - art->prefsizey = 120; - art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; - art->listener = view3d_props_region_listener; - art->init = view3d_tools_region_init; - art->draw = view3d_tools_region_draw; - BLI_addhead(&st->regiontypes, art); - - view3d_tool_props_register(art); - - /* regions: header */ art = MEM_callocN(sizeof(ARegionType), "spacetype view3d header region"); art->regionid = RGN_TYPE_HEADER; @@ -1526,8 +1549,12 @@ void ED_spacetype_view3d(void) art->listener = view3d_header_region_listener; art->init = view3d_header_region_init; art->draw = view3d_header_region_draw; + art->message_subscribe = view3d_header_region_message_subscribe; + BLI_addhead(&st->regiontypes, art); + + /* regions: hud */ + art = ED_area_type_hud(st->spaceid); BLI_addhead(&st->regiontypes, art); BKE_spacetype_register(st); } - |