Example #1
0
/** ensure \a v1 is \a dist from \a v2 */
void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist)
{
	if (!equals_v3v3(v2, v1)) {
		float nor[3];

		sub_v3_v3v3(nor, v1, v2);
		normalize_v3(nor);
		madd_v3_v3v3fl(v1, v2, nor, dist);
	}
}
Example #2
0
/* helper to fix a ebone position if its parent has moved due to alignment*/
static void fix_connected_bone(EditBone *ebone)
{
	float diff[3];

	if (!(ebone->parent) || !(ebone->flag & BONE_CONNECTED) || equals_v3v3(ebone->parent->tail, ebone->head))
		return;

	/* if the parent has moved we translate child's head and tail accordingly */
	sub_v3_v3v3(diff, ebone->parent->tail, ebone->head);
	add_v3_v3(ebone->head, diff);
	add_v3_v3(ebone->tail, diff);
}
static void bmbvh_find_face_segment_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
	struct SegmentUserData *bmcb_data = userdata;
	const BMLoop **ltri = bmcb_data->looptris[index];
	float dist, uv[2];
	const float *tri_cos[3];

	bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage);

	if (equals_v3v3(bmcb_data->co_a, tri_cos[0]) ||
	    equals_v3v3(bmcb_data->co_a, tri_cos[1]) ||
	    equals_v3v3(bmcb_data->co_a, tri_cos[2]) ||

	    equals_v3v3(bmcb_data->co_b, tri_cos[0]) ||
	    equals_v3v3(bmcb_data->co_b, tri_cos[1]) ||
	    equals_v3v3(bmcb_data->co_b, tri_cos[2]))
	{
		return;
	}

	if (isect_ray_tri_v3(ray->origin, ray->direction, tri_cos[0], tri_cos[1], tri_cos[2], &dist, uv) &&
	    (dist < hit->dist))
	{
		hit->dist = dist;
		hit->index = index;

		copy_v3_v3(hit->no, ltri[0]->f->no);

		madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);

		copy_v2_v2(bmcb_data->uv, uv);
	}
}
Example #4
0
static void fill_add_joint(EditBone *ebo, short eb_tail, ListBase *points)
{
	EditBonePoint *ebp;
	float vec[3];
	short found = 0;
	
	if (eb_tail) {
		copy_v3_v3(vec, ebo->tail);
	}
	else {
		copy_v3_v3(vec, ebo->head);
	}
	
	for (ebp = points->first; ebp; ebp = ebp->next) {
		if (equals_v3v3(ebp->vec, vec)) {
			if (eb_tail) {
				if ((ebp->head_owner) && (ebp->head_owner->parent == ebo)) {
					/* so this bone's tail owner is this bone */
					ebp->tail_owner = ebo;
					found = 1;
					break;
				}
			}
			else {
				if ((ebp->tail_owner) && (ebo->parent == ebp->tail_owner)) {
					/* so this bone's head owner is this bone */
					ebp->head_owner = ebo;
					found = 1;
					break;
				}
			}
		}
	}
	
	/* allocate a new point if no existing point was related */
	if (found == 0) {
		ebp = MEM_callocN(sizeof(EditBonePoint), "EditBonePoint");
		
		if (eb_tail) {
			copy_v3_v3(ebp->vec, ebo->tail);
			ebp->tail_owner = ebo;
		}
		else {
			copy_v3_v3(ebp->vec, ebo->head);
			ebp->head_owner = ebo;
		}
		
		BLI_addtail(points, ebp);
	}
}
Example #5
0
static int check_undistortion_cache_flags(MovieClip *clip)
{
    MovieClipCache *cache = clip->cache;
    MovieTrackingCamera *camera = &clip->tracking.camera;

    /* check for distortion model changes */
    if (!equals_v2v2(camera->principal, cache->postprocessed.principal))
        return FALSE;

    if (!equals_v3v3(&camera->k1, &cache->postprocessed.k1))
        return FALSE;

    return TRUE;
}
// With A, B and P indicating the three vertices of a given triangle, returns:
// 1 if points A and B are in the same position in the 3D space;
// 2 if the distance between point P and line segment AB is zero; and
// zero otherwise.
int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3[3])
{
	const float eps = 1.0e-6;
	const float eps_sq = eps * eps;

#if 0
	float area = area_tri_v3(v1, v2, v3);
	bool verbose = (area < 1.0e-6);
#endif

	if (equals_v3v3(v1, v2) || equals_v3v3(v2, v3) || equals_v3v3(v1, v3)) {
#if 0
		if (verbose && G.debug & G_DEBUG_FREESTYLE) {
			printf("BlenderFileLoader::testDegenerateTriangle = 1\n");
		}
#endif
		return 1;
	}
	if (dist_squared_to_line_segment_v3(v1, v2, v3) < eps_sq ||
	    dist_squared_to_line_segment_v3(v2, v1, v3) < eps_sq ||
	    dist_squared_to_line_segment_v3(v3, v1, v2) < eps_sq)
	{
#if 0
		if (verbose && G.debug & G_DEBUG_FREESTYLE) {
			printf("BlenderFileLoader::testDegenerateTriangle = 2\n");
		}
#endif
		return 2;
	}
#if 0
	if (verbose && G.debug & G_DEBUG_FREESTYLE) {
		printf("BlenderFileLoader::testDegenerateTriangle = 0\n");
	}
#endif
	return 0;
}
Example #7
0
/* Callback to bvh tree raycast. The tree must have been built using bvhtree_from_mesh_edges.
 * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */
static void mesh_edges_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
	const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
	const MVert *vert = data->vert;
	const MEdge *edge = &data->edge[index];

	const float radius_sq = SQUARE(data->sphere_radius);
	float dist;
	const float *v1, *v2, *r1;
	float r2[3], i1[3], i2[3];
	v1 = vert[edge->v1].co;
	v2 = vert[edge->v2].co;

	/* In case we get a zero-length edge, handle it as a point! */
	if (equals_v3v3(v1, v2)) {
		mesh_verts_spherecast_do(data, index, v1, ray, hit);
		return;
	}

	r1 = ray->origin;
	add_v3_v3v3(r2, r1, ray->direction);

	if (isect_line_line_v3(v1, v2, r1, r2, i1, i2)) {
		/* No hit if intersection point is 'behind' the origin of the ray, or too far away from it. */
		if ((dot_v3v3v3(r1, i2, r2) >= 0.0f) && ((dist = len_v3v3(r1, i2)) < hit->dist)) {
			const float e_fac = line_point_factor_v3(i1, v1, v2);
			if (e_fac < 0.0f) {
				copy_v3_v3(i1, v1);
			}
			else if (e_fac > 1.0f) {
				copy_v3_v3(i1, v2);
			}
			/* Ensure ray is really close enough from edge! */
			if (len_squared_v3v3(i1, i2) <= radius_sq) {
				hit->index = index;
				hit->dist = dist;
				copy_v3_v3(hit->co, i2);
			}
		}
	}
}
Example #8
0
static bool check_undistortion_cache_flags(MovieClip *clip)
{
	MovieClipCache *cache = clip->cache;
	MovieTrackingCamera *camera = &clip->tracking.camera;

	/* check for distortion model changes */
	if (!equals_v2v2(camera->principal, cache->postprocessed.principal)) {
		return false;
	}

	if (camera->distortion_model != cache->postprocessed.distortion_model) {
		return false;
	}

	if (!equals_v3v3(&camera->k1, &cache->postprocessed.polynomial_k1)) {
		return false;
	}

	if (!equals_v2v2(&camera->division_k1, &cache->postprocessed.division_k1)) {
		return false;
	}

	return true;
}
Example #9
0
/* Draw the given motion path for an Object or a Bone 
 *  - assumes that the viewport has already been initialized properly
 *    i.e. draw_motion_paths_init() has been called
 */
void draw_motion_path_instance(Scene *scene, 
                               Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath)
{
	//RegionView3D *rv3d = ar->regiondata;
	bMotionPathVert *mpv, *mpv_start;
	int i, stepsize = avs->path_step;
	int sfra, efra, sind, len;
	
	/* get frame ranges */
	if (avs->path_type == MOTIONPATH_TYPE_ACFRA) {
		/* With "Around Current", we only choose frames from around 
		 * the current frame to draw.
		 */
		sfra = CFRA - avs->path_bc;
		efra = CFRA + avs->path_ac;
	}
	else {
		/* Use the current display range */
		sfra = avs->path_sf;
		efra = avs->path_ef;
	}
	
	/* no matter what, we can only show what is in the cache and no more 
	 * - abort if whole range is past ends of path
	 * - otherwise clamp endpoints to extents of path
	 */
	if (sfra < mpath->start_frame) {
		/* start clamp */
		sfra = mpath->start_frame;
	}
	if (efra > mpath->end_frame) {
		/* end clamp */
		efra = mpath->end_frame;
	}
	
	if ((sfra > mpath->end_frame) || (efra < mpath->start_frame)) {
		/* whole path is out of bounds */
		return;
	}
	
	len = efra - sfra;
	
	if ((len <= 0) || (mpath->points == NULL)) {
		return;
	}
	
	/* get pointers to parts of path */
	sind = sfra - mpath->start_frame;
	mpv_start = (mpath->points + sind);
	
	/* draw curve-line of path */
	glShadeModel(GL_SMOOTH);
	
	glBegin(GL_LINE_STRIP);
	for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
		short sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
		float intensity;  /* how faint */
		
		int frame = sfra + i;
		int blend_base = (abs(frame - CFRA) == 1) ? TH_CFRAME : TH_BACK; /* "bleed" cframe color to ease color blending */
		
		/* set color
		 * - more intense for active/selected bones, less intense for unselected bones
		 * - black for before current frame, green for current frame, blue for after current frame
		 * - intensity decreases as distance from current frame increases
		 */
#define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max - min)) + min)
		if (frame < CFRA) {
			/* black - before cfra */
			if (sel) {
				/* intensity = 0.5f; */
				intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f);
			}
			else {
				/* intensity = 0.8f; */
				intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f);
			}
			UI_ThemeColorBlend(TH_WIRE, blend_base, intensity);
		}
		else if (frame > CFRA) {
			/* blue - after cfra */
			if (sel) {
				/* intensity = 0.5f; */
				intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f);
			}
			else {
				/* intensity = 0.8f; */
				intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f);
			}
			UI_ThemeColorBlend(TH_BONE_POSE, blend_base, intensity);
		}
		else {
			/* green - on cfra */
			if (sel) {
				intensity = 0.5f;
			}
			else {
				intensity = 0.99f;
			}
			UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10);
		}
#undef SET_INTENSITY

		/* draw a vertex with this color */
		glVertex3fv(mpv->co);
	}
	
	glEnd();
	glShadeModel(GL_FLAT);
	
	glPointSize(1.0);
	
	/* draw little black point at each frame
	 * NOTE: this is not really visible/noticeable
	 */
	glBegin(GL_POINTS);
	for (i = 0, mpv = mpv_start; i < len; i++, mpv++)
		glVertex3fv(mpv->co);
	glEnd();
	
	/* Draw little white dots at each framestep value */
	UI_ThemeColor(TH_TEXT_HI);
	glBegin(GL_POINTS);
	for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize)
		glVertex3fv(mpv->co);
	glEnd();
	
	/* Draw big green dot where the current frame is 
	 * NOTE: this is only done when keyframes are shown, since this adds similar types of clutter
	 */
	if ((avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) &&
	    (sfra < CFRA) && (CFRA <= efra))
	{
		UI_ThemeColor(TH_CFRAME);
		glPointSize(6.0f);
		
		glBegin(GL_POINTS);
		mpv = mpv_start + (CFRA - sfra);
		glVertex3fv(mpv->co);
		glEnd();
		
		UI_ThemeColor(TH_TEXT_HI);
	}
	
	/* XXX, this isn't up to date but probably should be kept so. */
	invert_m4_m4(ob->imat, ob->obmat);
	
	/* Draw frame numbers at each framestep value */
	if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) {
		unsigned char col[4];
		UI_GetThemeColor3ubv(TH_TEXT_HI, col);
		col[3] = 255;
		
		for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) {
			int frame = sfra + i;
			char numstr[32];
			size_t numstr_len;
			float co[3];
			
			/* only draw framenum if several consecutive highlighted points don't occur on same point */
			if (i == 0) {
				numstr_len = sprintf(numstr, " %d", frame);
				mul_v3_m4v3(co, ob->imat, mpv->co);
				view3d_cached_text_draw_add(co, numstr, numstr_len,
				                            0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
			}
			else if ((i >= stepsize) && (i < len - stepsize)) {
				bMotionPathVert *mpvP = (mpv - stepsize);
				bMotionPathVert *mpvN = (mpv + stepsize);
				
				if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) {
					numstr_len = sprintf(numstr, " %d", frame);
					mul_v3_m4v3(co, ob->imat, mpv->co);
					view3d_cached_text_draw_add(co, numstr, numstr_len,
					                            0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
				}
			}
		}
	}
	
	/* Keyframes - dots and numbers */
	if (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) {
		unsigned char col[4];
		
		AnimData *adt = BKE_animdata_from_id(&ob->id);
		DLRBT_Tree keys;
		
		/* build list of all keyframes in active action for object or pchan */
		BLI_dlrbTree_init(&keys);
		
		if (adt) {
			/* it is assumed that keyframes for bones are all grouped in a single group
			 * unless an option is set to always use the whole action
			 */
			if ((pchan) && (avs->path_viewflag & MOTIONPATH_VIEW_KFACT) == 0) {
				bActionGroup *agrp = BKE_action_group_find_name(adt->action, pchan->name);
				
				if (agrp) {
					agroup_to_keylist(adt, agrp, &keys, NULL);
					BLI_dlrbTree_linkedlist_sync(&keys);
				}
			}
			else {
				action_to_keylist(adt, adt->action, &keys, NULL);
				BLI_dlrbTree_linkedlist_sync(&keys);
			}
		}
		
		/* Draw slightly-larger yellow dots at each keyframe */
		UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
		col[3] = 255;
		
		glPointSize(4.0f);
		glColor3ubv(col);
		
		glBegin(GL_POINTS);
		for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
			int    frame = sfra + i; 
			float mframe = (float)(frame);
			
			if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe))
				glVertex3fv(mpv->co);
		}
		glEnd();
		
		/* Draw frame numbers of keyframes  */
		if (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) {
			float co[3];
			for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
				float mframe = (float)(sfra + i);
				
				if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
					char numstr[32];
					size_t numstr_len;
					
					numstr_len = sprintf(numstr, " %d", (sfra + i));
					mul_v3_m4v3(co, ob->imat, mpv->co);
					view3d_cached_text_draw_add(co, numstr, numstr_len,
					                            0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
				}
			}
		}
		
		BLI_dlrbTree_free(&keys);
	}
}
Example #10
0
static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) 
{
	Object *ob = CTX_data_edit_object(C);
	bArmature *arm = (bArmature *)ob->data;
	ListBase chains = {NULL, NULL};
	LinkData *chain;
	
	/* get chains of bones (ends on chains) */
	chains_find_tips(arm->edbo, &chains);
	if (chains.first == NULL) return OPERATOR_CANCELLED;
	
	/* ensure that mirror bones will also be operated on */
	armature_tag_select_mirrored(arm);
	
	/* clear BONE_TRANSFORM flags 
	 * - used to prevent duplicate/cancelling operations from occurring [#34123] 
	 * - BONE_DONE cannot be used here as that's already used for mirroring
	 */
	armature_clear_swap_done_flags(arm);
	
	/* loop over chains, only considering selected and visible bones */
	for (chain = chains.first; chain; chain = chain->next) {
		EditBone *ebo, *child = NULL, *parent = NULL;
		
		/* loop over bones in chain */
		for (ebo = chain->data; ebo; ebo = parent) {
			/* parent is this bone's original parent
			 *	- we store this, as the next bone that is checked is this one
			 *	  but the value of ebo->parent may change here...
			 */
			parent = ebo->parent;
			
			/* skip bone if already handled... [#34123] */
			if ((ebo->flag & BONE_TRANSFORM) == 0) {
				/* only if selected and editable */
				if (EBONE_VISIBLE(arm, ebo) && EBONE_EDITABLE(ebo)) {
					/* swap head and tail coordinates */
					SWAP(float, ebo->head[0], ebo->tail[0]);
					SWAP(float, ebo->head[1], ebo->tail[1]);
					SWAP(float, ebo->head[2], ebo->tail[2]);
					
					/* do parent swapping:
					 *	- use 'child' as new parent
					 *	- connected flag is only set if points are coincidental
					 */
					ebo->parent = child;
					if ((child) && equals_v3v3(ebo->head, child->tail))
						ebo->flag |= BONE_CONNECTED;
					else
						ebo->flag &= ~BONE_CONNECTED;
					
					/* get next bones 
					 *	- child will become the new parent of next bone
					 */
					child = ebo;
				}
				else {
					/* not swapping this bone, however, if its 'parent' got swapped, unparent us from it 
					 * as it will be facing in opposite direction
					 */
					if ((parent) && (EBONE_VISIBLE(arm, parent) && EBONE_EDITABLE(parent))) {
						ebo->parent = NULL;
						ebo->flag &= ~BONE_CONNECTED;
					}
					
					/* get next bones
					 *	- child will become new parent of next bone (not swapping occurred, 
					 *	  so set to NULL to prevent infinite-loop)
					 */
					child = NULL;
				}
				
				/* tag as done (to prevent double-swaps) */
				ebo->flag |= BONE_TRANSFORM;
			}
		}
Example #11
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);
	}
}
static int select_groped_exec(bContext *C, wmOperator *op)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTrackingTrack *track;
	MovieTrackingMarker *marker;
	MovieTracking *tracking = &clip->tracking;
	ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
	int group = RNA_enum_get(op->ptr, "group");
	int framenr = ED_space_clip_get_clip_frame_number(sc);

	track = tracksbase->first;
	while (track) {
		bool ok = false;

		marker = BKE_tracking_marker_get(track, framenr);

		if (group == 0) { /* Keyframed */
			ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED) == 0;
		}
		else if (group == 1) { /* Estimated */
			ok = marker->framenr != framenr;
		}
		else if (group == 2) { /* tracked */
			ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED);
		}
		else if (group == 3) { /* locked */
			ok = track->flag & TRACK_LOCKED;
		}
		else if (group == 4) { /* disabled */
			ok = marker->flag & MARKER_DISABLED;
		}
		else if (group == 5) { /* color */
			MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);

			if (act_track) {
				ok = (track->flag & TRACK_CUSTOMCOLOR) == (act_track->flag & TRACK_CUSTOMCOLOR);

				if (ok && track->flag & TRACK_CUSTOMCOLOR)
					ok = equals_v3v3(track->color, act_track->color);
			}
		}
		else if (group == 6) { /* failed */
			ok = (track->flag & TRACK_HAS_BUNDLE) == 0;
		}

		if (ok) {
			track->flag |= SELECT;
			if (sc->flag & SC_SHOW_MARKER_PATTERN)
				track->pat_flag |= SELECT;
			if (sc->flag & SC_SHOW_MARKER_SEARCH)
				track->search_flag |= SELECT;
		}

		track = track->next;
	}

	BKE_tracking_dopesheet_tag_update(tracking);

	WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip);

	return OPERATOR_FINISHED;
}
Example #13
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);
	}
}