static void view3d_select_loop(ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar, bool use_obedit_skip) { short code = 1; char dt; short dtx; 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) || (use_obedit_skip && (scene->obedit->data == base->object->data))) { base->selcol = 0; } else { base->selcol = code; if (GPU_select_load_id(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(G.main->eval_ctx, scene, base->object); for (dob = lb->first; dob; dob = dob->next) { float omat[4][4]; tbase.object = dob->ob; copy_m4_m4(omat, dob->ob->obmat); 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, omat); } free_object_duplilist(lb); } } code++; } } } v3d->xray = false; /* restore */ } }
/* 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, 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 { rect.xmin= input->xmin; rect.xmax= input->xmax; rect.ymin= input->ymin; rect.ymax= input->ymax; } 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) view3d_set_clipping(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 group-duplicators for selection too */ if((base->object->transflag & OB_DUPLI) && base->object->dup_group) { ListBase *lb; DupliObject *dob; Base tbase; tbase.flag= OB_FROMDUPLI; lb= object_duplilist(scene, base->object); 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) view3d_clr_clipping(); if(hits<0) printf("Too many objects in select buffer\n"); // XXX make error message return hits; }