コード例 #1
0
ファイル: view3d_view.c プロジェクト: greg100795/blender-git
/**
 * \warning be sure to account for a negative return value
 * This is an error, "Too many objects in select buffer"
 * and no action should be taken (can crash blender) if this happens
 *
 * \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection.
 */
short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input, bool do_nearest)
{
	Scene *scene = vc->scene;
	View3D *v3d = vc->v3d;
	ARegion *ar = vc->ar;
	rctf rect;
	short hits;
	const bool use_obedit_skip = (scene->obedit != NULL) && (vc->obedit == NULL);
	const bool do_passes = do_nearest && GPU_select_query_check_active();

	G.f |= G_PICKSEL;
	
	/* case not a border select */
	if (input->xmin == input->xmax) {
		rect.xmin = input->xmin - 12;  /* seems to be default value for bones only now */
		rect.xmax = input->xmin + 12;
		rect.ymin = input->ymin - 12;
		rect.ymax = input->ymin + 12;
	}
	else {
		BLI_rctf_rcti_copy(&rect, input);
	}
	
	view3d_winmatrix_set(ar, v3d, &rect);
	mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
	
	if (v3d->drawtype > OB_WIRE) {
		v3d->zbuf = true;
		glEnable(GL_DEPTH_TEST);
	}
	
	if (vc->rv3d->rflag & RV3D_CLIPPING)
		ED_view3d_clipping_set(vc->rv3d);
	
	if (do_passes)
		GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
	else
		GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_ALL, 0);

	view3d_select_loop(vc, scene, v3d, ar, use_obedit_skip);

	hits = GPU_select_end();
	
	/* second pass, to get the closest object to camera */
	if (do_passes) {
		GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);

		view3d_select_loop(vc, scene, v3d, ar, use_obedit_skip);

		GPU_select_end();
	}

	G.f &= ~G_PICKSEL;
	view3d_winmatrix_set(ar, v3d, NULL);
	mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
	
	if (v3d->drawtype > OB_WIRE) {
		v3d->zbuf = 0;
		glDisable(GL_DEPTH_TEST);
	}
// XXX	persp(PERSP_WIN);
	
	if (vc->rv3d->rflag & RV3D_CLIPPING)
		ED_view3d_clipping_disable();
	
	if (hits < 0) printf("Too many objects in select buffer\n");  /* XXX make error message */

	return hits;
}
コード例 #2
0
/* Warning: be sure to account for a negative return value
 *   This is an error, "Too many objects in select buffer"
 *   and no action should be taken (can crash blender) if this happens
 */
short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int bufsize, rcti *input)
{
	Scene *scene = vc->scene;
	View3D *v3d = vc->v3d;
	ARegion *ar = vc->ar;
	rctf rect;
	short code, hits;
	char dt;
	short dtx;
	
	G.f |= G_PICKSEL;
	
	/* case not a border select */
	if (input->xmin == input->xmax) {
		rect.xmin = input->xmin - 12;  /* seems to be default value for bones only now */
		rect.xmax = input->xmin + 12;
		rect.ymin = input->ymin - 12;
		rect.ymax = input->ymin + 12;
	}
	else {
		BLI_rctf_rcti_copy(&rect, input);
	}
	
	setwinmatrixview3d(ar, v3d, &rect);
	mult_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
	
	if (v3d->drawtype > OB_WIRE) {
		v3d->zbuf = TRUE;
		glEnable(GL_DEPTH_TEST);
	}
	
	if (vc->rv3d->rflag & RV3D_CLIPPING)
		ED_view3d_clipping_set(vc->rv3d);
	
	glSelectBuffer(bufsize, (GLuint *)buffer);
	glRenderMode(GL_SELECT);
	glInitNames();  /* these two calls whatfor? It doesnt work otherwise */
	glPushName(-1);
	code = 1;
	
	if (vc->obedit && vc->obedit->type == OB_MBALL) {
		draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
	}
	else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
		/* if not drawing sketch, draw bones */
		if (!BDR_drawSketchNames(vc)) {
			draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
		}
	}
	else {
		Base *base;
		
		v3d->xray = TRUE;  /* otherwise it postpones drawing */
		for (base = scene->base.first; base; base = base->next) {
			if (base->lay & v3d->lay) {
				
				if (base->object->restrictflag & OB_RESTRICT_SELECT)
					base->selcol = 0;
				else {
					base->selcol = code;
					glLoadName(code);
					draw_object(scene, ar, v3d, base, DRAW_PICKING | DRAW_CONSTCOLOR);
					
					/* we draw duplicators for selection too */
					if ((base->object->transflag & OB_DUPLI)) {
						ListBase *lb;
						DupliObject *dob;
						Base tbase;
						
						tbase.flag = OB_FROMDUPLI;
						lb = object_duplilist(scene, base->object, false);
						
						for (dob = lb->first; dob; dob = dob->next) {
							tbase.object = dob->ob;
							copy_m4_m4(dob->ob->obmat, dob->mat);
							
							/* extra service: draw the duplicator in drawtype of parent */
							/* MIN2 for the drawtype to allow bounding box objects in groups for lods */
							dt = tbase.object->dt;   tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
							dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;

							draw_object(scene, ar, v3d, &tbase, DRAW_PICKING | DRAW_CONSTCOLOR);
							
							tbase.object->dt = dt;
							tbase.object->dtx = dtx;

							copy_m4_m4(dob->ob->obmat, dob->omat);
						}
						free_object_duplilist(lb);
					}
					code++;
				}
			}
		}
		v3d->xray = false;  /* restore */
	}
	
	glPopName();    /* see above (pushname) */
	hits = glRenderMode(GL_RENDER);
	
	G.f &= ~G_PICKSEL;
	setwinmatrixview3d(ar, v3d, NULL);
	mult_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
	
	if (v3d->drawtype > OB_WIRE) {
		v3d->zbuf = 0;
		glDisable(GL_DEPTH_TEST);
	}
// XXX	persp(PERSP_WIN);
	
	if (vc->rv3d->rflag & RV3D_CLIPPING)
		ED_view3d_clipping_disable();
	
	if (hits < 0) printf("Too many objects in select buffer\n");  /* XXX make error message */

	return hits;
}