// XXX: this should be removed... We really shouldn't duplicate logic like this! bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, View3D *v3d) { Base *base = scene->basact; bGPdata *gpd = NULL; /* We have to make sure active object is actually visible and selected, else we must use default scene gpd, * to be consistent with ED_gpencil_data_get_active's behavior. */ if (base && TESTBASE(v3d, base)) { gpd = base->object->gpd; } return gpd ? gpd : scene->gpd; }
static bool view3d_localview_init( wmWindowManager *wm, wmWindow *win, Main *bmain, Scene *scene, 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, size_persp = 0.0f, size_ortho = 0.0f; unsigned int locallay; bool ok = false; if (v3d->localvd) { return ok; } INIT_MINMAX(min, max); locallay = free_localbit(bmain); if (locallay == 0) { BKE_report(reports, RPT_ERROR, "No more than 8 local views"); ok = false; } else { if (scene->obedit) { BKE_object_minmax(scene->obedit, min, max, false); ok = true; BASACT->lay |= locallay; scene->obedit->lay = BASACT->lay; } else { for (base = FIRSTBASE; base; base = base->next) { if (TESTBASE(v3d, base)) { BKE_object_minmax(base->object, min, max, false); base->lay |= locallay; base->object->lay = base->lay; ok = true; } } } sub_v3_v3v3(box, max, min); size = max_fff(box[0], box[1], box[2]); /* do not zoom closer than the near clipping plane */ size = max_ff(size, v3d->near * 1.5f); /* perspective size (we always switch out of camera view so no need to use its lens size) */ size_persp = ED_view3d_radius_to_persp_dist(focallength_to_fov(v3d->lens, DEFAULT_SENSOR_WIDTH), size / 2.0f) * VIEW3D_MARGIN; size_ortho = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f) * VIEW3D_MARGIN; } if (ok == true) { ARegion *ar; v3d->localvd = MEM_mallocN(sizeof(View3D), "localview"); memcpy(v3d->localvd, v3d, sizeof(View3D)); mid_v3_v3v3(mid, min, max); copy_v3_v3(v3d->cursor, mid); for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d = ar->regiondata; /* 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; } /* perspective should be a bit farther away to look nice */ if (rv3d->persp != RV3D_ORTHO) { dist_new = size_persp; } else { dist_new = size_ortho; } /* correction for window aspect ratio */ if (ar->winy > 2 && ar->winx > 2) { float asp = (float)ar->winx / (float)ar->winy; if (asp < 1.0f) asp = 1.0f / asp; dist_new *= asp; } ED_view3d_smooth_view_ex( wm, win, sa, v3d, ar, camera_old, NULL, ofs_new, NULL, &dist_new, NULL, smooth_viewtx); } } v3d->lay = locallay; } else { /* clear flags */ for (base = FIRSTBASE; base; base = base->next) { if (base->lay & locallay) { base->lay -= locallay; if (base->lay == 0) base->lay = v3d->layact; if (base->object != scene->obedit) base->flag |= SELECT; base->object->lay = base->lay; } } } return ok; }
static bool view3d_localview_init( wmWindowManager *wm, wmWindow *win, Main *bmain, Scene *scene, 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 locallay; bool ok = false; if (v3d->localvd) { return ok; } INIT_MINMAX(min, max); locallay = free_localbit(bmain); if (locallay == 0) { BKE_report(reports, RPT_ERROR, "No more than 8 local views"); ok = false; } else { if (scene->obedit) { BKE_object_minmax(scene->obedit, min, max, false); ok = true; BASACT->lay |= locallay; scene->obedit->lay = BASACT->lay; } else { for (base = FIRSTBASE; base; base = base->next) { if (TESTBASE(v3d, base)) { BKE_object_minmax(base->object, min, max, false); base->lay |= locallay; base->object->lay = base->lay; 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); copy_v3_v3(v3d->cursor, mid); 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, 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( wm, win, sa, v3d, ar, camera_old, NULL, ofs_new, NULL, ok_dist ? &dist_new : NULL, NULL, smooth_viewtx); } } v3d->lay = locallay; } else { /* clear flags */ for (base = FIRSTBASE; base; base = base->next) { if (base->lay & locallay) { base->lay -= locallay; if (base->lay == 0) base->lay = v3d->layact; if (base->object != scene->obedit) base->flag |= SELECT; base->object->lay = base->lay; } } } return ok; }
static void initlocalview(Main *bmain, Scene *scene, ScrArea *sa) { View3D *v3d= sa->spacedata.first; Base *base; float size = 0.0, min[3], max[3], box[3]; unsigned int locallay; int ok=0; if(v3d->localvd) return; INIT_MINMAX(min, max); locallay= free_localbit(bmain); if(locallay==0) { printf("Sorry, no more than 8 localviews\n"); // XXX error ok= 0; } else { if(scene->obedit) { minmax_object(scene->obedit, min, max); ok= 1; BASACT->lay |= locallay; scene->obedit->lay= BASACT->lay; } else { for(base= FIRSTBASE; base; base= base->next) { if(TESTBASE(v3d, base)) { minmax_object(base->object, min, max); base->lay |= locallay; base->object->lay= base->lay; ok= 1; } } } box[0]= (max[0]-min[0]); box[1]= (max[1]-min[1]); box[2]= (max[2]-min[2]); size= MAX3(box[0], box[1], box[2]); if(size <= 0.01f) size= 0.01f; } if(ok) { ARegion *ar; v3d->localvd= MEM_mallocN(sizeof(View3D), "localview"); memcpy(v3d->localvd, v3d, sizeof(View3D)); for(ar= sa->regionbase.first; ar; ar= ar->next) { if(ar->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d= ar->regiondata; rv3d->localvd= MEM_mallocN(sizeof(RegionView3D), "localview region"); memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D)); rv3d->ofs[0]= -(min[0]+max[0])/2.0f; rv3d->ofs[1]= -(min[1]+max[1])/2.0f; rv3d->ofs[2]= -(min[2]+max[2])/2.0f; rv3d->dist= size; /* perspective should be a bit farther away to look nice */ if(rv3d->persp==RV3D_ORTHO) rv3d->dist*= 0.7f; // correction for window aspect ratio if(ar->winy>2 && ar->winx>2) { float asp= (float)ar->winx/(float)ar->winy; if(asp < 1.0f) asp= 1.0f/asp; rv3d->dist*= asp; } if (rv3d->persp==RV3D_CAMOB) rv3d->persp= RV3D_PERSP; v3d->cursor[0]= -rv3d->ofs[0]; v3d->cursor[1]= -rv3d->ofs[1]; v3d->cursor[2]= -rv3d->ofs[2]; } } v3d->lay= locallay; } else { /* clear flags */ for(base= FIRSTBASE; base; base= base->next) { if( base->lay & locallay ) { base->lay-= locallay; if(base->lay==0) base->lay= v3d->layact; if(base->object != scene->obedit) base->flag |= SELECT; base->object->lay= base->lay; } } } }