/** * \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; }
/* 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; }