/* helper func - draw keyframe vertices only for an F-Curve */ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu) { FPoint *first, *last; float hsize, xscale, yscale; /* get view settings */ hsize = UI_GetThemeValuef(TH_VERTEX_SIZE); UI_view2d_getscale(&ar->v2d, &xscale, &yscale); /* set vertex color */ if (fcu->flag & (FCURVE_ACTIVE | FCURVE_SELECTED)) UI_ThemeColor(TH_TEXT_HI); else UI_ThemeColor(TH_TEXT); /* get verts */ first = fcu->fpt; last = (first) ? (first + (fcu->totvert - 1)) : (NULL); /* draw */ if (first && last) { /* anti-aliased lines for more consistent appearance */ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); draw_fcurve_sample_control(first->vec[0], first->vec[1], xscale, yscale, hsize); draw_fcurve_sample_control(last->vec[0], last->vec[1], xscale, yscale, hsize); glDisable(GL_BLEND); if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH); } }
static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) { MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); int width, height; struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata; BKE_movieclip_get_size(clip, &sc->user, &width, &height); if(!width || !height) return; /* non-selected knot handles */ userdata.hsize= UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); userdata.sel= 0; userdata.act_track= act_track; UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale); clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL); /* draw graph lines */ glEnable(GL_BLEND); clip_graph_tracking_values_iterate(sc, act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb); glDisable(GL_BLEND); /* selected knot handles on top of curves */ userdata.sel= 1; clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL); }
static void draw_fcurve_vertices(SpaceIpo *sipo, ARegion *ar, FCurve *fcu, short do_handles, short sel_handle_only, float units_scale) { View2D *v2d = &ar->v2d; /* only draw points if curve is visible * - draw unselected points before selected points as separate passes to minimize color-changing overhead * (XXX dunno if this is faster than drawing all in one pass though) * and also to make sure in the case of overlapping points that the selected is always visible * - draw handles before keyframes, so that keyframes will overlap handles (keyframes are more important for users) */ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); /* draw the two handles first (if they're shown, the curve doesn't have just a single keyframe, and the curve is being edited) */ if (do_handles) { set_fcurve_vertex_color(fcu, 0); draw_fcurve_vertices_handles(fcu, sipo, v2d, 0, sel_handle_only, units_scale); set_fcurve_vertex_color(fcu, 1); draw_fcurve_vertices_handles(fcu, sipo, v2d, 1, sel_handle_only, units_scale); } /* draw keyframes over the handles */ set_fcurve_vertex_color(fcu, 0); draw_fcurve_vertices_keyframes(fcu, sipo, v2d, !(fcu->flag & FCURVE_PROTECTED), 0); set_fcurve_vertex_color(fcu, 1); draw_fcurve_vertices_keyframes(fcu, sipo, v2d, !(fcu->flag & FCURVE_PROTECTED), 1); glPointSize(1.0f); }
/* helper func - draw handle vertices only for an F-Curve (if it is not protected) */ static void draw_fcurve_vertices_handles(FCurve *fcu, SpaceIpo *sipo, View2D *v2d, short sel, short sel_handle_only, float units_scale) { BezTriple *bezt = fcu->bezt; BezTriple *prevbezt = NULL; float hsize, xscale, yscale; int i; /* get view settings */ hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize; UI_view2d_getscale(v2d, &xscale, &yscale); /* Compensate OGL scale sued for unit mapping, so circle will be circle, not ellipse */ yscale *= units_scale; /* set handle color */ if (sel) UI_ThemeColor(TH_HANDLE_VERTEX_SELECT); else UI_ThemeColor(TH_HANDLE_VERTEX); /* anti-aliased lines for more consistent appearance */ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); for (i = 0; i < fcu->totvert; i++, prevbezt = bezt, bezt++) { /* Draw the editmode handles for a bezier curve (others don't have handles) * if their selection status matches the selection status we're drawing for * - first handle only if previous beztriple was bezier-mode * - second handle only if current beztriple is bezier-mode * * Also, need to take into account whether the keyframe was selected * if a Graph Editor option to only show handles of selected keys is on. */ if (!sel_handle_only || BEZSELECTED(bezt)) { if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) { if ((bezt->f1 & SELECT) == sel) /* && v2d->cur.xmin < bezt->vec[0][0] < v2d->cur.xmax)*/ draw_fcurve_handle_control(bezt->vec[0][0], bezt->vec[0][1], xscale, yscale, hsize); } if (bezt->ipo == BEZT_IPO_BEZ) { if ((bezt->f3 & SELECT) == sel) /* && v2d->cur.xmin < bezt->vec[2][0] < v2d->cur.xmax)*/ draw_fcurve_handle_control(bezt->vec[2][0], bezt->vec[2][1], xscale, yscale, hsize); } } } if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); }
static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc) { MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); int width, height; TrackMotionCurveUserData userdata; BKE_movieclip_get_size(clip, &sc->user, &width, &height); if (!width || !height) return; /* non-selected knot handles */ userdata.hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); userdata.sel = false; userdata.act_track = act_track; UI_view2d_scale_get(v2d, &userdata.xscale, &userdata.yscale); clip_graph_tracking_values_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, &userdata, tracking_segment_knot_cb, NULL, NULL); /* draw graph lines */ glEnable(GL_BLEND); clip_graph_tracking_values_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb); glDisable(GL_BLEND); /* selected knot handles on top of curves */ userdata.sel = true; clip_graph_tracking_values_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, &userdata, tracking_segment_knot_cb, NULL, NULL); }
static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *arg) { Scene *scene = CTX_data_scene(C); UnitSettings *unit = &scene->unit; RulerItem *ruler_item; RulerInfo *ruler_info = arg; RegionView3D *rv3d = ruler_info->ar->regiondata; // ARegion *ar = ruler_info->ar; const float cap_size = 4.0f; const float bg_margin = 4.0f * U.pixelsize; const float bg_radius = 4.0f * U.pixelsize; const float arc_size = 64.0f * U.pixelsize; #define ARC_STEPS 24 const int arc_steps = ARC_STEPS; int i; //unsigned int color_act = 0x666600; unsigned int color_act = 0xffffff; unsigned int color_base = 0x0; unsigned char color_back[4] = {0xff, 0xff, 0xff, 0x80}; unsigned char color_text[3]; unsigned char color_wire[3]; /* anti-aliased lines for more consistent appearance */ glEnable(GL_LINE_SMOOTH); BLF_enable(blf_mono_font, BLF_ROTATION); BLF_size(blf_mono_font, 14 * U.pixelsize, U.dpi); BLF_rotation(blf_mono_font, 0.0f); UI_GetThemeColor3ubv(TH_TEXT, color_text); UI_GetThemeColor3ubv(TH_WIRE, color_wire); for (ruler_item = ruler_info->items.first, i = 0; ruler_item; ruler_item = ruler_item->next, i++) { const bool is_act = (i == ruler_info->item_active); float dir_ruler[2]; float co_ss[3][2]; int j; /* should these be checked? - ok for now not to */ for (j = 0; j < 3; j++) { ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP); } glEnable(GL_BLEND); cpack(is_act ? color_act : color_base); if (ruler_item->flag & RULERITEM_USE_ANGLE) { glBegin(GL_LINE_STRIP); for (j = 0; j < 3; j++) { glVertex2fv(co_ss[j]); } glEnd(); cpack(0xaaaaaa); setlinestyle(3); glBegin(GL_LINE_STRIP); for (j = 0; j < 3; j++) { glVertex2fv(co_ss[j]); } glEnd(); setlinestyle(0); /* arc */ { float dir_tmp[3]; float co_tmp[3]; float arc_ss_coords[ARC_STEPS + 1][2]; float dir_a[3]; float dir_b[3]; float quat[4]; float axis[3]; float angle; const float px_scale = (ED_view3d_pixel_size(rv3d, ruler_item->co[1]) * min_fff(arc_size, len_v2v2(co_ss[0], co_ss[1]) / 2.0f, len_v2v2(co_ss[2], co_ss[1]) / 2.0f)); sub_v3_v3v3(dir_a, ruler_item->co[0], ruler_item->co[1]); sub_v3_v3v3(dir_b, ruler_item->co[2], ruler_item->co[1]); normalize_v3(dir_a); normalize_v3(dir_b); cross_v3_v3v3(axis, dir_a, dir_b); angle = angle_normalized_v3v3(dir_a, dir_b); axis_angle_to_quat(quat, axis, angle / arc_steps); copy_v3_v3(dir_tmp, dir_a); glColor3ubv(color_wire); for (j = 0; j <= arc_steps; j++) { madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale); ED_view3d_project_float_global(ar, co_tmp, arc_ss_coords[j], V3D_PROJ_TEST_NOP); mul_qt_v3(quat, dir_tmp); } glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, arc_ss_coords); glDrawArrays(GL_LINE_STRIP, 0, arc_steps + 1); glDisableClientState(GL_VERTEX_ARRAY); } /* text */ { char numstr[256]; float numstr_size[2]; float pos[2]; const int prec = 2; /* XXX, todo, make optional */ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec); BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]); pos[0] = co_ss[1][0] + (cap_size * 2.0f); pos[1] = co_ss[1][1] - (numstr_size[1] / 2.0f); /* draw text (bg) */ glColor4ubv(color_back); uiSetRoundBox(UI_CNR_ALL); uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin, pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1], bg_radius); /* draw text */ glColor3ubv(color_text); BLF_position(blf_mono_font, pos[0], pos[1], 0.0f); BLF_rotation(blf_mono_font, 0.0f); BLF_draw(blf_mono_font, numstr, sizeof(numstr)); } /* capping */ { float rot_90_vec_a[2]; float rot_90_vec_b[2]; float cap[2]; sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[1]); rot_90_vec_a[0] = -dir_ruler[1]; rot_90_vec_a[1] = dir_ruler[0]; normalize_v2(rot_90_vec_a); sub_v2_v2v2(dir_ruler, co_ss[1], co_ss[2]); rot_90_vec_b[0] = -dir_ruler[1]; rot_90_vec_b[1] = dir_ruler[0]; normalize_v2(rot_90_vec_b); glEnable(GL_BLEND); glColor3ubv(color_wire); glBegin(GL_LINES); madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size); glVertex2fv(cap); madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size); glVertex2fv(cap); madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size); glVertex2fv(cap); madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size); glVertex2fv(cap); /* angle vertex */ glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] - cap_size); glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] + cap_size); glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] + cap_size); glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] - cap_size); glEnd(); glDisable(GL_BLEND); } } else { glBegin(GL_LINE_STRIP); for (j = 0; j < 3; j += 2) { glVertex2fv(co_ss[j]); } glEnd(); cpack(0xaaaaaa); setlinestyle(3); glBegin(GL_LINE_STRIP); for (j = 0; j < 3; j += 2) { glVertex2fv(co_ss[j]); } glEnd(); setlinestyle(0); sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]); /* text */ { char numstr[256]; float numstr_size[2]; const int prec = 6; /* XXX, todo, make optional */ float pos[2]; ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec); BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]); mid_v2_v2v2(pos, co_ss[0], co_ss[2]); /* center text */ pos[0] -= numstr_size[0] / 2.0f; pos[1] -= numstr_size[1] / 2.0f; /* draw text (bg) */ glColor4ubv(color_back); uiSetRoundBox(UI_CNR_ALL); uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin, pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1], bg_radius); /* draw text */ glColor3ubv(color_text); BLF_position(blf_mono_font, pos[0], pos[1], 0.0f); BLF_draw(blf_mono_font, numstr, sizeof(numstr)); } /* capping */ { float rot_90_vec[2] = {-dir_ruler[1], dir_ruler[0]}; float cap[2]; normalize_v2(rot_90_vec); glEnable(GL_BLEND); glColor3ubv(color_wire); glBegin(GL_LINES); madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size); glVertex2fv(cap); madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size); glVertex2fv(cap); madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size); glVertex2fv(cap); madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size); glVertex2fv(cap); glEnd(); glDisable(GL_BLEND); } } } glDisable(GL_LINE_SMOOTH); BLF_disable(blf_mono_font, BLF_ROTATION); #undef ARC_STEPS /* draw snap */ if ((ruler_info->snap_flag & RULER_SNAP_OK) && (ruler_info->state == RULER_STATE_DRAG)) { ruler_item = ruler_item_active_get(ruler_info); if (ruler_item) { /* size from drawSnapping */ const float size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE); float co_ss[3]; ED_view3d_project_float_global(ar, ruler_item->co[ruler_item->co_index], co_ss, V3D_PROJ_TEST_NOP); cpack(color_act); circ(co_ss[0], co_ss[1], size * U.pixelsize); } } }
/* draws uv's in the image space */ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) { ToolSettings *ts; Mesh *me= obedit->data; EditMesh *em; EditFace *efa, *efa_act; MTFace *tf, *activetf = NULL; DerivedMesh *finaldm, *cagedm; char col1[4], col2[4]; float pointsize; int drawfaces, interpedges, lastsel, sel; Image *ima= sima->image; em= BKE_mesh_get_editmesh(me); activetf= EM_get_active_mtface(em, &efa_act, NULL, 0); /* will be set to NULL if hidden */ ts= scene->toolsettings; drawfaces= draw_uvs_face_check(scene); if(ts->uv_flag & UV_SYNC_SELECTION) interpedges= (ts->selectmode & SCE_SELECT_VERTEX); else interpedges= (ts->uv_selectmode == UV_SELECT_VERTEX); /* draw other uvs */ if(sima->flag & SI_DRAW_OTHER) draw_uvs_other(sima, scene, obedit, activetf); /* 1. draw shadow mesh */ if(sima->flag & SI_DRAWSHADOW) { /* first try existing derivedmesh */ if(!draw_uvs_dm_shadow(em->derivedFinal)) { /* create one if it does not exist */ cagedm = editmesh_get_derived_cage_and_final(scene, obedit, em, &finaldm, CD_MASK_BAREMESH|CD_MASK_MTFACE); /* when sync selection is enabled, all faces are drawn (except for hidden) * so if cage is the same as the final, theres no point in drawing this */ if(!((ts->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm))) draw_uvs_dm_shadow(finaldm); /* release derivedmesh again */ if(cagedm != finaldm) cagedm->release(cagedm); finaldm->release(finaldm); } } /* 2. draw colored faces */ if(sima->flag & SI_DRAW_STRETCH) { draw_uvs_stretch(sima, scene, em, activetf); } else if(me->drawflag & ME_DRAWFACES) { /* draw transparent faces */ UI_GetThemeColor4ubv(TH_FACE, col1); UI_GetThemeColor4ubv(TH_FACE_SELECT, col2); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); for(efa= em->faces.first; efa; efa= efa->next) { tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); if(uvedit_face_visible(scene, ima, efa, tf)) { efa->tmp.p = tf; if(tf==activetf) continue; /* important the temp pointer is set above */ if(uvedit_face_selected(scene, efa, tf)) glColor4ubv((GLubyte *)col2); else glColor4ubv((GLubyte *)col1); glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); glVertex2fv(tf->uv[0]); glVertex2fv(tf->uv[1]); glVertex2fv(tf->uv[2]); if(efa->v4) glVertex2fv(tf->uv[3]); glEnd(); } else { if(tf == activetf) activetf= NULL; efa->tmp.p = NULL; } } glDisable(GL_BLEND); } else { /* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */ for(efa= em->faces.first; efa; efa= efa->next) { tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); if(uvedit_face_visible(scene, ima, efa, tf)) { efa->tmp.p = tf; } else { if(tf == activetf) activetf= NULL; efa->tmp.p = NULL; } } } /* 3. draw active face stippled */ if(activetf) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); UI_ThemeColor4(TH_EDITMESH_ACTIVE); glEnable(GL_POLYGON_STIPPLE); glPolygonStipple(stipple_quarttone); glBegin(efa_act->v4? GL_QUADS: GL_TRIANGLES); glVertex2fv(activetf->uv[0]); glVertex2fv(activetf->uv[1]); glVertex2fv(activetf->uv[2]); if(efa_act->v4) glVertex2fv(activetf->uv[3]); glEnd(); glDisable(GL_POLYGON_STIPPLE); glDisable(GL_BLEND); } /* 4. draw edges */ if(sima->flag & SI_SMOOTH_UV) { glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } switch(sima->dt_uv) { case SI_UVDT_DASH: for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf) { cpack(0x111111); glBegin(GL_LINE_LOOP); glVertex2fv(tf->uv[0]); glVertex2fv(tf->uv[1]); glVertex2fv(tf->uv[2]); if(efa->v4) glVertex2fv(tf->uv[3]); glEnd(); setlinestyle(2); cpack(0x909090); glBegin(GL_LINE_STRIP); glVertex2fv(tf->uv[0]); glVertex2fv(tf->uv[1]); glEnd(); glBegin(GL_LINE_STRIP); glVertex2fv(tf->uv[0]); if(efa->v4) glVertex2fv(tf->uv[3]); else glVertex2fv(tf->uv[2]); glEnd(); glBegin(GL_LINE_STRIP); glVertex2fv(tf->uv[1]); glVertex2fv(tf->uv[2]); if(efa->v4) glVertex2fv(tf->uv[3]); glEnd(); setlinestyle(0); } } break; case SI_UVDT_BLACK: /* black/white */ case SI_UVDT_WHITE: if(sima->dt_uv==SI_UVDT_WHITE) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(0.0f, 0.0f, 0.0f); for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf) { glBegin(GL_LINE_LOOP); glVertex2fv(tf->uv[0]); glVertex2fv(tf->uv[1]); glVertex2fv(tf->uv[2]); if(efa->v4) glVertex2fv(tf->uv[3]); glEnd(); } } break; case SI_UVDT_OUTLINE: glLineWidth(3); cpack(0x0); for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf) { glBegin(GL_LINE_LOOP); glVertex2fv(tf->uv[0]); glVertex2fv(tf->uv[1]); glVertex2fv(tf->uv[2]); if(efa->v4) glVertex2fv(tf->uv[3]); glEnd(); } } glLineWidth(1); col2[0] = col2[1] = col2[2] = 192; col2[3] = 255; glColor4ubv((unsigned char *)col2); if(me->drawflag & ME_DRAWEDGES) { UI_GetThemeColor4ubv(TH_VERTEX_SELECT, col1); lastsel = sel = 0; if(interpedges) { glShadeModel(GL_SMOOTH); for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf) { glBegin(GL_LINE_LOOP); sel = (uvedit_uv_selected(scene, efa, tf, 0)? 1 : 0); if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } glVertex2fv(tf->uv[0]); sel = uvedit_uv_selected(scene, efa, tf, 1)? 1 : 0; if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } glVertex2fv(tf->uv[1]); sel = uvedit_uv_selected(scene, efa, tf, 2)? 1 : 0; if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } glVertex2fv(tf->uv[2]); if(efa->v4) { sel = uvedit_uv_selected(scene, efa, tf, 3)? 1 : 0; if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } glVertex2fv(tf->uv[3]); } glEnd(); } } glShadeModel(GL_FLAT); } else { for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf) { glBegin(GL_LINES); sel = (uvedit_edge_selected(scene, efa, tf, 0)? 1 : 0); if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } glVertex2fv(tf->uv[0]); glVertex2fv(tf->uv[1]); sel = uvedit_edge_selected(scene, efa, tf, 1)? 1 : 0; if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } glVertex2fv(tf->uv[1]); glVertex2fv(tf->uv[2]); sel = uvedit_edge_selected(scene, efa, tf, 2)? 1 : 0; if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } glVertex2fv(tf->uv[2]); if(efa->v4) { glVertex2fv(tf->uv[3]); sel = uvedit_edge_selected(scene, efa, tf, 3)? 1 : 0; if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } glVertex2fv(tf->uv[3]); } glVertex2fv(tf->uv[0]); glEnd(); } } } } else { /* no nice edges */ for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf) { glBegin(GL_LINE_LOOP); glVertex2fv(tf->uv[0]); glVertex2fv(tf->uv[1]); glVertex2fv(tf->uv[2]); if(efa->v4) glVertex2fv(tf->uv[3]); glEnd(); } } } break; } if(sima->flag & SI_SMOOTH_UV) { glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); } /* 5. draw face centers */ if(drawfaces) { float cent[2]; pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE); glPointSize(pointsize); // TODO - drawobject.c changes this value after - Investigate! /* unselected faces */ UI_ThemeColor(TH_WIRE); bglBegin(GL_POINTS); for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf && !uvedit_face_selected(scene, efa, tf)) { uv_center(tf->uv, cent, efa->v4 != NULL); bglVertex2fv(cent); } } bglEnd(); /* selected faces */ UI_ThemeColor(TH_FACE_DOT); bglBegin(GL_POINTS); for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf && uvedit_face_selected(scene, efa, tf)) { uv_center(tf->uv, cent, efa->v4 != NULL); bglVertex2fv(cent); } } bglEnd(); } /* 6. draw uv vertices */ if(drawfaces != 2) { /* 2 means Mesh Face Mode */ /* unselected uvs */ UI_ThemeColor(TH_VERTEX); pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE); glPointSize(pointsize); bglBegin(GL_POINTS); for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf) { if(!uvedit_uv_selected(scene, efa, tf, 0)) bglVertex2fv(tf->uv[0]); if(!uvedit_uv_selected(scene, efa, tf, 1)) bglVertex2fv(tf->uv[1]); if(!uvedit_uv_selected(scene, efa, tf, 2)) bglVertex2fv(tf->uv[2]); if(efa->v4 && !uvedit_uv_selected(scene, efa, tf, 3)) bglVertex2fv(tf->uv[3]); } } bglEnd(); /* pinned uvs */ /* give odd pointsizes odd pin pointsizes */ glPointSize(pointsize*2 + (((int)pointsize % 2)? (-1): 0)); cpack(0xFF); bglBegin(GL_POINTS); for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf) { if(tf->unwrap & TF_PIN1) bglVertex2fv(tf->uv[0]); if(tf->unwrap & TF_PIN2) bglVertex2fv(tf->uv[1]); if(tf->unwrap & TF_PIN3) bglVertex2fv(tf->uv[2]); if(efa->v4 && (tf->unwrap & TF_PIN4)) bglVertex2fv(tf->uv[3]); } } bglEnd(); /* selected uvs */ UI_ThemeColor(TH_VERTEX_SELECT); glPointSize(pointsize); bglBegin(GL_POINTS); for(efa= em->faces.first; efa; efa= efa->next) { tf= (MTFace *)efa->tmp.p; /* visible faces cached */ if(tf) { if(uvedit_uv_selected(scene, efa, tf, 0)) bglVertex2fv(tf->uv[0]); if(uvedit_uv_selected(scene, efa, tf, 1)) bglVertex2fv(tf->uv[1]); if(uvedit_uv_selected(scene, efa, tf, 2)) bglVertex2fv(tf->uv[2]); if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) bglVertex2fv(tf->uv[3]); } } bglEnd(); } glPointSize(1.0); BKE_mesh_end_editmesh(obedit->data, em); }
/* return non-zero if spline is selected */ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline, const char draw_flag, const char draw_type, const float xscale, const float yscale) { const bool is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; const bool is_smooth = (draw_flag & MASK_DRAWFLAG_SMOOTH) != 0; unsigned char rgb_spline[4]; MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); SpaceClip *sc = CTX_wm_space_clip(C); bool undistort = false; int i, handle_size, tot_feather_point; float (*feather_points)[2], (*fp)[2]; float min[2], max[2]; if (!spline->tot_point) return; if (sc) undistort = sc->clip && (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT); /* TODO, add this to sequence editor */ handle_size = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize; glPointSize(handle_size); mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline); /* feather points */ feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); for (i = 0; i < spline->tot_point; i++) { /* watch it! this is intentionally not the deform array, only check for sel */ MaskSplinePoint *point = &spline->points[i]; int j; for (j = 0; j <= point->tot_uw; j++) { float feather_point[2]; bool sel = false; copy_v2_v2(feather_point, *fp); if (undistort) mask_point_undistort_pos(sc, feather_point, feather_point); if (j == 0) { sel = MASKPOINT_ISSEL_ANY(point); } else { sel = (point->uw[j - 1].flag & SELECT) != 0; } if (sel) { if (point == masklay->act_point) glColor3f(1.0f, 1.0f, 1.0f); else UI_ThemeColor(TH_HANDLE_VERTEX_SELECT); } else { UI_ThemeColor(TH_HANDLE_VERTEX); } glBegin(GL_POINTS); glVertex2fv(feather_point); glEnd(); fp++; } } MEM_freeN(feather_points); if (is_smooth) { glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } /* control points */ INIT_MINMAX2(min, max); for (i = 0; i < spline->tot_point; i++) { /* watch it! this is intentionally not the deform array, only check for sel */ MaskSplinePoint *point = &spline->points[i]; MaskSplinePoint *point_deform = &points_array[i]; BezTriple *bezt = &point_deform->bezt; float vert[2]; copy_v2_v2(vert, bezt->vec[1]); if (undistort) { mask_point_undistort_pos(sc, vert, vert); } /* draw handle segment */ if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) { float handle[2]; BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_STICK, handle); if (undistort) { mask_point_undistort_pos(sc, handle, handle); } draw_single_handle(masklay, point, MASK_WHICH_HANDLE_STICK, draw_type, handle_size, xscale, yscale, vert, handle); } else { float handle_left[2], handle_right[2]; BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_LEFT, handle_left); BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_RIGHT, handle_right); if (undistort) { mask_point_undistort_pos(sc, handle_left, handle_left); mask_point_undistort_pos(sc, handle_left, handle_left); } draw_single_handle(masklay, point, MASK_WHICH_HANDLE_LEFT, draw_type, handle_size, xscale, yscale, vert, handle_left); draw_single_handle(masklay, point, MASK_WHICH_HANDLE_RIGHT, draw_type, handle_size, xscale, yscale, vert, handle_right); } /* draw CV point */ if (MASKPOINT_ISSEL_KNOT(point)) { if (point == masklay->act_point) glColor3f(1.0f, 1.0f, 1.0f); else UI_ThemeColor(TH_HANDLE_VERTEX_SELECT); } else UI_ThemeColor(TH_HANDLE_VERTEX); glBegin(GL_POINTS); glVertex2fv(vert); glEnd(); minmax_v2v2_v2(min, max, vert); } if (is_spline_sel) { float x = (min[0] + max[0]) / 2.0f; float y = (min[1] + max[1]) / 2.0f; /* TODO(sergey): Remove hardcoded colors. */ if (masklay->act_spline == spline) { glColor3ub(255, 255, 255); } else { glColor3ub(255, 255, 0); } draw_circle(x, y, 6.0f, true, xscale, yscale); glColor3ub(0, 0, 0); draw_circle(x, y, 6.0f, false, xscale, yscale); } if (is_smooth) { glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); } }
/* Draw selected verts for strokes being edited */ static void gp_draw_strokes_edit(bGPDframe *gpf, int offsx, int offsy, int winx, int winy, short dflag, const float tcolor[3]) { bGPDstroke *gps; const bool no_xray = (dflag & GP_DRAWDATA_NO_XRAY) != 0; int mask_orig = 0; /* set up depth masks... */ if (dflag & GP_DRAWDATA_ONLY3D) { if (no_xray) { glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig); glDepthMask(0); glEnable(GL_DEPTH_TEST); /* first arg is normally rv3d->dist, but this isn't * available here and seems to work quite well without */ bglPolygonOffset(1.0f, 1.0f); #if 0 glEnable(GL_POLYGON_OFFSET_LINE); glPolygonOffset(-1.0f, -1.0f); #endif } } /* draw stroke verts */ for (gps = gpf->strokes.first; gps; gps = gps->next) { bGPDspoint *pt; float vsize, bsize; int i; /* check if stroke can be drawn */ if (gp_can_draw_stroke(gps, dflag) == false) continue; /* Optimisation: only draw points for selected strokes * We assume that selected points can only occur in * strokes that are selected too. */ if ((gps->flag & GP_STROKE_SELECT) == 0) continue; /* Get size of verts: * - The selected state needs to be larger than the unselected state so that * they stand out more. * - We use the theme setting for size of the unselected verts */ bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE); if ((int)bsize > 8) { vsize = 10.0f; bsize = 8.0f; } else { vsize = bsize + 2; } /* First Pass: Draw all the verts (i.e. these become the unselected state) */ if (tcolor != NULL) { /* for now, we assume that the base color of the points is not too close to the real color */ glColor3fv(tcolor); } else { /* this doesn't work well with the default theme and black strokes... */ UI_ThemeColor(TH_GP_VERTEX); } glPointSize(bsize); glBegin(GL_POINTS); for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) { if (gps->flag & GP_STROKE_3DSPACE) { glVertex3fv(&pt->x); } else { float co[2]; gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co); glVertex2fv(co); } } glEnd(); /* Second Pass: Draw only verts which are selected */ UI_ThemeColor(TH_GP_VERTEX_SELECT); glPointSize(vsize); glBegin(GL_POINTS); for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) { if (pt->flag & GP_SPOINT_SELECT) { if (gps->flag & GP_STROKE_3DSPACE) { glVertex3fv(&pt->x); } else { float co[2]; gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co); glVertex2fv(co); } } } glEnd(); } /* clear depth mask */ if (dflag & GP_DRAWDATA_ONLY3D) { if (no_xray) { glDepthMask(mask_orig); glDisable(GL_DEPTH_TEST); bglPolygonOffset(0.0, 0.0); #if 0 glDisable(GL_POLYGON_OFFSET_LINE); glPolygonOffset(0, 0); #endif } } }
void drawSnapping(const struct bContext *C, TransInfo *t) { unsigned char col[4], selectedCol[4], activeCol[4]; if (!activeSnap(t)) return; UI_GetThemeColor3ubv(TH_TRANSFORM, col); col[3] = 128; UI_GetThemeColor3ubv(TH_SELECT, selectedCol); selectedCol[3] = 128; UI_GetThemeColor3ubv(TH_ACTIVE, activeCol); activeCol[3] = 192; if (t->spacetype == SPACE_VIEW3D) { if (validSnap(t)) { TransSnapPoint *p; View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); float imat[4][4]; float size; glDisable(GL_DEPTH_TEST); size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE); invert_m4_m4(imat, rv3d->viewmat); for (p = t->tsnap.points.first; p; p = p->next) { if (p == t->tsnap.selectedPoint) { glColor4ubv(selectedCol); } else { glColor4ubv(col); } drawcircball(GL_LINE_LOOP, p->co, ED_view3d_pixel_size(rv3d, p->co) * size * 0.75f, imat); } if (t->tsnap.status & POINT_INIT) { glColor4ubv(activeCol); drawcircball(GL_LINE_LOOP, t->tsnap.snapPoint, ED_view3d_pixel_size(rv3d, t->tsnap.snapPoint) * size, imat); } /* draw normal if needed */ if (usingSnappingNormal(t) && validSnappingNormal(t)) { glColor4ubv(activeCol); glBegin(GL_LINES); glVertex3f(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]); glVertex3f(t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0], t->tsnap.snapPoint[1] + t->tsnap.snapNormal[1], t->tsnap.snapPoint[2] + t->tsnap.snapNormal[2]); glEnd(); } if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } } else if (t->spacetype == SPACE_IMAGE) { if (validSnap(t)) { /* This will not draw, and Im nor sure why - campbell */ #if 0 float xuser_asp, yuser_asp; int wi, hi; float w, h; calc_image_view(G.sima, 'f'); // float myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); glLoadIdentity(); ED_space_image_get_aspect(t->sa->spacedata.first, &xuser_aspx, &yuser_asp); ED_space_image_width(t->sa->spacedata.first, &wi, &hi); w = (((float)wi) / IMG_SIZE_FALLBACK) * G.sima->zoom * xuser_asp; h = (((float)hi) / IMG_SIZE_FALLBACK) * G.sima->zoom * yuser_asp; cpack(0xFFFFFF); glTranslate2fv(t->tsnap.snapPoint); //glRectf(0, 0, 1, 1); setlinestyle(0); cpack(0x0); fdrawline(-0.020 / w, 0, -0.1 / w, 0); fdrawline(0.1 / w, 0, 0.020 / w, 0); fdrawline(0, -0.020 / h, 0, -0.1 / h); fdrawline(0, 0.1 / h, 0, 0.020 / h); glTranslatef(-t->tsnap.snapPoint[0], -t->tsnap.snapPoint[1], 0.0f); setlinestyle(0); #endif } } else if (t->spacetype == SPACE_NODE) { if (validSnap(t)) { ARegion *ar = CTX_wm_region(C); TransSnapPoint *p; float size; size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE); glEnable(GL_BLEND); for (p = t->tsnap.points.first; p; p = p->next) { if (p == t->tsnap.selectedPoint) { glColor4ubv(selectedCol); } else { glColor4ubv(col); } ED_node_draw_snap(&ar->v2d, p->co, size, 0); } if (t->tsnap.status & POINT_INIT) { glColor4ubv(activeCol); ED_node_draw_snap(&ar->v2d, t->tsnap.snapPoint, size, t->tsnap.snapNodeBorder); } glDisable(GL_BLEND); } } }