static void draw_mesh_text(Scene *scene, Object *ob, int glsl) { Mesh *me = ob->data; DerivedMesh *ddm; MPoly *mp, *mface = me->mpoly; MTexPoly *mtpoly = me->mtpoly; MLoopUV *mloopuv = me->mloopuv; MLoopUV *luv; MLoopCol *mloopcol = me->mloopcol; /* why does mcol exist? */ MLoopCol *lcol; bProperty *prop = BKE_bproperty_object_get(ob, "Text"); GPUVertexAttribs gattribs; int a, totpoly = me->totpoly; /* fake values to pass to GPU_render_text() */ MCol tmp_mcol[4] = {{0}}; MCol *tmp_mcol_pt = mloopcol ? tmp_mcol : NULL; MTFace tmp_tf = {{{0}}}; /* don't draw without tfaces */ if (!mtpoly || !mloopuv) return; /* don't draw when editing */ if (ob->mode & OB_MODE_EDIT) return; else if (ob == OBACT) if (BKE_paint_select_elem_test(ob)) return; ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); for (a = 0, mp = mface; a < totpoly; a++, mtpoly++, mp++) { short matnr = mp->mat_nr; int mf_smooth = mp->flag & ME_SMOOTH; Material *mat = (me->mat) ? me->mat[matnr] : NULL; int mode = mat ? mat->game.flag : GEMAT_INVISIBLE; if (!(mode & GEMAT_INVISIBLE) && (mode & GEMAT_TEXT) && mp->totloop >= 3) { /* get the polygon as a tri/quad */ int mp_vi[4]; float v1[3], v2[3], v3[3], v4[3]; char string[MAX_PROPSTRING]; int characters, i, glattrib = -1, badtex = 0; /* TEXFACE */ ME_MTEXFACE_CPY(&tmp_tf, mtpoly); if (glsl) { GPU_enable_material(matnr + 1, &gattribs); for (i = 0; i < gattribs.totlayer; i++) { if (gattribs.layer[i].type == CD_MTFACE) { glattrib = gattribs.layer[i].glindex; break; } } } else { badtex = set_draw_settings_cached(0, &tmp_tf, mat, Gtexdraw); if (badtex) { continue; } } mp_vi[0] = me->mloop[mp->loopstart + 0].v; mp_vi[1] = me->mloop[mp->loopstart + 1].v; mp_vi[2] = me->mloop[mp->loopstart + 2].v; mp_vi[3] = (mp->totloop >= 4) ? me->mloop[mp->loopstart + 3].v : 0; /* UV */ luv = &mloopuv[mp->loopstart]; copy_v2_v2(tmp_tf.uv[0], luv->uv); luv++; copy_v2_v2(tmp_tf.uv[1], luv->uv); luv++; copy_v2_v2(tmp_tf.uv[2], luv->uv); luv++; if (mp->totloop >= 4) { copy_v2_v2(tmp_tf.uv[3], luv->uv); } /* COLOR */ if (mloopcol) { unsigned int totloop_clamp = min_ii(4, mp->totloop); unsigned int j; lcol = &mloopcol[mp->loopstart]; for (j = 0; j < totloop_clamp; j++, lcol++) { MESH_MLOOPCOL_TO_MCOL(lcol, &tmp_mcol[j]); } } /* LOCATION */ ddm->getVertCo(ddm, mp_vi[0], v1); ddm->getVertCo(ddm, mp_vi[1], v2); ddm->getVertCo(ddm, mp_vi[2], v3); if (mp->totloop >= 4) { ddm->getVertCo(ddm, mp_vi[3], v4); } /* The BM_FONT handling is in the gpu module, shared with the * game engine, was duplicated previously */ BKE_bproperty_set_valstr(prop, string); characters = strlen(string); if (!BKE_image_has_ibuf(mtpoly->tpage, NULL)) characters = 0; if (!mf_smooth) { float nor[3]; normal_tri_v3(nor, v1, v2, v3); glNormal3fv(nor); } GPU_render_text(&tmp_tf, mode, string, characters, (unsigned int *)tmp_mcol_pt, v1, v2, v3, (mp->totloop >= 4 ? v4 : NULL), glattrib); } } ddm->release(ddm); }
void BKE_mask_spline_feather_collapse_inner_loops( MaskSpline *spline, float (*feather_points)[2], const unsigned int tot_feather_point) { #define BUCKET_INDEX(co) \ feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side) int buckets_per_side, tot_bucket; float bucket_size, bucket_scale[2]; FeatherEdgesBucket *buckets; unsigned int i; float min[2], max[2]; float max_delta_x = -1.0f, max_delta_y = -1.0f, max_delta; if (tot_feather_point < 4) { /* self-intersection works only for quads at least, * in other cases polygon can't be self-intersecting anyway */ return; } /* find min/max corners of mask to build buckets in that space */ INIT_MINMAX2(min, max); for (i = 0; i < tot_feather_point; i++) { unsigned int next = i + 1; float delta; minmax_v2v2_v2(min, max, feather_points[i]); if (next == tot_feather_point) { if (spline->flag & MASK_SPLINE_CYCLIC) next = 0; else break; } delta = fabsf(feather_points[i][0] - feather_points[next][0]); if (delta > max_delta_x) max_delta_x = delta; delta = fabsf(feather_points[i][1] - feather_points[next][1]); if (delta > max_delta_y) max_delta_y = delta; } /* prevent divisionsby zero by ensuring bounding box is not collapsed */ if (max[0] - min[0] < FLT_EPSILON) { max[0] += 0.01f; min[0] -= 0.01f; } if (max[1] - min[1] < FLT_EPSILON) { max[1] += 0.01f; min[1] -= 0.01f; } /* use dynamically calculated buckets per side, so we likely wouldn't * run into a situation when segment doesn't fit two buckets which is * pain collecting candidates for intersection */ max_delta_x /= max[0] - min[0]; max_delta_y /= max[1] - min[1]; max_delta = MAX2(max_delta_x, max_delta_y); buckets_per_side = min_ii(512, 0.9f / max_delta); if (buckets_per_side == 0) { /* happens when some segment fills the whole bounding box across some of dimension */ buckets_per_side = 1; } tot_bucket = buckets_per_side * buckets_per_side; bucket_size = 1.0f / buckets_per_side; /* pre-compute multipliers, to save mathematical operations in loops */ bucket_scale[0] = 1.0f / ((max[0] - min[0]) * bucket_size); bucket_scale[1] = 1.0f / ((max[1] - min[1]) * bucket_size); /* fill in buckets' edges */ buckets = MEM_callocN(sizeof(FeatherEdgesBucket) * tot_bucket, "feather buckets"); for (i = 0; i < tot_feather_point; i++) { int start = i, end = i + 1; int start_bucket_index, end_bucket_index; if (end == tot_feather_point) { if (spline->flag & MASK_SPLINE_CYCLIC) end = 0; else break; } start_bucket_index = BUCKET_INDEX(feather_points[start]); end_bucket_index = BUCKET_INDEX(feather_points[end]); feather_bucket_add_edge(&buckets[start_bucket_index], start, end); if (start_bucket_index != end_bucket_index) { FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index]; FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b; feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side, &diagonal_bucket_a, &diagonal_bucket_b); feather_bucket_add_edge(end_bucket, start, end); feather_bucket_add_edge(diagonal_bucket_a, start, end); feather_bucket_add_edge(diagonal_bucket_a, start, end); } } /* check all edges for intersection with edges from their buckets */ for (i = 0; i < tot_feather_point; i++) { int cur_a = i, cur_b = i + 1; int start_bucket_index, end_bucket_index; FeatherEdgesBucket *start_bucket; if (cur_b == tot_feather_point) cur_b = 0; start_bucket_index = BUCKET_INDEX(feather_points[cur_a]); end_bucket_index = BUCKET_INDEX(feather_points[cur_b]); start_bucket = &buckets[start_bucket_index]; feather_bucket_check_intersect(feather_points, tot_feather_point, start_bucket, cur_a, cur_b); if (start_bucket_index != end_bucket_index) { FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index]; FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b; feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side, &diagonal_bucket_a, &diagonal_bucket_b); feather_bucket_check_intersect(feather_points, tot_feather_point, end_bucket, cur_a, cur_b); feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_a, cur_a, cur_b); feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_b, cur_a, cur_b); } } /* free buckets */ for (i = 0; i < tot_bucket; i++) { if (buckets[i].segments) MEM_freeN(buckets[i].segments); } MEM_freeN(buckets); #undef BUCKET_INDEX }
/* called in WM_check, also inits stuff after file read */ void wm_window_add_ghostwindows(wmWindowManager *wm) { wmKeyMap *keymap; wmWindow *win; /* no commandline prefsize? then we set this. * Note that these values will be used only * when there is no startup.blend yet. */ if (wm_init_state.size_x == 0) { wm_get_screensize(&wm_init_state.size_x, &wm_init_state.size_y); /* note!, this isnt quite correct, active screen maybe offset 1000s if PX, * we'd need a wm_get_screensize like function that gives offset, * in practice the window manager will likely move to the correct monitor */ wm_init_state.start_x = 0; wm_init_state.start_y = 0; #if !defined(__APPLE__) && !defined(WIN32) /* X11 */ /* X11, start maximized but use default sane size */ wm_init_state.size_x = min_ii(wm_init_state.size_x, WM_WIN_INIT_SIZE_X); wm_init_state.size_y = min_ii(wm_init_state.size_y, WM_WIN_INIT_SIZE_Y); /* pad */ wm_init_state.start_x = WM_WIN_INIT_PAD; wm_init_state.start_y = WM_WIN_INIT_PAD; wm_init_state.size_x -= WM_WIN_INIT_PAD * 2; wm_init_state.size_y -= WM_WIN_INIT_PAD * 2; #endif } for (win = wm->windows.first; win; win = win->next) { if (win->ghostwin == NULL) { if ((win->sizex == 0) || (wm_init_state.override_flag & WIN_OVERRIDE_GEOM)) { win->posx = wm_init_state.start_x; win->posy = wm_init_state.start_y; win->sizex = wm_init_state.size_x; win->sizey = wm_init_state.size_y; win->windowstate = GHOST_kWindowStateNormal; wm_init_state.override_flag &= ~WIN_OVERRIDE_GEOM; } if (wm_init_state.override_flag & WIN_OVERRIDE_WINSTATE) { win->windowstate = wm_init_state.windowstate; wm_init_state.override_flag &= ~WIN_OVERRIDE_WINSTATE; } wm_window_add_ghostwindow("Blender", win); } /* happens after fileread */ if (win->eventstate == NULL) win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state"); /* add keymap handlers (1 handler for all keys in map!) */ keymap = WM_keymap_find(wm->defaultconf, "Window", 0, 0); WM_event_add_keymap_handler(&win->handlers, keymap); keymap = WM_keymap_find(wm->defaultconf, "Screen", 0, 0); WM_event_add_keymap_handler(&win->handlers, keymap); keymap = WM_keymap_find(wm->defaultconf, "Screen Editing", 0, 0); WM_event_add_keymap_handler(&win->modalhandlers, keymap); /* add drop boxes */ { ListBase *lb = WM_dropboxmap_find("Window", 0, 0); WM_event_add_dropbox_handler(&win->handlers, lb); } wm_window_title(wm, win); } }
/* Calculate factor of a scale, which will eliminate black areas * appearing on the frame caused by frame translation. */ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, int width, int height) { float firstmedian[2]; MovieTrackingStabilization *stab = &tracking->stabilization; float aspect = tracking->camera.pixel_aspect; /* Early output if stabilization data is already up-to-date. */ if (stab->ok) return stab->scale; /* See comment in BKE_tracking_stabilization_data_get about first frame. */ if (stabilization_median_point_get(tracking, 1, firstmedian)) { int sfra = INT_MAX, efra = INT_MIN, cfra; float scale = 1.0f; MovieTrackingTrack *track; stab->scale = 1.0f; /* Calculate frame range of tracks used for stabilization. */ track = tracking->tracks.first; while (track) { if (track->flag & TRACK_USE_2D_STAB || ((stab->flag & TRACKING_STABILIZE_ROTATION) && track == stab->rot_track)) { sfra = min_ii(sfra, track->markers[0].framenr); efra = max_ii(efra, track->markers[track->markersnr - 1].framenr); } track = track->next; } /* For every frame we calculate scale factor needed to eliminate black * aread and choose largest scale factor as final one. */ for (cfra = sfra; cfra <= efra; cfra++) { float median[2]; float translation[2], angle, tmp_scale; int i; float mat[4][4]; float points[4][2] = {{0.0f, 0.0f}, {0.0f, height}, {width, height}, {width, 0.0f}}; float si, co; stabilization_median_point_get(tracking, cfra, median); stabilization_calculate_data(tracking, cfra, width, height, firstmedian, median, translation, &tmp_scale, &angle); BKE_tracking_stabilization_data_to_mat4(width, height, aspect, translation, 1.0f, angle, mat); si = sinf(angle); co = cosf(angle); for (i = 0; i < 4; i++) { int j; float a[3] = {0.0f, 0.0f, 0.0f}, b[3] = {0.0f, 0.0f, 0.0f}; copy_v3_v3(a, points[i]); copy_v3_v3(b, points[(i + 1) % 4]); mul_m4_v3(mat, a); mul_m4_v3(mat, b); for (j = 0; j < 4; j++) { float point[3] = {points[j][0], points[j][1], 0.0f}; float v1[3], v2[3]; sub_v3_v3v3(v1, b, a); sub_v3_v3v3(v2, point, a); if (cross_v2v2(v1, v2) >= 0.0f) { const float rotDx[4][2] = {{1.0f, 0.0f}, {0.0f, -1.0f}, {-1.0f, 0.0f}, {0.0f, 1.0f}}; const float rotDy[4][2] = {{0.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, -1.0f}, {-1.0f, 0.0f}}; float dx = translation[0] * rotDx[j][0] + translation[1] * rotDx[j][1], dy = translation[0] * rotDy[j][0] + translation[1] * rotDy[j][1]; float w, h, E, F, G, H, I, J, K, S; if (j % 2) { w = (float)height / 2.0f; h = (float)width / 2.0f; } else { w = (float)width / 2.0f; h = (float)height / 2.0f; } E = -w * co + h * si; F = -h * co - w * si; if ((i % 2) == (j % 2)) { G = -w * co - h * si; H = h * co - w * si; } else { G = w * co + h * si; H = -h * co + w * si; } I = F - H; J = G - E; K = G * F - E * H; S = (-w * I - h * J) / (dx * I + dy * J + K); scale = max_ff(scale, S); } } } } stab->scale = scale; if (stab->maxscale > 0.0f) stab->scale = min_ff(stab->scale, stab->maxscale); } else { stab->scale = 1.0f; } stab->ok = TRUE; return stab->scale; }
/* Create context for camera/object motion reconstruction. * Copies all data needed for reconstruction from movie * clip datablock, so editing this clip is safe during * reconstruction job is in progress. */ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip, MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height) { MovieTracking *tracking = &clip->tracking; MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data"); ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); float aspy = 1.0f / tracking->camera.pixel_aspect; int num_tracks = BLI_countlist(tracksbase); int sfra = INT_MAX, efra = INT_MIN; MovieTrackingTrack *track; BLI_strncpy(context->object_name, object->name, sizeof(context->object_name)); context->is_camera = object->flag & TRACKING_OBJECT_CAMERA; context->motion_flag = tracking->settings.motion_flag; context->select_keyframes = (tracking->settings.reconstruction_flag & TRACKING_USE_KEYFRAME_SELECTION) != 0; tracking_cameraIntrinscisOptionsFromTracking(tracking, width, height, &context->camera_intrinsics_options); context->tracks_map = tracks_map_new(context->object_name, context->is_camera, num_tracks, 0); track = tracksbase->first; while (track) { int first = 0, last = track->markersnr - 1; MovieTrackingMarker *first_marker = &track->markers[0]; MovieTrackingMarker *last_marker = &track->markers[track->markersnr - 1]; /* find first not-disabled marker */ while (first <= track->markersnr - 1 && first_marker->flag & MARKER_DISABLED) { first++; first_marker++; } /* find last not-disabled marker */ while (last >= 0 && last_marker->flag & MARKER_DISABLED) { last--; last_marker--; } if (first < track->markersnr - 1) sfra = min_ii(sfra, first_marker->framenr); if (last >= 0) efra = max_ii(efra, last_marker->framenr); tracks_map_insert(context->tracks_map, track, NULL); track = track->next; } context->sfra = sfra; context->efra = efra; context->tracks = libmv_tracks_new(clip, tracksbase, width, height * aspy); context->keyframe1 = keyframe1; context->keyframe2 = keyframe2; context->refine_flags = reconstruct_refine_intrinsics_get_flags(tracking, object); return context; }
static int console_copy_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceConsole *sc = CTX_wm_space_console(C); DynStr *buf_dyn = BLI_dynstr_new(); char *buf_str; ConsoleLine *cl; int sel[2]; int offset = 0; ConsoleLine cl_dummy = {NULL}; #if 0 /* copy whole file */ for (cl = sc->scrollback.first; cl; cl = cl->next) { BLI_dynstr_append(buf_dyn, cl->line); BLI_dynstr_append(buf_dyn, "\n"); } #endif if (sc->sel_start == sc->sel_end) return OPERATOR_CANCELLED; console_scrollback_prompt_begin(sc, &cl_dummy); for (cl = sc->scrollback.first; cl; cl = cl->next) { offset += cl->len + 1; } if (offset == 0) { console_scrollback_prompt_end(sc, &cl_dummy); return OPERATOR_CANCELLED; } offset -= 1; sel[0] = offset - sc->sel_end; sel[1] = offset - sc->sel_start; for (cl = sc->scrollback.first; cl; cl = cl->next) { if (sel[0] <= cl->len && sel[1] >= 0) { int sta = max_ii(sel[0], 0); int end = min_ii(sel[1], cl->len); if (BLI_dynstr_get_len(buf_dyn)) BLI_dynstr_append(buf_dyn, "\n"); BLI_dynstr_nappend(buf_dyn, cl->line + sta, end - sta); } sel[0] -= cl->len + 1; sel[1] -= cl->len + 1; } buf_str = BLI_dynstr_get_cstring(buf_dyn); BLI_dynstr_free(buf_dyn); WM_clipboard_text_set(buf_str, 0); MEM_freeN(buf_str); console_scrollback_prompt_end(sc, &cl_dummy); return OPERATOR_FINISHED; }
static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene) { float x; int *points, totseg, i, a; float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1); MovieTracking *tracking = &clip->tracking; MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking); MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking); MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking); MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* cache background */ ED_region_cache_draw_background(ar); /* cached segments -- could be usefu lto debug caching strategies */ BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points); ED_region_cache_draw_cached_segments(ar, totseg, points, sfra, efra); /* track */ if (act_track || act_plane_track) { for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) { int framenr; int markersnr = generic_track_get_markersnr(act_track, act_plane_track); while (a < markersnr) { int marker_framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a); if (marker_framenr >= i) break; if (a < markersnr - 1 && generic_track_get_marker_framenr(act_track, act_plane_track, a + 1) > i) break; a++; } a = min_ii(a, markersnr - 1); if (generic_track_is_marker_enabled(act_track, act_plane_track, a)) { framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a); if (framenr != i) glColor4ub(128, 128, 0, 96); else if (generic_track_is_marker_keyframed(act_track, act_plane_track, a)) glColor4ub(255, 255, 0, 196); else glColor4ub(255, 255, 0, 96); glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4 * UI_DPI_FAC); } } } /* failed frames */ if (reconstruction->flag & TRACKING_RECONSTRUCTED) { int n = reconstruction->camnr; MovieReconstructedCamera *cameras = reconstruction->cameras; glColor4ub(255, 0, 0, 96); for (i = sfra, a = 0; i <= efra; i++) { bool ok = false; while (a < n) { if (cameras[a].framenr == i) { ok = true; break; } else if (cameras[a].framenr > i) { break; } a++; } if (!ok) glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8 * UI_DPI_FAC); } } glDisable(GL_BLEND); /* current frame */ x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx; UI_ThemeColor(TH_CFRAME); glRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC); ED_region_cache_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC); /* solver keyframes */ glColor4ub(175, 255, 0, 255); draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2); draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2); /* movie clip animation */ if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) { ED_mask_draw_frames(sc->mask_info.mask, ar, CFRA, sfra, efra); } }
void startConstraint(TransInfo *t) { t->con.mode |= CON_APPLY; *t->con.text = ' '; t->num.idx_max = min_ii(getConstraintSpaceDimension(t) - 1, t->idx_max); }
/** * Update the brush mask image by trying to reuse the cached texture result. * This can be considerably faster for brushes that change size due to pressure or * textures that stick to the surface where only part of the pixels are new */ static void brush_painter_mask_imbuf_partial_update(BrushPainter *painter, const float pos[2], int diameter) { BrushPainterCache *cache = &painter->cache; unsigned short *tex_mask_old; int destx, desty, srcx, srcy, w, h, x1, y1, x2, y2; /* create brush image buffer if it didn't exist yet */ if (!cache->tex_mask) cache->tex_mask = MEM_mallocN(sizeof(unsigned short) * diameter * diameter, "brush_painter_mask"); /* create new texture image buffer with coordinates relative to old */ tex_mask_old = cache->tex_mask_old; cache->tex_mask_old = MEM_mallocN(sizeof(unsigned short) * diameter * diameter, "brush_painter_mask"); if (tex_mask_old) { ImBuf maskibuf; ImBuf maskibuf_old; maskibuf.x = maskibuf.y = diameter; maskibuf_old.x = cache->tex_mask_old_w; maskibuf_old.y = cache->tex_mask_old_h; srcx = srcy = 0; w = cache->tex_mask_old_w; h = cache->tex_mask_old_h; destx = (int)painter->lastpaintpos[0] - (int)pos[0] + (diameter / 2 - w / 2); desty = (int)painter->lastpaintpos[1] - (int)pos[1] + (diameter / 2 - h / 2); /* hack, use temporary rects so that clipping works */ IMB_rectclip(&maskibuf, &maskibuf_old, &destx, &desty, &srcx, &srcy, &w, &h); } else { srcx = srcy = 0; destx = desty = 0; w = h = 0; } x1 = min_ii(destx, diameter); y1 = min_ii(desty, diameter); x2 = min_ii(destx + w, diameter); y2 = min_ii(desty + h, diameter); /* blend existing texture in new position */ if ((x1 < x2) && (y1 < y2)) brush_painter_mask_imbuf_update(painter, tex_mask_old, x1, y1, x2, y2, srcx, srcy, diameter); if (tex_mask_old) MEM_freeN(tex_mask_old); /* sample texture in new areas */ if ((0 < x1) && (0 < diameter)) brush_painter_mask_imbuf_update(painter, NULL, 0, 0, x1, diameter, 0, 0, diameter); if ((x2 < diameter) && (0 < diameter)) brush_painter_mask_imbuf_update(painter, NULL, x2, 0, diameter, diameter, 0, 0, diameter); if ((x1 < x2) && (0 < y1)) brush_painter_mask_imbuf_update(painter, NULL, x1, 0, x2, y1, 0, 0, diameter); if ((x1 < x2) && (y2 < diameter)) brush_painter_mask_imbuf_update(painter, NULL, x1, y2, x2, diameter, 0, 0, diameter); /* through with sampling, now update sizes */ cache->tex_mask_old_w = diameter; cache->tex_mask_old_h = diameter; }
void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect) { float xzoom = glaGetOneFloat(GL_ZOOM_X); float yzoom = glaGetOneFloat(GL_ZOOM_Y); /* The pixel space coordinate of the intersection of * the [zoomed] image with the origin. */ float ix = -x / xzoom; float iy = -y / yzoom; /* The maximum pixel amounts the image can be cropped * at the lower left without exceeding the origin. */ int off_x = floor(max_ff(ix, 0.0f)); int off_y = floor(max_ff(iy, 0.0f)); /* The zoomed space coordinate of the raster position * (starting at the lower left most unclipped pixel). */ float rast_x = x + off_x * xzoom; float rast_y = y + off_y * yzoom; GLfloat scissor[4]; int draw_w, draw_h; /* Determine the smallest number of pixels we need to draw * before the image would go off the upper right corner. * * It may seem this is just an optimization but some graphics * cards (ATI) freak out if there is a large zoom factor and * a large number of pixels off the screen (probably at some * level the number of image pixels to draw is getting multiplied * by the zoom and then clamped). Making sure we draw the * fewest pixels possible keeps everyone mostly happy (still * fails if we zoom in on one really huge pixel so that it * covers the entire screen). */ glGetFloatv(GL_SCISSOR_BOX, scissor); draw_w = min_ii(img_w - off_x, ceil((scissor[2] - rast_x) / xzoom)); draw_h = min_ii(img_h - off_y, ceil((scissor[3] - rast_y) / yzoom)); if (draw_w > 0 && draw_h > 0) { int old_row_length = glaGetOneInteger(GL_UNPACK_ROW_LENGTH); /* Don't use safe RasterPos (slower) if we can avoid it. */ if (rast_x >= 0 && rast_y >= 0) { glRasterPos2f(rast_x, rast_y); } else { glaRasterPosSafe2f(rast_x, rast_y, 0, 0); } glPixelStorei(GL_UNPACK_ROW_LENGTH, row_w); if (format == GL_LUMINANCE || format == GL_RED) { if (type == GL_FLOAT) { float *f_rect = (float *)rect; glDrawPixels(draw_w, draw_h, format, type, f_rect + (off_y * row_w + off_x)); } else if (type == GL_INT || type == GL_UNSIGNED_INT) { int *i_rect = (int *)rect; glDrawPixels(draw_w, draw_h, format, type, i_rect + (off_y * row_w + off_x)); } } else { /* RGBA */ if (type == GL_FLOAT) { float *f_rect = (float *)rect; glDrawPixels(draw_w, draw_h, format, type, f_rect + (off_y * row_w + off_x) * 4); } else if (type == GL_UNSIGNED_BYTE) { unsigned char *uc_rect = (unsigned char *) rect; glDrawPixels(draw_w, draw_h, format, type, uc_rect + (off_y * row_w + off_x) * 4); } } glPixelStorei(GL_UNPACK_ROW_LENGTH, old_row_length); } }
static void zbuf_fill_in_rgba(ZSpan *zspan, DrawBufPixel *col, float *v1, float *v2, float *v3, float *v4) { DrawBufPixel *rectpofs, *rp; double zxd, zyd, zy0, zverg; float x0, y0, z0; float x1, y1, z1, x2, y2, z2, xx1; const float *span1, *span2; float *rectzofs, *rz; int x, y; int sn1, sn2, rectx, my0, my2; /* init */ zbuf_init_span(zspan); /* set spans */ zbuf_add_to_span(zspan, v1, v2); zbuf_add_to_span(zspan, v2, v3); zbuf_add_to_span(zspan, v3, v4); zbuf_add_to_span(zspan, v4, v1); /* clipped */ if (zspan->minp2 == NULL || zspan->maxp2 == NULL) return; my0 = max_ii(zspan->miny1, zspan->miny2); my2 = min_ii(zspan->maxy1, zspan->maxy2); // printf("my %d %d\n", my0, my2); if (my2 < my0) return; /* ZBUF DX DY, in floats still */ x1 = v1[0] - v2[0]; x2 = v2[0] - v3[0]; y1 = v1[1] - v2[1]; y2 = v2[1] - v3[1]; z1 = v1[2] - v2[2]; z2 = v2[2] - v3[2]; x0 = y1 * z2 - z1 * y2; y0 = z1 * x2 - x1 * z2; z0 = x1 * y2 - y1 * x2; if (z0 == 0.0f) return; xx1 = (x0 * v1[0] + y0 * v1[1]) / z0 + v1[2]; zxd = -(double)x0 / (double)z0; zyd = -(double)y0 / (double)z0; zy0 = ((double)my2) * zyd + (double)xx1; /* start-offset in rect */ rectx = zspan->rectx; rectzofs = (float *)(zspan->rectz + rectx * my2); rectpofs = ((DrawBufPixel *)zspan->rectdraw) + rectx * my2; /* correct span */ sn1 = (my0 + my2) / 2; if (zspan->span1[sn1] < zspan->span2[sn1]) { span1 = zspan->span1 + my2; span2 = zspan->span2 + my2; } else { span1 = zspan->span2 + my2; span2 = zspan->span1 + my2; } for (y = my2; y >= my0; y--, span1--, span2--) { sn1 = floor(*span1); sn2 = floor(*span2); sn1++; if (sn2 >= rectx) sn2 = rectx - 1; if (sn1 < 0) sn1 = 0; if (sn2 >= sn1) { zverg = (double)sn1 * zxd + zy0; rz = rectzofs + sn1; rp = rectpofs + sn1; x = sn2 - sn1; while (x >= 0) { if (zverg < (double)*rz) { *rz = zverg; *rp = *col; } zverg += zxd; rz++; rp++; x--; } } zy0 -= zyd; rectzofs -= rectx; rectpofs -= rectx; } }
static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, float *r_offset) { float factor = 1.0f, offset = 0.0f; if (flag & ANIM_UNITCONV_RESTORE) { if (r_offset) *r_offset = fcu->prev_offset; return 1.0f / fcu->prev_norm_factor; } if (flag & ANIM_UNITCONV_NORMALIZE_FREEZE) { if (r_offset) *r_offset = fcu->prev_offset; if (fcu->prev_norm_factor == 0.0f) { /* Happens when Auto Normalize was disabled before * any curves were displayed. */ return 1.0f; } return fcu->prev_norm_factor; } if (G.moving & G_TRANSFORM_FCURVES) { if (r_offset) *r_offset = fcu->prev_offset; if (fcu->prev_norm_factor == 0.0f) { /* Same as above. */ return 1.0f; } return fcu->prev_norm_factor; } fcu->prev_norm_factor = 1.0f; if (fcu->bezt) { const bool use_preview_only = PRVRANGEON; const BezTriple *bezt; int i; float max_coord = -FLT_MAX; float min_coord = FLT_MAX; float range; if (fcu->totvert < 1) { return 1.0f; } for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { if (use_preview_only && !IN_RANGE_INCL(bezt->vec[1][0], scene->r.psfra, scene->r.pefra)) { continue; } if (i == 0) { /* We ignore extrapolation flags and handle here, and use the * control point position only. so we normalize "interesting" * part of the curve. * * Here we handle left extrapolation. */ max_coord = max_ff(max_coord, bezt->vec[1][1]); min_coord = min_ff(min_coord, bezt->vec[1][1]); } else { const BezTriple *prev_bezt = bezt - 1; if (prev_bezt->ipo == BEZT_IPO_CONST) { /* Constant interpolation: previous CV value is used up * to the current keyframe. */ max_coord = max_ff(max_coord, bezt->vec[1][1]); min_coord = min_ff(min_coord, bezt->vec[1][1]); } else if (prev_bezt->ipo == BEZT_IPO_LIN) { /* Linear interpolation: min/max using both previous and * and current CV. */ max_coord = max_ff(max_coord, bezt->vec[1][1]); min_coord = min_ff(min_coord, bezt->vec[1][1]); max_coord = max_ff(max_coord, prev_bezt->vec[1][1]); min_coord = min_ff(min_coord, prev_bezt->vec[1][1]); } else if (prev_bezt->ipo == BEZT_IPO_BEZ) { const int resol = fcu->driver ? 32 : min_ii((int)(5.0f * len_v2v2(bezt->vec[1], prev_bezt->vec[1])), 32); if (resol < 2) { max_coord = max_ff(max_coord, prev_bezt->vec[1][1]); min_coord = min_ff(min_coord, prev_bezt->vec[1][1]); } else { float data[120]; float v1[2], v2[2], v3[2], v4[2]; v1[0] = prev_bezt->vec[1][0]; v1[1] = prev_bezt->vec[1][1]; v2[0] = prev_bezt->vec[2][0]; v2[1] = prev_bezt->vec[2][1]; v3[0] = bezt->vec[0][0]; v3[1] = bezt->vec[0][1]; v4[0] = bezt->vec[1][0]; v4[1] = bezt->vec[1][1]; correct_bezpart(v1, v2, v3, v4); BKE_curve_forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3); BKE_curve_forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3); for (int j = 0; j <= resol; ++j) { const float *fp = &data[j * 3]; max_coord = max_ff(max_coord, fp[1]); min_coord = min_ff(min_coord, fp[1]); } } } } } if (max_coord > min_coord) { range = max_coord - min_coord; if (range > FLT_EPSILON) { factor = 2.0f / range; } offset = -min_coord - range / 2.0f; } else if (max_coord == min_coord) { factor = 1.0f; offset = -min_coord; } } BLI_assert(factor != 0.0f); if (r_offset) { *r_offset = offset; } fcu->prev_norm_factor = factor; fcu->prev_offset = offset; return factor; }