Example #1
0
/* only meant for timer usage */
static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
	View3D *v3d = CTX_wm_view3d(C);
	RegionView3D *rv3d = CTX_wm_region_view3d(C);
	struct SmoothView3DStore *sms = rv3d->sms;
	float step, step_inv;
	
	/* escape if not our timer */
	if (rv3d->smooth_timer == NULL || rv3d->smooth_timer != event->customdata)
		return OPERATOR_PASS_THROUGH;
	
	if (sms->time_allowed != 0.0)
		step = (float)((rv3d->smooth_timer->duration) / sms->time_allowed);
	else
		step = 1.0f;
	
	/* end timer */
	if (step >= 1.0f) {
		
		/* if we went to camera, store the original */
		if (sms->to_camera) {
			rv3d->persp = RV3D_CAMOB;
			view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
		}
		else {
			view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);

			ED_view3d_camera_lock_sync(v3d, rv3d);
			ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
		}
		
		if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
			rv3d->view = sms->org_view;
		}

		MEM_freeN(rv3d->sms);
		rv3d->sms = NULL;
		
		WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
		rv3d->smooth_timer = NULL;
		rv3d->rflag &= ~RV3D_NAVIGATING;
	}
	else {
		/* ease in/out */
		step = (3.0f * step * step - 2.0f * step * step * step);

		step_inv = 1.0f - step;

		interp_v3_v3v3(rv3d->ofs,      sms->src.ofs,  sms->dst.ofs,  step);
		interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, step);
		
		rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv;
		v3d->lens  = sms->dst.lens * step + sms->src.lens * step_inv;

		ED_view3d_camera_lock_sync(v3d, rv3d);
		if (ED_screen_animation_playing(CTX_wm_manager(C))) {
			ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
		}

	}
	
	if (rv3d->viewlock & RV3D_BOXVIEW)
		view3d_boxview_copy(CTX_wm_area(C), CTX_wm_region(C));

	/* note: this doesn't work right because the v3d->lens is now used in ortho mode r51636,
	 * when switching camera in quad-view the other ortho views would zoom & reset.
	 *
	 * For now only redraw all regions when smoothview finishes.
	 */
	if (step >= 1.0f) {
		WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
	}
	else {
		ED_region_tag_redraw(CTX_wm_region(C));
	}
	
	return OPERATOR_FINISHED;
}
Example #2
0
/* the arguments are the desired situation */
void ED_view3d_smooth_view_ex(
        /* avoid passing in the context */
        wmWindowManager *wm, wmWindow *win, ScrArea *sa,

        View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera,
        const float *ofs, const float *quat, const float *dist, const float *lens,
        const int smooth_viewtx)
{
	RegionView3D *rv3d = ar->regiondata;
	struct SmoothView3DStore sms = {{0}};
	bool ok = false;
	
	/* initialize sms */
	view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
	view3d_smooth_view_state_backup(&sms.src, v3d, rv3d);
	/* if smoothview runs multiple times... */
	if (rv3d->sms == NULL) {
		view3d_smooth_view_state_backup(&sms.org, v3d, rv3d);
		sms.org_view = rv3d->view;
	}
	else {
		sms.org = rv3d->sms->org;
		sms.org_view = rv3d->sms->org_view;
	}
	/* sms.to_camera = false; */  /* initizlized to zero anyway */

	/* note on camera locking, this is a little confusing but works ok.
	 * we may be changing the view 'as if' there is no active camera, but in fact
	 * there is an active camera which is locked to the view.
	 *
	 * In the case where smooth view is moving _to_ a camera we don't want that
	 * camera to be moved or changed, so only when the camera is not being set should
	 * we allow camera option locking to initialize the view settings from the camera.
	 */
	if (camera == NULL && oldcamera == NULL) {
		ED_view3d_camera_lock_init(v3d, rv3d);
	}

	/* store the options we want to end with */
	if (ofs)  copy_v3_v3(sms.dst.ofs, ofs);
	if (quat) copy_qt_qt(sms.dst.quat, quat);
	if (dist) sms.dst.dist = *dist;
	if (lens) sms.dst.lens = *lens;

	if (camera) {
		sms.dst.dist = ED_view3d_offset_distance(camera->obmat, ofs, VIEW3D_DIST_FALLBACK);
		ED_view3d_from_object(camera, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens);
		sms.to_camera = true; /* restore view3d values in end */
	}
	
	/* skip smooth viewing for render engine draw */
	if (smooth_viewtx && v3d->drawtype != OB_RENDER) {
		bool changed = false; /* zero means no difference */
		
		if (oldcamera != camera)
			changed = true;
		else if (sms.dst.dist != rv3d->dist)
			changed = true;
		else if (sms.dst.lens != v3d->lens)
			changed = true;
		else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs))
			changed = true;
		else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat))
			changed = true;
		
		/* The new view is different from the old one
		 * so animate the view */
		if (changed) {
			/* original values */
			if (oldcamera) {
				sms.src.dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs, 0.0f);
				/* this */
				ED_view3d_from_object(oldcamera, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens);
			}
			/* grid draw as floor */
			if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
				/* use existing if exists, means multiple calls to smooth view wont loose the original 'view' setting */
				rv3d->view = RV3D_VIEW_USER;
			}

			sms.time_allowed = (double)smooth_viewtx / 1000.0;
			
			/* if this is view rotation only
			 * we can decrease the time allowed by
			 * the angle between quats 
			 * this means small rotations wont lag */
			if (quat && !ofs && !dist) {
				float vec1[3] = {0, 0, 1}, vec2[3] = {0, 0, 1};
				float q1[4], q2[4];

				invert_qt_qt(q1, sms.dst.quat);
				invert_qt_qt(q2, sms.src.quat);

				mul_qt_v3(q1, vec1);
				mul_qt_v3(q2, vec2);

				/* scale the time allowed by the rotation */
				sms.time_allowed *= (double)angle_v3v3(vec1, vec2) / M_PI; /* 180deg == 1.0 */
			}

			/* ensure it shows correct */
			if (sms.to_camera) {
				/* use ortho if we move from an ortho view to an ortho camera */
				rv3d->persp = (((rv3d->is_persp == false) &&
				                (camera->type == OB_CAMERA) &&
				                (((Camera *)camera->data)->type == CAM_ORTHO)) ?
				                RV3D_ORTHO : RV3D_PERSP);
			}

			rv3d->rflag |= RV3D_NAVIGATING;
			
			/* not essential but in some cases the caller will tag the area for redraw,
			 * and in that case we can get a flicker of the 'org' user view but we want to see 'src' */
			view3d_smooth_view_state_restore(&sms.src, v3d, rv3d);

			/* keep track of running timer! */
			if (rv3d->sms == NULL) {
				rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d");
			}
			*rv3d->sms = sms;
			if (rv3d->smooth_timer) {
				WM_event_remove_timer(wm, win, rv3d->smooth_timer);
			}
			/* TIMER1 is hardcoded in keymap */
			rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0); /* max 30 frs/sec */

			ok = true;
		}
	}
	
	/* if we get here nothing happens */
	if (ok == false) {
		if (sms.to_camera == false) {
			copy_v3_v3(rv3d->ofs, sms.dst.ofs);
			copy_qt_qt(rv3d->viewquat, sms.dst.quat);
			rv3d->dist = sms.dst.dist;
			v3d->lens = sms.dst.lens;

			ED_view3d_camera_lock_sync(v3d, rv3d);
		}

		if (rv3d->viewlock & RV3D_BOXVIEW) {
			view3d_boxview_copy(sa, ar);
		}

		ED_region_tag_redraw(ar);
	}
}
Example #3
0
/* only meant for timer usage */
static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
{
	View3D *v3d = CTX_wm_view3d(C);
	RegionView3D *rv3d= CTX_wm_region_view3d(C);
	struct SmoothViewStore *sms= rv3d->sms;
	float step, step_inv;
	
	/* escape if not our timer */
	if(rv3d->smooth_timer==NULL || rv3d->smooth_timer!=event->customdata)
		return OPERATOR_PASS_THROUGH;
	
	if(sms->time_allowed != 0.0)
		step = (float)((rv3d->smooth_timer->duration)/sms->time_allowed);
	else
		step = 1.0f;
	
	/* end timer */
	if(step >= 1.0f) {
		
		/* if we went to camera, store the original */
		if(sms->to_camera) {
			rv3d->persp= RV3D_CAMOB;
			copy_v3_v3(rv3d->ofs, sms->orig_ofs);
			copy_qt_qt(rv3d->viewquat, sms->orig_quat);
			rv3d->dist = sms->orig_dist;
			v3d->lens = sms->orig_lens;
		}
		else {
			copy_v3_v3(rv3d->ofs, sms->new_ofs);
			copy_qt_qt(rv3d->viewquat, sms->new_quat);
			rv3d->dist = sms->new_dist;
			v3d->lens = sms->new_lens;

			ED_view3d_camera_lock_sync(v3d, rv3d);
		}
		
		if((rv3d->viewlock & RV3D_LOCKED)==0) {
			rv3d->view= sms->orig_view;
		}

		MEM_freeN(rv3d->sms);
		rv3d->sms= NULL;
		
		WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
		rv3d->smooth_timer= NULL;
		rv3d->rflag &= ~RV3D_NAVIGATING;
	}
	else {
		int i;
		
		/* ease in/out */
		if (step < 0.5f)	step = (float)pow(step*2.0f, 2.0)/2.0f;
		else				step = (float)1.0f-(powf(2.0f*(1.0f-step),2.0f)/2.0f);

		step_inv = 1.0f-step;

		for (i=0; i<3; i++)
			rv3d->ofs[i] = sms->new_ofs[i] * step + sms->orig_ofs[i]*step_inv;

		interp_qt_qtqt(rv3d->viewquat, sms->orig_quat, sms->new_quat, step);
		
		rv3d->dist = sms->new_dist * step + sms->orig_dist*step_inv;
		v3d->lens = sms->new_lens * step + sms->orig_lens*step_inv;

		ED_view3d_camera_lock_sync(v3d, rv3d);
	}
	
	if(rv3d->viewlock & RV3D_BOXVIEW)
		view3d_boxview_copy(CTX_wm_area(C), CTX_wm_region(C));
	
	WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d);
	
	return OPERATOR_FINISHED;
}
Example #4
0
static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event)
{
	Main *bmain= CTX_data_main(C);
	Scene *scene= CTX_data_scene(C);
//	Object *obedit= CTX_data_edit_object(C);
	View3D *v3d= CTX_wm_view3d(C);
//	BoundBox *bb;
	Object *ob= OBACT;
	TransformProperties *tfp= v3d->properties_storage;
	
	switch(event) {
	
	case B_REDR:
		ED_area_tag_redraw(CTX_wm_area(C));
		return; /* no notifier! */
		
	case B_OBJECTPANEL:
		DAG_id_tag_update(&ob->id, OB_RECALC_OB);
		break;

	
	case B_OBJECTPANELMEDIAN:
		if(ob) {
			v3d_editvertex_buts(NULL, v3d, ob, 1.0);
			DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
		}
		break;
		
		/* note; this case also used for parbone */
	case B_OBJECTPANELPARENT:
		if(ob) {
			if(ob->id.lib || test_parent_loop(ob->parent, ob) ) 
				ob->parent= NULL;
			else {
				DAG_scene_sort(bmain, scene);
				DAG_id_tag_update(&ob->id, OB_RECALC_OB);
			}
		}
		break;
		

	case B_ARMATUREPANEL3:  // rotate button on channel
		{
			bPoseChannel *pchan;
			float eul[3];
			
			pchan= get_active_posechannel(ob);
			if (!pchan) return;
			
			/* make a copy to eul[3], to allow TAB on buttons to work */
			eul[0]= (float)M_PI*tfp->ob_eul[0]/180.0f;
			eul[1]= (float)M_PI*tfp->ob_eul[1]/180.0f;
			eul[2]= (float)M_PI*tfp->ob_eul[2]/180.0f;
			
			if (pchan->rotmode == ROT_MODE_AXISANGLE) {
				float quat[4];
				/* convert to axis-angle, passing through quats  */
				eul_to_quat( quat,eul);
				quat_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,quat);
			}
			else if (pchan->rotmode == ROT_MODE_QUAT)
				eul_to_quat( pchan->quat,eul);
			else
				copy_v3_v3(pchan->eul, eul);
		}
		/* no break, pass on */
	case B_ARMATUREPANEL2:
		{
			ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
			DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
		}
		break;
	case B_TRANSFORMSPACEADD:
	{
		char names[sizeof(((TransformOrientation *)NULL)->name)]= "";
		BIF_createTransformOrientation(C, NULL, names, 1, 0);
		break;
	}
	case B_TRANSFORMSPACECLEAR:
		BIF_clearTransformOrientation(C);
		break;
		
#if 0 // XXX
	case B_WEIGHT0_0:
		wpaint->weight = 0.0f;
		break;
		
	case B_WEIGHT1_4:
		wpaint->weight = 0.25f;
		break;
	case B_WEIGHT1_2:
		wpaint->weight = 0.5f;
		break;
	case B_WEIGHT3_4:
		wpaint->weight = 0.75f;
		break;
	case B_WEIGHT1_0:
		wpaint->weight = 1.0f;
		break;
		
	case B_OPA1_8:
		wpaint->a = 0.125f;
		break;
	case B_OPA1_4:
		wpaint->a = 0.25f;
		break;
	case B_OPA1_2:
		wpaint->a = 0.5f;
		break;
	case B_OPA3_4:
		wpaint->a = 0.75f;
		break;
	case B_OPA1_0:
		wpaint->a = 1.0f;
		break;
#endif
	case B_CLR_WPAINT:
//		if(!multires_level1_test()) {
		{
			bDeformGroup *defGroup = BLI_findlink(&ob->defbase, ob->actdef-1);
			if(defGroup) {
				Mesh *me= ob->data;
				int a;
				for(a=0; a<me->totvert; a++)
					ED_vgroup_vert_remove (ob, defGroup, a);
				DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
			}
		}
		break;
	case B_RV3D_LOCKED:
	case B_RV3D_BOXVIEW:
	case B_RV3D_BOXCLIP:
		{
			ScrArea *sa= CTX_wm_area(C);
			ARegion *ar= sa->regionbase.last;
			RegionView3D *rv3d;
			short viewlock;
			
			ar= ar->prev;
			rv3d= ar->regiondata;
			viewlock= rv3d->viewlock;
			
			if((viewlock & RV3D_LOCKED)==0)
				viewlock= 0;
			else if((viewlock & RV3D_BOXVIEW)==0)
				viewlock &= ~RV3D_BOXCLIP;
			
			for(; ar; ar= ar->prev) {
				if(ar->alignment==RGN_ALIGN_QSPLIT) {
					rv3d= ar->regiondata;
					rv3d->viewlock= viewlock;
				}
			}
			
			if(rv3d->viewlock & RV3D_BOXVIEW)
				view3d_boxview_copy(sa, sa->regionbase.last);
			
			ED_area_tag_redraw(sa);
		}
		break;
	}

	/* default for now */
	WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, ob);
}
Example #5
0
/* the arguments are the desired situation */
void smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera,
                 float *ofs, float *quat, float *dist, float *lens)
{
	wmWindowManager *wm= CTX_wm_manager(C);
	wmWindow *win= CTX_wm_window(C);
	ScrArea *sa= CTX_wm_area(C);

	RegionView3D *rv3d= ar->regiondata;
	struct SmoothViewStore sms= {0};
	short ok= FALSE;
	
	/* initialize sms */
	copy_v3_v3(sms.new_ofs, rv3d->ofs);
	copy_qt_qt(sms.new_quat, rv3d->viewquat);
	sms.new_dist= rv3d->dist;
	sms.new_lens= v3d->lens;
	sms.to_camera= 0;

	/* note on camera locking, this is a little confusing but works ok.
	 * we may be changing the view 'as if' there is no active camera, but infact
	 * there is an active camera which is locked to the view.
	 *
	 * In the case where smooth view is moving _to_ a camera we dont want that
	 * camera to be moved or changed, so only when the camera is not being set should
	 * we allow camera option locking to initialize the view settings from the camera.
	 */
	if(camera == NULL && oldcamera == NULL) {
		ED_view3d_camera_lock_init(v3d, rv3d);
	}

	/* store the options we want to end with */
	if(ofs) copy_v3_v3(sms.new_ofs, ofs);
	if(quat) copy_qt_qt(sms.new_quat, quat);
	if(dist) sms.new_dist= *dist;
	if(lens) sms.new_lens= *lens;

	if (camera) {
		ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens);
		sms.to_camera= 1; /* restore view3d values in end */
	}
	
	if (C && U.smooth_viewtx) {
		int changed = 0; /* zero means no difference */
		
		if (oldcamera != camera)
			changed = 1;
		else if (sms.new_dist != rv3d->dist)
			changed = 1;
		else if (sms.new_lens != v3d->lens)
			changed = 1;
		else if (!equals_v3v3(sms.new_ofs, rv3d->ofs))
			changed = 1;
		else if (!equals_v4v4(sms.new_quat, rv3d->viewquat))
			changed = 1;
		
		/* The new view is different from the old one
			* so animate the view */
		if (changed) {

			/* original values */
			if (oldcamera) {
				sms.orig_dist= rv3d->dist; // below function does weird stuff with it...
				ED_view3d_from_object(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens);
			}
			else {
				copy_v3_v3(sms.orig_ofs, rv3d->ofs);
				copy_qt_qt(sms.orig_quat, rv3d->viewquat);
				sms.orig_dist= rv3d->dist;
				sms.orig_lens= v3d->lens;
			}
			/* grid draw as floor */
			if((rv3d->viewlock & RV3D_LOCKED)==0) {
				/* use existing if exists, means multiple calls to smooth view wont loose the original 'view' setting */
				sms.orig_view= rv3d->sms ? rv3d->sms->orig_view : rv3d->view;
				rv3d->view= RV3D_VIEW_USER;
			}

			sms.time_allowed= (double)U.smooth_viewtx / 1000.0;
			
			/* if this is view rotation only
				* we can decrease the time allowed by
				* the angle between quats 
				* this means small rotations wont lag */
			if (quat && !ofs && !dist) {
				float vec1[3]={0,0,1}, vec2[3]= {0,0,1};
				float q1[4], q2[4];

				invert_qt_qt(q1, sms.new_quat);
				invert_qt_qt(q2, sms.orig_quat);

				mul_qt_v3(q1, vec1);
				mul_qt_v3(q2, vec2);

				/* scale the time allowed by the rotation */
				sms.time_allowed *= (double)angle_v3v3(vec1, vec2) / M_PI; /* 180deg == 1.0 */
			}

			/* ensure it shows correct */
			if(sms.to_camera) rv3d->persp= RV3D_PERSP;

			rv3d->rflag |= RV3D_NAVIGATING;
			
			/* keep track of running timer! */
			if(rv3d->sms==NULL)
				rv3d->sms= MEM_mallocN(sizeof(struct SmoothViewStore), "smoothview v3d");
			*rv3d->sms= sms;
			if(rv3d->smooth_timer)
				WM_event_remove_timer(wm, win, rv3d->smooth_timer);
			/* TIMER1 is hardcoded in keymap */
			rv3d->smooth_timer= WM_event_add_timer(wm, win, TIMER1, 1.0/100.0);	/* max 30 frs/sec */
			
			ok= TRUE;
		}
	}
	
	/* if we get here nothing happens */
	if(ok == FALSE) {
		if(sms.to_camera==0) {
			copy_v3_v3(rv3d->ofs, sms.new_ofs);
			copy_qt_qt(rv3d->viewquat, sms.new_quat);
			rv3d->dist = sms.new_dist;
			v3d->lens = sms.new_lens;
		}

		if(rv3d->viewlock & RV3D_BOXVIEW)
			view3d_boxview_copy(sa, ar);

		ED_region_tag_redraw(ar);
	}
}