Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_view3d/view3d_select.c
| Show First 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | |||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_sculpt.h" | #include "ED_sculpt.h" | ||||
| #include "ED_mball.h" | #include "ED_mball.h" | ||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| #include "GPU_draw.h" | #include "GPU_draw.h" | ||||
| #include "GPU_select.h" | |||||
| #include "view3d_intern.h" /* own include */ | #include "view3d_intern.h" /* own include */ | ||||
| float ED_view3d_select_dist_px(void) | float ED_view3d_select_dist_px(void) | ||||
| { | { | ||||
| return 75.0f * U.pixelsize; | return 75.0f * U.pixelsize; | ||||
| } | } | ||||
| /* TODO: should return whether there is valid context to continue */ | /* TODO: should return whether there is valid context to continue */ | ||||
| ▲ Show 20 Lines • Show All 975 Lines • ▼ Show 20 Lines | for (base = FIRSTBASE; base; base = base->next) { | ||||
| if (base->flag & SELECT) { | if (base->flag & SELECT) { | ||||
| if (b != base) { | if (b != base) { | ||||
| ED_base_object_select(base, BA_DESELECT); | ED_base_object_select(base, BA_DESELECT); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static Base *object_mouse_select_menu( | static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffer, int hits, const int mval[2], short toggle) | ||||
| bContext *C, ViewContext *vc, unsigned int *buffer, int hits, | |||||
| const int mval[2], bool toggle) | |||||
| { | { | ||||
| int baseCount = 0; | short baseCount = 0; | ||||
| bool ok; | bool ok; | ||||
| LinkNode *linklist = NULL; | LinkNode *linklist = NULL; | ||||
| CTX_DATA_BEGIN (C, Base *, base, selectable_bases) | CTX_DATA_BEGIN (C, Base *, base, selectable_bases) | ||||
| { | { | ||||
| ok = false; | ok = false; | ||||
| /* two selection methods, the CTRL select uses max dist of 15 */ | /* two selection methods, the CTRL select uses max dist of 15 */ | ||||
| ▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | static int mixed_bones_object_selectbuffer( | ||||
| } | } | ||||
| if (r_do_nearest) { | if (r_do_nearest) { | ||||
| *r_do_nearest = do_nearest; | *r_do_nearest = do_nearest; | ||||
| } | } | ||||
| do_nearest = do_nearest && !enumerate; | do_nearest = do_nearest && !enumerate; | ||||
| const int select_mode = (do_nearest ? VIEW3D_SELECT_PICK_NEAREST : VIEW3D_SELECT_PICK_ALL); | |||||
| int hits = 0; | |||||
| /* we _must_ end cache before return, use 'goto finally' */ | |||||
| GPU_select_cache_begin(); | |||||
| BLI_rcti_init_pt_radius(&rect, mval, 14); | BLI_rcti_init_pt_radius(&rect, mval, 14); | ||||
| hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, do_nearest); | hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode); | ||||
| if (hits15 == 1) { | if (hits15 == 1) { | ||||
| return selectbuffer_ret_hits_15(buffer, hits15); | hits = selectbuffer_ret_hits_15(buffer, hits15); | ||||
| goto finally; | |||||
| } | } | ||||
| else if (hits15 > 0) { | else if (hits15 > 0) { | ||||
| has_bones15 = selectbuffer_has_bones(buffer, hits15); | has_bones15 = selectbuffer_has_bones(buffer, hits15); | ||||
| offs = 4 * hits15; | offs = 4 * hits15; | ||||
| BLI_rcti_init_pt_radius(&rect, mval, 9); | BLI_rcti_init_pt_radius(&rect, mval, 9); | ||||
| hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, do_nearest); | hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode); | ||||
| if (hits9 == 1) { | if (hits9 == 1) { | ||||
| return selectbuffer_ret_hits_9(buffer, hits15, hits9); | hits = selectbuffer_ret_hits_9(buffer, hits15, hits9); | ||||
| goto finally; | |||||
| } | } | ||||
| else if (hits9 > 0) { | else if (hits9 > 0) { | ||||
| has_bones9 = selectbuffer_has_bones(buffer + offs, hits9); | has_bones9 = selectbuffer_has_bones(buffer + offs, hits9); | ||||
| offs += 4 * hits9; | offs += 4 * hits9; | ||||
| BLI_rcti_init_pt_radius(&rect, mval, 5); | BLI_rcti_init_pt_radius(&rect, mval, 5); | ||||
| hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, do_nearest); | hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode); | ||||
| if (hits5 == 1) { | if (hits5 == 1) { | ||||
| return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); | hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); | ||||
| goto finally; | |||||
| } | } | ||||
| else if (hits5 > 0) { | else if (hits5 > 0) { | ||||
| has_bones5 = selectbuffer_has_bones(buffer + offs, hits5); | has_bones5 = selectbuffer_has_bones(buffer + offs, hits5); | ||||
| } | } | ||||
| } | } | ||||
| if (has_bones5) return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); | if (has_bones5) { hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); goto finally; } | ||||
| else if (has_bones9) return selectbuffer_ret_hits_9(buffer, hits15, hits9); | else if (has_bones9) { hits = selectbuffer_ret_hits_9(buffer, hits15, hits9); goto finally; } | ||||
| else if (has_bones15) return selectbuffer_ret_hits_15(buffer, hits15); | else if (has_bones15) { hits = selectbuffer_ret_hits_15(buffer, hits15); goto finally; } | ||||
| if (hits5 > 0) return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); | if (hits5 > 0) { hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); goto finally; } | ||||
| else if (hits9 > 0) return selectbuffer_ret_hits_9(buffer, hits15, hits9); | else if (hits9 > 0) { hits = selectbuffer_ret_hits_9(buffer, hits15, hits9); goto finally; } | ||||
| else return selectbuffer_ret_hits_15(buffer, hits15); | else { hits = selectbuffer_ret_hits_15(buffer, hits15); goto finally; } | ||||
| } | } | ||||
| return 0; | finally: | ||||
| GPU_select_cache_end(); | |||||
| return hits; | |||||
| } | } | ||||
| /* returns basact */ | /* returns basact */ | ||||
| static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int hits, | static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int hits, | ||||
| Base *startbase, bool has_bones, bool do_nearest) | Base *startbase, bool has_bones, bool do_nearest) | ||||
| { | { | ||||
| Scene *scene = vc->scene; | Scene *scene = vc->scene; | ||||
| View3D *v3d = vc->v3d; | View3D *v3d = vc->v3d; | ||||
| ▲ Show 20 Lines • Show All 177 Lines • ▼ Show 20 Lines | else { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| unsigned int buffer[MAXPICKBUF]; | unsigned int buffer[MAXPICKBUF]; | ||||
| bool do_nearest; | bool do_nearest; | ||||
| /* if objects have posemode set, the bones are in the same selection buffer */ | /* if objects have posemode set, the bones are in the same selection buffer */ | ||||
| hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, true, enumerate, &do_nearest); | hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, true, enumerate, &do_nearest); | ||||
| if (hits > 0) { | if (hits > 0) { | ||||
| /* note: bundles are handling in the same way as bones */ | /* note: bundles are handling in the same way as bones */ | ||||
| const bool has_bones = selectbuffer_has_bones(buffer, hits); | const bool has_bones = selectbuffer_has_bones(buffer, hits); | ||||
| /* note; shift+alt goes to group-flush-selecting */ | /* note; shift+alt goes to group-flush-selecting */ | ||||
| if (enumerate) { | if (enumerate) { | ||||
| ▲ Show 20 Lines • Show All 424 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| MetaBall *mb = (MetaBall *)vc->obedit->data; | MetaBall *mb = (MetaBall *)vc->obedit->data; | ||||
| MetaElem *ml; | MetaElem *ml; | ||||
| int a; | int a; | ||||
| unsigned int buffer[MAXPICKBUF]; | unsigned int buffer[MAXPICKBUF]; | ||||
| int hits; | int hits; | ||||
| hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, false); | hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL); | ||||
| if (extend == false && select) | if (extend == false && select) | ||||
| BKE_mball_deselect_all(mb); | BKE_mball_deselect_all(mb); | ||||
| for (ml = mb->editelems->first; ml; ml = ml->next) { | for (ml = mb->editelems->first; ml; ml = ml->next) { | ||||
| for (a = 0; a < hits; a++) { | for (a = 0; a < hits; a++) { | ||||
| if (ml->selcol1 == buffer[(4 * a) + 3]) { | if (ml->selcol1 == buffer[(4 * a) + 3]) { | ||||
| ml->flag |= MB_SCALE_RAD; | ml->flag |= MB_SCALE_RAD; | ||||
| Show All 17 Lines | |||||
| { | { | ||||
| bArmature *arm = vc->obedit->data; | bArmature *arm = vc->obedit->data; | ||||
| EditBone *ebone; | EditBone *ebone; | ||||
| int a; | int a; | ||||
| unsigned int buffer[MAXPICKBUF]; | unsigned int buffer[MAXPICKBUF]; | ||||
| int hits; | int hits; | ||||
| hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, false); | hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL); | ||||
| /* clear flag we use to detect point was affected */ | /* clear flag we use to detect point was affected */ | ||||
| for (ebone = arm->edbo->first; ebone; ebone = ebone->next) | for (ebone = arm->edbo->first; ebone; ebone = ebone->next) | ||||
| ebone->flag &= ~BONE_DONE; | ebone->flag &= ~BONE_DONE; | ||||
| if (extend == false && select) | if (extend == false && select) | ||||
| ED_armature_deselect_all_visible(vc->obedit); | ED_armature_deselect_all_visible(vc->obedit); | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | if (extend == false && select) { | ||||
| } | } | ||||
| else { | else { | ||||
| object_deselect_all_visible(vc->scene, vc->v3d); | object_deselect_all_visible(vc->scene, vc->v3d); | ||||
| } | } | ||||
| } | } | ||||
| /* selection buffer now has bones potentially too, so we add MAXPICKBUF */ | /* selection buffer now has bones potentially too, so we add MAXPICKBUF */ | ||||
| vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(unsigned int), "selection buffer"); | vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(unsigned int), "selection buffer"); | ||||
| hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, false); | hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL); | ||||
| /* | /* | ||||
| * LOGIC NOTES (theeth): | * LOGIC NOTES (theeth): | ||||
| * The buffer and ListBase have the same relative order, which makes the selection | * The buffer and ListBase have the same relative order, which makes the selection | ||||
| * very simple. Loop through both data sets at the same time, if the color | * very simple. Loop through both data sets at the same time, if the color | ||||
| * is the same as the object, we have a hit and can move to the next color | * is the same as the object, we have a hit and can move to the next color | ||||
| * and object pair, if not, just move to the next object, | * and object pair, if not, just move to the next object, | ||||
| * keeping the same color until we have a hit. | * keeping the same color until we have a hit. | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 837 Lines • Show Last 20 Lines | |||||