void BKE_brush_make_local(Brush *brush) { /* - only lib users: do nothing * - only local users: set flag * - mixed: make copy */ Main *bmain = G.main; Scene *scene; int is_local = FALSE, is_lib = FALSE; if (brush->id.lib == NULL) return; if (brush->clone.image) { /* special case: ima always local immediately. Clone image should only * have one user anyway. */ id_clear_lib_data(bmain, &brush->clone.image->id); extern_local_brush(brush); } for (scene = bmain->scene.first; scene && ELEM(0, is_lib, is_local); scene = scene->id.next) { if (BKE_paint_brush(&scene->toolsettings->imapaint.paint) == brush) { if (scene->id.lib) is_lib = TRUE; else is_local = TRUE; } } if (is_local && is_lib == FALSE) { id_clear_lib_data(bmain, &brush->id); extern_local_brush(brush); /* enable fake user by default */ if (!(brush->id.flag & LIB_FAKEUSER)) { brush->id.flag |= LIB_FAKEUSER; brush->id.us++; } } else if (is_local && is_lib) { Brush *brush_new = BKE_brush_copy(brush); brush_new->id.us = 1; /* only keep fake user */ brush_new->id.flag |= LIB_FAKEUSER; /* Remap paths of new ID using old library as base. */ BKE_id_lib_local_paths(bmain, brush->id.lib, &brush_new->id); for (scene = bmain->scene.first; scene; scene = scene->id.next) { if (BKE_paint_brush(&scene->toolsettings->imapaint.paint) == brush) { if (scene->id.lib == NULL) { BKE_paint_brush_set(&scene->toolsettings->imapaint.paint, brush_new); } } } } }
static void draw_image_paint_helpers(const bContext *C, ARegion *ar, Scene *scene, float zoomx, float zoomy) { Brush *brush; int x, y, w, h; unsigned char *clonerect; brush = BKE_paint_brush(&scene->toolsettings->imapaint.paint); if (brush && (brush->imagepaint_tool == PAINT_TOOL_CLONE)) { /* this is not very efficient, but glDrawPixels doesn't allow * drawing with alpha */ clonerect = get_alpha_clone_image(C, scene, &w, &h); if (clonerect) { UI_view2d_view_to_region(&ar->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y); glPixelZoom(zoomx, zoomy); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glaDrawPixelsSafe(x, y, w, h, w, GL_RGBA, GL_UNSIGNED_BYTE, clonerect); glDisable(GL_BLEND); glPixelZoom(1.0, 1.0); MEM_freeN(clonerect); } } }
static int stencil_reset_transform(bContext *C, wmOperator *op) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); bool do_mask = RNA_boolean_get(op->ptr, "mask"); if (!br) return OPERATOR_CANCELLED; if (do_mask) { br->mask_stencil_pos[0] = 256; br->mask_stencil_pos[1] = 256; br->mask_stencil_dimension[0] = 256; br->mask_stencil_dimension[1] = 256; br->mask_mtex.rot = 0; } else { br->stencil_pos[0] = 256; br->stencil_pos[1] = 256; br->stencil_dimension[0] = 256; br->stencil_dimension[1] = 256; br->mtex.rot = 0; } WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; }
bool ED_texture_context_check_others(const bContext *C) { /* We cannot rely on sbuts->texuser here, as it is NULL when in "old" tex handling, non-OTHERS tex context. */ Object *ob = CTX_data_active_object(C); /* object */ if (ob) { /* Tex force field. */ if (ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) { return true; } /* modifiers */ { bool check = false; modifiers_foreachTexLink(ob, texture_context_check_modifier_foreach, &check); if (check) { return true; } } } /* brush */ if (BKE_paint_brush(BKE_paint_get_active_from_context(C))) { return true; } return false; }
static int buttons_context_path_brush(ButsContextPath *path) { Scene *scene; Brush *br = NULL; PointerRNA *ptr = &path->ptr[path->len - 1]; /* if we already have a (pinned) brush, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Brush)) { return 1; } /* if we have a scene, use the toolsettings brushes */ else if (buttons_context_path_scene(path)) { scene = path->ptr[path->len - 1].data; if (scene) br = BKE_paint_brush(BKE_paint_get_active(scene)); if (br) { RNA_id_pointer_create((ID *)br, &path->ptr[path->len]); path->len++; return 1; } } /* no path to a brush possible */ return 0; }
static int brush_generic_tool_set(Main *bmain, Paint *paint, const int tool, const size_t tool_offset, const int ob_mode, const char *tool_name, int create_missing, int toggle) { Brush *brush, *brush_orig = BKE_paint_brush(paint); if (toggle) brush = brush_tool_toggle(bmain, brush_orig, tool, tool_offset, ob_mode); else brush = brush_tool_cycle(bmain, brush_orig, tool, tool_offset, ob_mode); if (!brush && brush_tool(brush_orig, tool_offset) != tool && create_missing) { brush = BKE_brush_add(bmain, tool_name); brush_tool_set(brush, tool_offset, tool); brush->ob_mode = ob_mode; brush->toggle_brush = brush_orig; } if (brush) { BKE_paint_brush_set(paint, brush); BKE_paint_invalidate_overlay_all(); WM_main_add_notifier(NC_BRUSH | NA_EDITED, brush); return OPERATOR_FINISHED; } else { return OPERATOR_CANCELLED; } }
/*** Cursors ***/ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); PaintStroke *stroke = customdata; if (stroke && brush) { GPU_line_smooth(true); GPU_blend(true); ARegion *ar = stroke->vc.ar; uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ubv(paint->paint_cursor_col); immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, x, y); immVertex2f(pos, stroke->last_mouse_position[0] + ar->winrct.xmin, stroke->last_mouse_position[1] + ar->winrct.ymin); immEnd(); immUnbindProgram(); GPU_blend(false); GPU_line_smooth(false); } }
static int stencil_control_poll(bContext *C) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); return (br && (br->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL || br->mask_mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL)); }
static int stencil_fit_image_aspect_exec(bContext *C, wmOperator *op) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); bool use_scale = RNA_boolean_get(op->ptr, "use_scale"); bool use_repeat = RNA_boolean_get(op->ptr, "use_repeat"); bool do_mask = RNA_boolean_get(op->ptr, "mask"); Tex *tex = NULL; MTex *mtex = NULL; if (br) { mtex = do_mask ? &br->mask_mtex : &br->mtex; tex = mtex->tex; } if (tex && tex->type == TEX_IMAGE && tex->ima) { float aspx, aspy; Image *ima = tex->ima; float orig_area, stencil_area, factor; ED_image_get_uv_aspect(ima, NULL, &aspx, &aspy); if (use_scale) { aspx *= mtex->size[0]; aspy *= mtex->size[1]; } if (use_repeat && tex->extend == TEX_REPEAT) { aspx *= tex->xrepeat; aspy *= tex->yrepeat; } orig_area = aspx * aspy; if (do_mask) { stencil_area = br->mask_stencil_dimension[0] * br->mask_stencil_dimension[1]; } else { stencil_area = br->stencil_dimension[0] * br->stencil_dimension[1]; } factor = sqrt(stencil_area / orig_area); if (do_mask) { br->mask_stencil_dimension[0] = factor * aspx; br->mask_stencil_dimension[1] = factor * aspy; } else { br->stencil_dimension[0] = factor * aspx; br->stencil_dimension[1] = factor * aspy; } } WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; }
static int brush_curve_preset_exec(bContext *C, wmOperator *op) { Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); if (br) { Scene *scene = CTX_data_scene(C); BKE_brush_curve_preset(br, RNA_enum_get(op->ptr, "shape")); BKE_paint_invalidate_cursor_overlay(scene, br->curve); } return OPERATOR_FINISHED; }
static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int *width, int *height) { Brush *brush = BKE_paint_brush(&scene->toolsettings->imapaint.paint); ImBuf *ibuf; unsigned int size, alpha; unsigned char *display_buffer; unsigned char *rect, *cp; void *cache_handle; if (!brush || !brush->clone.image) return NULL; ibuf = BKE_image_acquire_ibuf(brush->clone.image, NULL, NULL); if (!ibuf) return NULL; display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); if (!display_buffer) { BKE_image_release_ibuf(brush->clone.image, ibuf, NULL); IMB_display_buffer_release(cache_handle); return NULL; } rect = MEM_dupallocN(display_buffer); IMB_display_buffer_release(cache_handle); if (!rect) { BKE_image_release_ibuf(brush->clone.image, ibuf, NULL); return NULL; } *width = ibuf->x; *height = ibuf->y; size = (*width) * (*height); alpha = (unsigned char)255 * brush->clone.alpha; cp = rect; while (size-- > 0) { cp[3] = alpha; cp += 4; } BKE_image_release_ibuf(brush->clone.image, ibuf, NULL); return rect; }
static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); Object *ob = CTX_data_active_object(C); if (!ob || !brush) return OPERATOR_CANCELLED; if (ob->mode & OB_MODE_SCULPT) BKE_brush_sculpt_reset(brush); /* TODO: other modes */ return OPERATOR_FINISHED; }
void BKE_paint_init(Paint *p, const char col[3]) { Brush *brush; /* If there's no brush, create one */ brush = BKE_paint_brush(p); if (brush == NULL) brush = BKE_brush_add(G.main, "Brush"); BKE_paint_brush_set(p, brush); memcpy(p->paint_cursor_col, col, 3); p->paint_cursor_col[3] = 128; p->flags |= PAINT_SHOW_BRUSH; }
/* Brush operators */ static int brush_add_exec(bContext *C, wmOperator *UNUSED(op)) { /*int type = RNA_enum_get(op->ptr, "type");*/ Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); Main *bmain = CTX_data_main(C); if (br) br = BKE_brush_copy(br); else br = BKE_brush_add(bmain, "Brush"); BKE_paint_brush_set(paint, br); return OPERATOR_FINISHED; }
static int stencil_control_poll(bContext *C) { PaintMode mode = BKE_paintmode_get_active_from_context(C); Paint *paint; Brush *br; if (!paint_supports_texture(mode)) return false; paint = BKE_paint_get_active_from_context(C); br = BKE_paint_brush(paint); return (br && (br->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL || br->mask_mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL)); }
static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); Object *ob = CTX_data_active_object(C); if (!ob || !brush) return OPERATOR_CANCELLED; /* TODO: other modes */ if (ob->mode & OB_MODE_SCULPT) { BKE_brush_sculpt_reset(brush); } else { return OPERATOR_CANCELLED; } WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush); return OPERATOR_FINISHED; }
/* Brush operators */ static int brush_add_exec(bContext *C, wmOperator *UNUSED(op)) { /*int type = RNA_enum_get(op->ptr, "type");*/ Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); Main *bmain = CTX_data_main(C); ePaintMode mode = BKE_paintmode_get_active_from_context(C); if (br) { br = BKE_brush_copy(bmain, br); } else { br = BKE_brush_add(bmain, "Brush", BKE_paint_object_mode_from_paint_mode(mode)); id_us_min(&br->id); /* fake user only */ } BKE_paint_brush_set(paint, br); return OPERATOR_FINISHED; }
void *paint_2d_new_stroke(bContext *C, wmOperator *op, int mode) { Scene *scene = CTX_data_scene(C); ToolSettings *settings = scene->toolsettings; Brush *brush = BKE_paint_brush(&settings->imapaint.paint); ImagePaintState *s = MEM_callocN(sizeof(ImagePaintState), "ImagePaintState"); s->sima = CTX_wm_space_image(C); s->v2d = &CTX_wm_region(C)->v2d; s->scene = scene; s->screen = CTX_wm_screen(C); s->brush = brush; s->tool = brush->imagepaint_tool; s->blend = brush->blend; s->image = s->sima->image; s->symmetry = settings->imapaint.paint.symmetry_flags; if (!paint_2d_canvas_set(s, s->image)) { if (s->warnmultifile) BKE_report(op->reports, RPT_WARNING, "Image requires 4 color channels to paint"); if (s->warnpackedfile) BKE_report(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted"); MEM_freeN(s); return NULL; } if (brush->imagepaint_tool == PAINT_TOOL_SOFTEN) { s->blurkernel = paint_new_blur_kernel(brush, false); } paint_brush_init_tex(s->brush); /* create painter */ s->painter = brush_painter_2d_new(scene, s->brush, mode == BRUSH_STROKE_INVERT); return s; }
static int brush_scale_size_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); // Object *ob = CTX_data_active_object(C); float scalar = RNA_float_get(op->ptr, "scalar"); if (brush) { // pixel radius { const int old_size = BKE_brush_size_get(scene, brush); int size = (int)(scalar * old_size); if (abs(old_size - size) < U.pixelsize) { if (scalar > 1) { size += U.pixelsize; } else if (scalar < 1) { size -= U.pixelsize; } } BKE_brush_size_set(scene, brush, size); } // unprojected radius { float unprojected_radius = scalar * BKE_brush_unprojected_radius_get(scene, brush); if (unprojected_radius < 0.001f) // XXX magic number unprojected_radius = 0.001f; BKE_brush_unprojected_radius_set(scene, brush, unprojected_radius); } WM_main_add_notifier(NC_BRUSH | NA_EDITED, brush); } return OPERATOR_FINISHED; }
/* used for both 3d view and image window */ void paint_sample_color(const bContext *C, ARegion *ar, int x, int y) /* frontbuf */ { Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); unsigned int col; char *cp; CLAMP(x, 0, ar->winx); CLAMP(y, 0, ar->winy); glReadBuffer(GL_FRONT); glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); cp = (char *)&col; if (br) { br->rgb[0] = cp[0] / 255.0f; br->rgb[1] = cp[1] / 255.0f; br->rgb[2] = cp[2] / 255.0f; } }
static int brush_scale_size_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); // Object *ob = CTX_data_active_object(C); float scalar = RNA_float_get(op->ptr, "scalar"); if (brush) { // pixel radius { const int old_size = BKE_brush_size_get(scene, brush); int size = (int)(scalar * old_size); if (old_size == size) { if (scalar > 1) { size++; } else if (scalar < 1) { size--; } } CLAMP(size, 1, 2000); // XXX magic number BKE_brush_size_set(scene, brush, size); } // unprojected radius { float unprojected_radius = scalar * BKE_brush_unprojected_radius_get(scene, brush); if (unprojected_radius < 0.001f) // XXX magic number unprojected_radius = 0.001f; BKE_brush_unprojected_radius_set(scene, brush, unprojected_radius); } } return OPERATOR_FINISHED; }
static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); float mvalf[2] = {event->mval[0], event->mval[1]}; ARegion *ar = CTX_wm_region(C); StencilControlData *scd; int mask = RNA_enum_get(op->ptr, "texmode"); if (mask) { if (br->mask_mtex.brush_map_mode != MTEX_MAP_MODE_STENCIL) return OPERATOR_CANCELLED; } else { if (br->mtex.brush_map_mode != MTEX_MAP_MODE_STENCIL) return OPERATOR_CANCELLED; } scd = MEM_mallocN(sizeof(StencilControlData), "stencil_control"); scd->mask = mask; scd->br = br; copy_v2_v2(scd->init_mouse, mvalf); stencil_set_target(scd); scd->mode = RNA_enum_get(op->ptr, "mode"); scd->event_type = event->type; scd->area_size[0] = ar->winx; scd->area_size[1] = ar->winy; op->customdata = scd; WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; }
static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from) { SpaceNode *snode = CTX_wm_space_node(C); Scene *scene = CTX_data_scene(C); Object *ob = OBACT; Tex *tx = NULL; if (snode->texfrom == SNODE_TEX_OBJECT) { if (ob) { tx = give_current_object_texture(ob); if (tx) { if (ob->type == OB_LAMP) *r_from = (ID *)ob->data; else *r_from = (ID *)give_current_material(ob, ob->actcol); /* from is not set fully for material nodes, should be ID + Node then */ *r_id = &tx->id; *r_ntree = tx->nodetree; } } } else if (snode->texfrom == SNODE_TEX_WORLD) { if (scene->world) { *r_from = (ID *)scene->world; tx = give_current_world_texture(scene->world); if (tx) { *r_id = &tx->id; *r_ntree = tx->nodetree; } } } else if (snode->texfrom == SNODE_TEX_BRUSH) { struct Brush *brush = NULL; if (ob && (ob->mode & OB_MODE_SCULPT)) brush = BKE_paint_brush(&scene->toolsettings->sculpt->paint); else brush = BKE_paint_brush(&scene->toolsettings->imapaint.paint); if (brush) { *r_from = (ID *)brush; tx = give_current_brush_texture(brush); if (tx) { *r_id = &tx->id; *r_ntree = tx->nodetree; } } } else if (snode->texfrom == SNODE_TEX_LINESTYLE) { FreestyleLineStyle *linestyle = BKE_linestyle_active_from_scene(scene); if (linestyle) { *r_from = (ID *)linestyle; tx = give_current_linestyle_texture(linestyle); if (tx) { *r_id = &tx->id; *r_ntree = tx->nodetree; } } } }
static void buttons_texture_users_from_context(ListBase *users, const bContext *C, SpaceButs *sbuts) { Scene *scene = NULL; Object *ob = NULL; Material *ma = NULL; Lamp *la = NULL; World *wrld = NULL; Brush *brush = NULL; ID *pinid = sbuts->pinid; bool limited_mode = (sbuts->flag & SB_TEX_USER_LIMITED) != 0; /* get data from context */ if (pinid) { if (GS(pinid->name) == ID_SCE) scene = (Scene *)pinid; else if (GS(pinid->name) == ID_OB) ob = (Object *)pinid; else if (GS(pinid->name) == ID_LA) la = (Lamp *)pinid; else if (GS(pinid->name) == ID_WO) wrld = (World *)pinid; else if (GS(pinid->name) == ID_MA) ma = (Material *)pinid; else if (GS(pinid->name) == ID_BR) brush = (Brush *)pinid; } if (!scene) scene = CTX_data_scene(C); if (!(pinid || pinid == &scene->id)) { ob = (scene->basact) ? scene->basact->object : NULL; wrld = scene->world; brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); } if (ob && ob->type == OB_LAMP && !la) la = ob->data; if (ob && !ma) ma = give_current_material(ob, ob->actcol); /* fill users */ users->first = users->last = NULL; if (ma && !limited_mode) buttons_texture_users_find_nodetree(users, &ma->id, ma->nodetree, "Material"); if (la && !limited_mode) buttons_texture_users_find_nodetree(users, &la->id, la->nodetree, "Lamp"); if (wrld && !limited_mode) buttons_texture_users_find_nodetree(users, &wrld->id, wrld->nodetree, "World"); if (ob) { ParticleSystem *psys = psys_get_current(ob); MTex *mtex; int a; /* modifiers */ modifiers_foreachTexLink(ob, buttons_texture_modifier_foreach, users); /* particle systems */ if (psys && !limited_mode) { for (a = 0; a < MAX_MTEX; a++) { mtex = psys->part->mtex[a]; if (mtex) { PointerRNA ptr; PropertyRNA *prop; RNA_pointer_create(&psys->part->id, &RNA_ParticleSettingsTextureSlot, mtex, &ptr); prop = RNA_struct_find_property(&ptr, "texture"); buttons_texture_user_property_add(users, &psys->part->id, ptr, prop, "Particles", RNA_struct_ui_icon(&RNA_ParticleSettings), psys->name); } } } /* field */ if (ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) { PointerRNA ptr; PropertyRNA *prop; RNA_pointer_create(&ob->id, &RNA_FieldSettings, ob->pd, &ptr); prop = RNA_struct_find_property(&ptr, "texture"); buttons_texture_user_property_add(users, &ob->id, ptr, prop, "Fields", ICON_FORCE_TEXTURE, "Texture Field"); } } /* brush */ if (brush) { PointerRNA ptr; PropertyRNA *prop; /* texture */ RNA_pointer_create(&brush->id, &RNA_BrushTextureSlot, &brush->mtex, &ptr); prop = RNA_struct_find_property(&ptr, "texture"); buttons_texture_user_property_add(users, &brush->id, ptr, prop, "Brush", ICON_BRUSH_DATA, "Brush"); /* mask texture */ RNA_pointer_create(&brush->id, &RNA_BrushTextureSlot, &brush->mask_mtex, &ptr); prop = RNA_struct_find_property(&ptr, "texture"); buttons_texture_user_property_add(users, &brush->id, ptr, prop, "Brush", ICON_BRUSH_DATA, "Brush Mask"); } }
/* used for both 3d view and image window */ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_proj, bool use_palette) { Scene *scene = CTX_data_scene(C); Paint *paint = BKE_paint_get_active_from_context(C); Palette *palette = BKE_paint_palette(paint); PaletteColor *color; Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); unsigned int col; const unsigned char *cp; CLAMP(x, 0, ar->winx); CLAMP(y, 0, ar->winy); if (use_palette) { if (!palette) { palette = BKE_palette_add(CTX_data_main(C), "Palette"); BKE_paint_palette_set(paint, palette); } color = BKE_palette_color_add(palette); } if (CTX_wm_view3d(C) && texpaint_proj) { /* first try getting a colour directly from the mesh faces if possible */ Object *ob = OBACT; bool sample_success = false; if (ob) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); ViewContext vc; const int mval[2] = {x, y}; unsigned int faceindex; unsigned int totface = dm->getNumTessFaces(dm); MTFace *dm_mtface = dm->getTessFaceDataArray(dm, CD_MTFACE); DM_update_materials(dm, ob); if (dm_mtface) { view3d_set_viewcontext(C, &vc); view3d_operator_needs_opengl(C); if (imapaint_pick_face(&vc, mval, &faceindex, totface)) { Image *image = imapaint_face_image(dm, faceindex); ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (ibuf && ibuf->rect) { float uv[2]; float u, v; imapaint_pick_uv(scene, ob, faceindex, mval, uv); sample_success = true; u = fmodf(uv[0], 1.0f); v = fmodf(uv[1], 1.0f); if (u < 0.0f) u += 1.0f; if (v < 0.0f) v += 1.0f; u = u * ibuf->x - 0.5f; v = v * ibuf->y - 0.5f; if (ibuf->rect_float) { float rgba_f[4]; bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); straight_to_premul_v4(rgba_f); if (use_palette) { linearrgb_to_srgb_v3_v3(color->rgb, rgba_f); } else { linearrgb_to_srgb_v3_v3(rgba_f, rgba_f); BKE_brush_color_set(scene, br, rgba_f); } } else { unsigned char rgba[4]; bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v); if (use_palette) { rgb_uchar_to_float(color->rgb, rgba); } else { float rgba_f[3]; rgb_uchar_to_float(rgba_f, rgba); BKE_brush_color_set(scene, br, rgba_f); } } } BKE_image_release_ibuf(image, ibuf, NULL); } } dm->release(dm); } if (!sample_success) { glReadBuffer(GL_FRONT); glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); } else return; } else { glReadBuffer(GL_FRONT); glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); } cp = (unsigned char *)&col; if (use_palette) { rgb_uchar_to_float(color->rgb, cp); } else { float rgba_f[3]; rgb_uchar_to_float(rgba_f, cp); BKE_brush_color_set(scene, br, rgba_f); } }
static int brush_curve_preset_poll(bContext *C) { Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); return br && br->curve; }
static void buttons_texture_users_from_context(ListBase *users, const bContext *C, SpaceProperties *sbuts) { Scene *scene = NULL; Object *ob = NULL; FreestyleLineStyle *linestyle = NULL; Brush *brush = NULL; ID *pinid = sbuts->pinid; bool limited_mode = (sbuts->flag & SB_TEX_USER_LIMITED) != 0; /* get data from context */ if (pinid) { if (GS(pinid->name) == ID_SCE) { scene = (Scene *)pinid; } else if (GS(pinid->name) == ID_OB) { ob = (Object *)pinid; } else if (GS(pinid->name) == ID_BR) { brush = (Brush *)pinid; } else if (GS(pinid->name) == ID_LS) { linestyle = (FreestyleLineStyle *)pinid; } } if (!scene) { scene = CTX_data_scene(C); } const ID_Type id_type = pinid != NULL ? GS(pinid->name) : -1; if (!pinid || id_type == ID_SCE) { wmWindow *win = CTX_wm_window(C); ViewLayer *view_layer = (win->scene == scene) ? WM_window_get_active_view_layer(win) : BKE_view_layer_default_view(scene); brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); linestyle = BKE_linestyle_active_from_view_layer(view_layer); ob = OBACT(view_layer); } /* fill users */ BLI_listbase_clear(users); if (linestyle && !limited_mode) { buttons_texture_users_find_nodetree( users, &linestyle->id, linestyle->nodetree, N_("Line Style")); } if (ob) { ParticleSystem *psys = psys_get_current(ob); MTex *mtex; int a; /* modifiers */ modifiers_foreachTexLink(ob, buttons_texture_modifier_foreach, users); /* grease pencil modifiers */ BKE_gpencil_modifiers_foreachTexLink(ob, buttons_texture_modifier_gpencil_foreach, users); /* particle systems */ if (psys && !limited_mode) { for (a = 0; a < MAX_MTEX; a++) { mtex = psys->part->mtex[a]; if (mtex) { PointerRNA ptr; PropertyRNA *prop; RNA_pointer_create(&psys->part->id, &RNA_ParticleSettingsTextureSlot, mtex, &ptr); prop = RNA_struct_find_property(&ptr, "texture"); buttons_texture_user_property_add(users, &psys->part->id, ptr, prop, N_("Particles"), RNA_struct_ui_icon(&RNA_ParticleSettings), psys->name); } } } /* field */ if (ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) { PointerRNA ptr; PropertyRNA *prop; RNA_pointer_create(&ob->id, &RNA_FieldSettings, ob->pd, &ptr); prop = RNA_struct_find_property(&ptr, "texture"); buttons_texture_user_property_add( users, &ob->id, ptr, prop, N_("Fields"), ICON_FORCE_TEXTURE, IFACE_("Texture Field")); } } /* brush */ if (brush) { PointerRNA ptr; PropertyRNA *prop; /* texture */ RNA_pointer_create(&brush->id, &RNA_BrushTextureSlot, &brush->mtex, &ptr); prop = RNA_struct_find_property(&ptr, "texture"); buttons_texture_user_property_add( users, &brush->id, ptr, prop, N_("Brush"), ICON_BRUSH_DATA, IFACE_("Brush")); /* mask texture */ RNA_pointer_create(&brush->id, &RNA_BrushTextureSlot, &brush->mask_mtex, &ptr); prop = RNA_struct_find_property(&ptr, "texture"); buttons_texture_user_property_add( users, &brush->id, ptr, prop, N_("Brush"), ICON_BRUSH_DATA, IFACE_("Brush Mask")); } }