Beispiel #1
0
/* x and y are mouse coords (area space) */
void *get_nearest_bone(bContext *C, short findunsel, int x, int y)
{
	ViewContext vc;
	rcti rect;
	unsigned int buffer[MAXPICKBUF];
	short hits;
	
	view3d_set_viewcontext(C, &vc);
	
	// rect.xmin = ... mouseco!
	rect.xmin = rect.xmax = x;
	rect.ymin = rect.ymax = y;
	
	hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true);

	if (hits > 0)
		return get_bone_from_selectbuffer(vc.scene, vc.scene->basact, buffer, hits, findunsel, true);
	
	return NULL;
}
Beispiel #2
0
/* Select MetaElement with mouse click (user can select radius circle or
 * stiffness circle) */
int mouse_mball(bContext *C, const int mval[2], int extend, int deselect, int toggle)
{
	static MetaElem *startelem = NULL;
	Object *obedit = CTX_data_edit_object(C);
	ViewContext vc;
	MetaBall *mb = (MetaBall *)obedit->data;
	MetaElem *ml, *ml_act = NULL;
	int a, hits;
	unsigned int buffer[4 * MAXPICKBUF];
	rcti rect;

	view3d_set_viewcontext(C, &vc);

	rect.xmin = mval[0] - 12;
	rect.xmax = mval[0] + 12;
	rect.ymin = mval[1] - 12;
	rect.ymax = mval[1] + 12;

	hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect);

	/* does startelem exist? */
	ml = mb->editelems->first;
	while (ml) {
		if (ml == startelem) break;
		ml = ml->next;
	}

	if (ml == NULL) startelem = mb->editelems->first;
	
	if (hits > 0) {
		ml = startelem;
		while (ml) {
			for (a = 0; a < hits; a++) {
				/* index converted for gl stuff */
				if (ml->selcol1 == buffer[4 * a + 3]) {
					ml->flag |= MB_SCALE_RAD;
					ml_act = ml;
				}
				if (ml->selcol2 == buffer[4 * a + 3]) {
					ml->flag &= ~MB_SCALE_RAD;
					ml_act = ml;
				}
			}
			if (ml_act) break;
			ml = ml->next;
			if (ml == NULL) ml = mb->editelems->first;
			if (ml == startelem) break;
		}
		
		/* When some metaelem was found, then it is necessary to select or
		 * deselect it. */
		if (ml_act) {
			if (extend) {
				ml_act->flag |= SELECT;
			}
			else if (deselect) {
				ml_act->flag &= ~SELECT;
			}
			else if (toggle) {
				if (ml_act->flag & SELECT)
					ml_act->flag &= ~SELECT;
				else
					ml_act->flag |= SELECT;
			}
			else {
				/* Deselect all existing metaelems */
				BKE_mball_deselect_all(mb);

				/* Select only metaelem clicked on */
				ml_act->flag |= SELECT;
			}
			
			mb->lastelem = ml_act;
			
			WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb);

			return 1;
		}
	}

	return 0;
}
/* note that BONE ROOT only gets drawn for root bones (or without IK) */
static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2],
                                           ListBase *edbo, int findunsel, int *selmask)
{
	bArmature *arm = (bArmature *)vc->obedit->data;
	EditBone *ebone_next_act = arm->act_edbone;

	EditBone *ebone;
	rcti rect;
	unsigned int buffer[MAXPICKBUF];
	unsigned int hitresult, besthitresult = BONESEL_NOSEL;
	int i, mindep = 4;
	short hits;

	glInitNames();
	
	/* find the bone after the current active bone, so as to bump up its chances in selection.
	 * this way overlapping bones will cycle selection state as with objects. */
	if (ebone_next_act &&
	    EBONE_VISIBLE(arm, ebone_next_act) &&
	    ebone_next_act->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL))
	{
		ebone_next_act = ebone_next_act->next ? ebone_next_act->next : arm->edbo->first;
	}
	else {
		ebone_next_act = NULL;
	}

	rect.xmin = mval[0] - 5;
	rect.xmax = mval[0] + 5;
	rect.ymin = mval[1] - 5;
	rect.ymax = mval[1] + 5;

	hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
	if (hits == 0) {
		rect.xmin = mval[0] - 12;
		rect.xmax = mval[0] + 12;
		rect.ymin = mval[1] - 12;
		rect.ymax = mval[1] + 12;
		hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
	}
	/* See if there are any selected bones in this group */
	if (hits > 0) {
		
		if (hits == 1) {
			if (!(buffer[3] & BONESEL_NOSEL)) 
				besthitresult = buffer[3];
		}
		else {
			for (i = 0; i < hits; i++) {
				hitresult = buffer[3 + (i * 4)];
				if (!(hitresult & BONESEL_NOSEL)) {
					int dep;
					
					ebone = BLI_findlink(edbo, hitresult & ~BONESEL_ANY);
					
					/* clicks on bone points get advantage */
					if (hitresult & (BONESEL_ROOT | BONESEL_TIP)) {
						/* but also the unselected one */
						if (findunsel) {
							if ( (hitresult & BONESEL_ROOT) && (ebone->flag & BONE_ROOTSEL) == 0)
								dep = 1;
							else if ( (hitresult & BONESEL_TIP) && (ebone->flag & BONE_TIPSEL) == 0)
								dep = 1;
							else 
								dep = 2;
						}
						else {
							dep = 2;
						}
					}
					else {
						/* bone found */
						if (findunsel) {
							if ((ebone->flag & BONE_SELECTED) == 0)
								dep = 2;
							else
								dep = 3;
						}
						else {
							dep = 3;
						}
					}

					if (ebone == ebone_next_act) {
						dep -= 1;
					}

					if (dep < mindep) {
						mindep = dep;
						besthitresult = hitresult;
					}
				}
			}
		}
		
		if (!(besthitresult & BONESEL_NOSEL)) {
			
			ebone = BLI_findlink(edbo, besthitresult & ~BONESEL_ANY);
			
			*selmask = 0;
			if (besthitresult & BONESEL_ROOT)
				*selmask |= BONE_ROOTSEL;
			if (besthitresult & BONESEL_TIP)
				*selmask |= BONE_TIPSEL;
			if (besthitresult & BONESEL_BONE)
				*selmask |= BONE_SELECTED;
			return ebone;
		}
	}
	*selmask = 0;
	return NULL;
}