Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h2
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c308
8 files changed, 330 insertions, 22 deletions
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index abb6fed965e..c3a02ecb1a2 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -2853,13 +2853,13 @@ static int viewselected_exec(bContext *C, wmOperator *op)
}
else if (obedit) {
/* only selected */
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer_eval, obedit->mode, ob_eval_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (view_layer_eval, v3d, obedit->mode, ob_eval_iter) {
ok |= ED_view3d_minmax_verts(ob_eval_iter, min, max);
}
FOREACH_OBJECT_IN_MODE_END;
}
else if (ob_eval && (ob_eval->mode & OB_MODE_POSE)) {
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer_eval, ob_eval->mode, ob_eval_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (view_layer_eval, v3d, ob_eval->mode, ob_eval_iter) {
ok |= BKE_pose_minmax(ob_eval_iter, min, max, true, true);
}
FOREACH_OBJECT_IN_MODE_END;
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
index 6cd94830fe9..be07928d5fc 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
@@ -107,12 +107,13 @@ static int gizmo_preselect_elem_test_select(
{
ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
if (((gz_ele->bases)) == NULL ||
(gz_ele->bases[0] != view_layer->basact))
{
MEM_SAFE_FREE(gz_ele->bases);
gz_ele->bases = BKE_view_layer_array_from_bases_in_edit_mode(
- view_layer, &gz_ele->bases_len);
+ view_layer, v3d, &gz_ele->bases_len);
}
}
@@ -298,12 +299,13 @@ static int gizmo_preselect_edgering_test_select(
{
ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
if (((gz_ring->bases)) == NULL ||
(gz_ring->bases[0] != view_layer->basact))
{
MEM_SAFE_FREE(gz_ring->bases);
gz_ring->bases = BKE_view_layer_array_from_bases_in_edit_mode(
- view_layer, &gz_ring->bases_len);
+ view_layer, v3d, &gz_ring->bases_len);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 05f2d8f67e1..9f77f671a7d 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -171,10 +171,12 @@ void VIEW3D_OT_select_box(struct wmOperatorType *ot);
void VIEW3D_OT_select_lasso(struct wmOperatorType *ot);
void VIEW3D_OT_select_menu(struct wmOperatorType *ot);
+/* view3d_view.c */
void VIEW3D_OT_smoothview(struct wmOperatorType *ot);
void VIEW3D_OT_camera_to_view(struct wmOperatorType *ot);
void VIEW3D_OT_camera_to_view_selected(struct wmOperatorType *ot);
void VIEW3D_OT_object_as_camera(struct wmOperatorType *ot);
+void VIEW3D_OT_localview(struct wmOperatorType *ot);
bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const struct BoundBox *bb, float obmat[4][4]);
bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const struct BoundBox *bb);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 2dbe0a0b843..8092dc9f0f7 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -204,6 +204,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_camera_to_view);
WM_operatortype_append(VIEW3D_OT_camera_to_view_selected);
WM_operatortype_append(VIEW3D_OT_object_as_camera);
+ WM_operatortype_append(VIEW3D_OT_localview);
WM_operatortype_append(VIEW3D_OT_fly);
WM_operatortype_append(VIEW3D_OT_walk);
WM_operatortype_append(VIEW3D_OT_navigate);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index f973f84cf6f..aafe931ff07 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -456,7 +456,7 @@ static Base **do_pose_tag_select_op_prepare(ViewContext *vc, uint *r_bases_len)
{
Base **bases = NULL;
BLI_array_declare(bases);
- FOREACH_BASE_IN_MODE_BEGIN (vc->view_layer, OB_MODE_POSE, base_iter) {
+ FOREACH_BASE_IN_MODE_BEGIN (vc->view_layer, vc->v3d, OB_MODE_POSE, base_iter) {
Object *ob_iter = base_iter->object;
bArmature *arm = ob_iter->data;
for (bPoseChannel *pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) {
@@ -1001,7 +1001,7 @@ static void view3d_lasso_select(
}
else { /* Edit Mode */
- FOREACH_OBJECT_IN_MODE_BEGIN (vc->view_layer, ob->mode, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (vc->view_layer, vc->v3d, ob->mode, ob_iter) {
ED_view3d_viewcontext_init_object(vc, ob_iter);
switch (vc->obedit->type) {
@@ -1729,7 +1729,7 @@ static bool ed_object_select_pick(
}
}
else if (ED_armature_pose_select_pick_with_buffer(
- view_layer, basact, buffer, hits, extend, deselect, toggle, do_nearest))
+ view_layer, v3d, basact, buffer, hits, extend, deselect, toggle, do_nearest))
{
/* then bone is found */
@@ -2252,7 +2252,7 @@ static int do_armature_box_select(
VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP);
uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(vc->view_layer, &objects_len);
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(vc->view_layer, vc->v3d, &objects_len);
/* clear flag we use to detect point was affected */
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -2531,7 +2531,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
if (vc.obedit) {
- FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.obedit->mode, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.v3d, vc.obedit->mode, ob_iter) {
ED_view3d_viewcontext_init_object(&vc, ob_iter);
switch (vc.obedit->type) {
@@ -3264,7 +3264,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
{
view3d_operator_needs_opengl(C);
- FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, obact->mode, ob_iter) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.v3d, obact->mode, ob_iter) {
ED_view3d_viewcontext_init_object(&vc, ob_iter);
obact = vc.obact;
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 9089a34ecaf..760208ffe28 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -90,7 +90,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
if (obedit) {
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
obedit = objects[ob_index];
@@ -132,7 +132,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
else {
struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
- FOREACH_SELECTED_EDITABLE_OBJECT_BEGIN(view_layer_eval, ob_eval)
+ FOREACH_SELECTED_EDITABLE_OBJECT_BEGIN(view_layer_eval, v3d, ob_eval)
{
Object *ob = DEG_get_original_object(ob_eval);
if (ob->mode & OB_MODE_POSE) {
@@ -268,7 +268,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
float snap_target_local[3];
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
obedit = objects[ob_index];
@@ -624,7 +624,7 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
int global_transverts_tot = 0;
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
obedit = objects[ob_index];
@@ -687,7 +687,7 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
}
}
else {
- FOREACH_SELECTED_OBJECT_BEGIN(view_layer_eval, ob_eval)
+ FOREACH_SELECTED_OBJECT_BEGIN(view_layer_eval, v3d, ob_eval)
{
copy_v3_v3(vec, ob_eval->obmat[3]);
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 022fccd7ce7..8b0124a7a2b 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -91,14 +91,9 @@ void ED_view3d_background_color_get(const Scene *scene, const View3D *v3d, float
}
}
-View3DCursor *ED_view3d_cursor3d_get(Scene *scene, View3D *v3d)
+View3DCursor *ED_view3d_cursor3d_get(Scene *scene, View3D *UNUSED(v3d))
{
- if (v3d && v3d->localvd) {
- return &v3d->cursor;
- }
- else {
- return &scene->cursor;
- }
+ return &scene->cursor;
}
void ED_view3d_cursor3d_calc_mat3(const Scene *scene, const View3D *v3d, float mat[3][3])
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index f8f2e9635e4..a7098ae255d 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -43,6 +43,7 @@
#include "BKE_context.h"
#include "BKE_object.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -60,6 +61,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "ED_object.h"
#include "ED_screen.h"
#include "DRW_engine.h"
@@ -1106,6 +1108,312 @@ finally:
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Local View Operators
+ * \{ */
+
+static unsigned int free_localbit(Main *bmain)
+{
+ ScrArea *sa;
+ bScreen *sc;
+
+ unsigned short local_view_bits = 0;
+
+ /* sometimes we loose a localview: when an area is closed */
+ /* check all areas: which localviews are in use? */
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl = sa->spacedata.first;
+ for (; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *) sl;
+ if (v3d->localvd) {
+ local_view_bits |= v3d->local_view_uuid;
+ }
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < 16; i++) {
+ if ((local_view_bits & (1 << i)) == 0) {
+ return (1 << i);
+ }
+ }
+
+ return 0;
+}
+
+static bool view3d_localview_init(
+ const Depsgraph *depsgraph,
+ wmWindowManager *wm,
+ wmWindow *win,
+ Main *bmain,
+ ViewLayer *view_layer,
+ ScrArea *sa,
+ const int smooth_viewtx,
+ ReportList *reports)
+{
+ View3D *v3d = sa->spacedata.first;
+ Base *base;
+ float min[3], max[3], box[3], mid[3];
+ float size = 0.0f;
+ unsigned int local_view_bit;
+ bool ok = false;
+
+ if (v3d->localvd) {
+ return ok;
+ }
+
+ INIT_MINMAX(min, max);
+
+ local_view_bit = free_localbit(bmain);
+
+ if (local_view_bit == 0) {
+ /* TODO(dfelinto): We can kick one of the other 3D views out of local view
+ specially if it is not being used. */
+ BKE_report(reports, RPT_ERROR, "No more than 16 local views");
+ ok = false;
+ }
+ else {
+ Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
+ if (obedit) {
+ FOREACH_BASE_IN_EDIT_MODE_BEGIN(view_layer, v3d, base_iter) {
+ BKE_object_minmax(base_iter->object, min, max, false);
+ base_iter->local_view_bits |= local_view_bit;
+ ok = true;
+ } FOREACH_BASE_IN_EDIT_MODE_END;
+ }
+ else {
+ for (base = FIRSTBASE(view_layer); base; base = base->next) {
+ if (TESTBASE(v3d, base)) {
+ BKE_object_minmax(base->object, min, max, false);
+ base->local_view_bits |= local_view_bit;
+ /* Technically we should leave for Depsgraph to handle this.
+ But it is harmless to do it here, and it seems to be necessary. */
+ base->object->base_local_view_bits = base->local_view_bits;
+ ok = true;
+ }
+ }
+ }
+
+ sub_v3_v3v3(box, max, min);
+ size = max_fff(box[0], box[1], box[2]);
+ }
+
+ if (ok == true) {
+ ARegion *ar;
+
+ v3d->localvd = MEM_mallocN(sizeof(View3D), "localview");
+
+ memcpy(v3d->localvd, v3d, sizeof(View3D));
+
+ mid_v3_v3v3(mid, min, max);
+
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = ar->regiondata;
+ bool ok_dist = true;
+
+ /* New view values. */
+ Object *camera_old = NULL;
+ float dist_new, ofs_new[3];
+
+ rv3d->localvd = MEM_mallocN(sizeof(RegionView3D), "localview region");
+ memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D));
+
+ negate_v3_v3(ofs_new, mid);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ rv3d->persp = RV3D_PERSP;
+ camera_old = v3d->camera;
+ }
+
+ if (rv3d->persp == RV3D_ORTHO) {
+ if (size < 0.0001f) {
+ ok_dist = false;
+ }
+ }
+
+ if (ok_dist) {
+ dist_new = ED_view3d_radius_to_dist(v3d, ar, depsgraph, rv3d->persp, true, (size / 2) * VIEW3D_MARGIN);
+
+ if (rv3d->persp == RV3D_PERSP) {
+ /* Don't zoom closer than the near clipping plane. */
+ dist_new = max_ff(dist_new, v3d->near * 1.5f);
+ }
+ }
+
+ ED_view3d_smooth_view_ex(
+ depsgraph,
+ wm, win, sa, v3d, ar, smooth_viewtx,
+ &(const V3D_SmoothParams) {
+ .camera_old = camera_old,
+ .ofs = ofs_new, .quat = rv3d->viewquat,
+ .dist = ok_dist ? &dist_new : NULL, .lens = &v3d->lens});
+ }
+ }
+
+ v3d->local_view_uuid = local_view_bit;
+ }
+
+ DEG_on_visible_update(bmain, false);
+ return ok;
+}
+
+static void restore_localviewdata(
+ const Depsgraph *depsgraph,
+ wmWindowManager *wm,
+ wmWindow *win,
+ Main *bmain,
+ ScrArea *sa,
+ const int smooth_viewtx)
+{
+ const bool free = true;
+ ARegion *ar;
+ View3D *v3d = sa->spacedata.first;
+ Object *camera_old, *camera_new;
+
+ if (v3d->localvd == NULL) return;
+
+ camera_old = v3d->camera;
+ camera_new = v3d->localvd->camera;
+
+ v3d->local_view_uuid = 0;
+ v3d->camera = v3d->localvd->camera;
+
+ if (free) {
+ MEM_freeN(v3d->localvd);
+ v3d->localvd = NULL;
+ }
+
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->localvd) {
+ Object *camera_old_rv3d, *camera_new_rv3d;
+
+ camera_old_rv3d = (rv3d->persp == RV3D_CAMOB) ? camera_old : NULL;
+ camera_new_rv3d = (rv3d->localvd->persp == RV3D_CAMOB) ? camera_new : NULL;
+
+ rv3d->view = rv3d->localvd->view;
+ rv3d->persp = rv3d->localvd->persp;
+ rv3d->camzoom = rv3d->localvd->camzoom;
+
+ ED_view3d_smooth_view_ex(
+ depsgraph,
+ wm, win, sa,
+ v3d, ar, smooth_viewtx,
+ &(const V3D_SmoothParams) {
+ .camera_old = camera_old_rv3d, .camera = camera_new_rv3d,
+ .ofs = rv3d->localvd->ofs, .quat = rv3d->localvd->viewquat,
+ .dist = &rv3d->localvd->dist});
+
+ if (free) {
+ MEM_freeN(rv3d->localvd);
+ rv3d->localvd = NULL;
+ }
+ }
+
+ ED_view3d_shade_update(bmain, v3d, sa);
+ }
+ }
+}
+
+static bool view3d_localview_exit(
+ const Depsgraph *depsgraph,
+ wmWindowManager *wm,
+ wmWindow *win,
+ Main *bmain,
+ ViewLayer *view_layer,
+ ScrArea *sa,
+ const int smooth_viewtx)
+{
+ View3D *v3d = sa->spacedata.first;
+ struct Base *base;
+ unsigned int local_view_bit;
+
+ if (v3d->localvd) {
+
+ local_view_bit = v3d->local_view_uuid;
+
+ restore_localviewdata(depsgraph, wm, win, bmain, sa, smooth_viewtx);
+
+ Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
+ for (base = FIRSTBASE(view_layer); base; base = base->next) {
+ if (base->local_view_bits & local_view_bit) {
+ base->local_view_bits &= ~local_view_bit;
+ if (base->object != obedit) {
+ ED_object_base_select(base, BA_SELECT);
+ }
+ }
+ }
+
+ DEG_on_visible_update(bmain, false);
+
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+static int localview_exec(bContext *C, wmOperator *op)
+{
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ ScrArea *sa = CTX_wm_area(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ bool changed;
+
+ if (v3d->localvd) {
+ changed = view3d_localview_exit(depsgraph, wm, win, bmain, view_layer, sa, smooth_viewtx);
+ }
+ else {
+ changed = view3d_localview_init(depsgraph, wm, win, bmain, view_layer, sa, smooth_viewtx, op->reports);
+ }
+
+ if (changed) {
+ DEG_id_type_tag(bmain, ID_OB);
+ ED_area_tag_redraw(sa);
+
+ /* Unselected objects become selected when exiting. */
+ if (v3d->localvd == NULL) {
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+ else {
+ DEG_id_tag_update(&scene->id, DEG_TAG_BASE_FLAGS_UPDATE);
+ }
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void VIEW3D_OT_localview(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Local View";
+ ot->description = "Toggle display of selected object(s) separately and centered in view";
+ ot->idname = "VIEW3D_OT_localview";
+
+ /* api callbacks */
+ ot->exec = localview_exec;
+ ot->flag = OPTYPE_UNDO; /* localview changes object layer bitflags */
+
+ ot->poll = ED_operator_view3d_active;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name View Layer Utilities
* \{ */