void make_local_brush(Brush *brush) { /* - only lib users: do nothing * - only local users: set flag * - mixed: make copy */ Main *bmain= G.main; Scene *scene; int local= 0, lib= 0; if(brush->id.lib==NULL) return; if(brush->clone.image) { /* special case: ima always local immediately */ brush->clone.image->id.lib= NULL; brush->clone.image->id.flag= LIB_LOCAL; new_id(&bmain->brush, (ID *)brush->clone.image, NULL); extern_local_brush(brush); } for(scene= bmain->scene.first; scene && ELEM(0, lib, local); scene=scene->id.next) { if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) { if(scene->id.lib) lib= 1; else local= 1; } } if(local && lib==0) { brush->id.lib= NULL; brush->id.flag= LIB_LOCAL; new_id(&bmain->brush, (ID *)brush, NULL); 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(local && lib) { Brush *brushn= copy_brush(brush); brushn->id.us= 1; /* only keep fake user */ brushn->id.flag |= LIB_FAKEUSER; for(scene= bmain->scene.first; scene; scene=scene->id.next) { if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) { if(scene->id.lib==NULL) { paint_brush_set(&scene->toolsettings->imapaint.paint, brushn); } } } } }
void make_local_brush(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(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= copy_brush(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(paint_brush(&scene->toolsettings->imapaint.paint)==brush) { if(scene->id.lib==NULL) { paint_brush_set(&scene->toolsettings->imapaint.paint, brush_new); } } } } }
static void set_unified_unprojected_radius(Brush *brush, float value) { Scene *sce; for (sce= G.main->scene.first; sce; sce= sce->id.next) { if (sce->toolsettings && ELEM4(brush, paint_brush(&(sce->toolsettings->imapaint.paint)), paint_brush(&(sce->toolsettings->vpaint->paint)), paint_brush(&(sce->toolsettings->wpaint->paint)), paint_brush(&(sce->toolsettings->sculpt->paint)))) { sce->toolsettings->sculpt_paint_unified_unprojected_radius= value; } } }
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) { struct Brush *brush, *brush_orig = 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(tool_name); brush_tool_set(brush, tool_offset, tool); brush->ob_mode = ob_mode; brush->toggle_brush = brush_orig; } if (brush) { paint_brush_set(paint, brush); WM_main_add_notifier(NC_BRUSH | NA_EDITED, brush); return OPERATOR_FINISHED; } else { return OPERATOR_CANCELLED; } }
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= paint_brush(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 unsigned char *get_alpha_clone_image(Scene *scene, int *width, int *height) { Brush *brush = paint_brush(&scene->toolsettings->imapaint.paint); ImBuf *ibuf; unsigned int size, alpha; unsigned char *rect, *cp; if(!brush || !brush->clone.image) return NULL; ibuf= BKE_image_get_ibuf(brush->clone.image, NULL); if(!ibuf || !ibuf->rect) return NULL; rect= MEM_dupallocN(ibuf->rect); if(!rect) 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; } return rect; }
static int brush_curve_preset_exec(bContext *C, wmOperator *op) { Brush *br = paint_brush(paint_get_active(CTX_data_scene(C))); brush_curve_preset(br, RNA_enum_get(op->ptr, "shape")); return OPERATOR_FINISHED; }
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 = 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_to_region_no_clip(&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 short unified_settings(Brush *brush) { Scene *sce; for (sce= G.main->scene.first; sce; sce= sce->id.next) { if (sce->toolsettings && ELEM4(brush, paint_brush(&(sce->toolsettings->imapaint.paint)), paint_brush(&(sce->toolsettings->vpaint->paint)), paint_brush(&(sce->toolsettings->wpaint->paint)), paint_brush(&(sce->toolsettings->sculpt->paint)))) { return sce->toolsettings->sculpt_paint_settings; } } return 0; }
static float unified_unprojected_radius(Brush *brush) { Scene *sce; for (sce= G.main->scene.first; sce; sce= sce->id.next) { if (sce->toolsettings && ELEM4(brush, paint_brush(&(sce->toolsettings->imapaint.paint)), paint_brush(&(sce->toolsettings->vpaint->paint)), paint_brush(&(sce->toolsettings->wpaint->paint)), paint_brush(&(sce->toolsettings->sculpt->paint)))) { return sce->toolsettings->sculpt_paint_unified_unprojected_radius; } } return 0.125f; // XXX magic number }
static int unified_size(Brush *brush) { Scene *sce; for (sce= G.main->scene.first; sce; sce= sce->id.next) { if (sce->toolsettings && ELEM4(brush, paint_brush(&(sce->toolsettings->imapaint.paint)), paint_brush(&(sce->toolsettings->vpaint->paint)), paint_brush(&(sce->toolsettings->wpaint->paint)), paint_brush(&(sce->toolsettings->sculpt->paint)))) { return sce->toolsettings->sculpt_paint_unified_size; } } return 35; // XXX magic number }
static void set_unified_settings(Brush *brush, short flag, int value) { Scene *sce; for (sce= G.main->scene.first; sce; sce= sce->id.next) { if (sce->toolsettings && ELEM4(brush, paint_brush(&(sce->toolsettings->imapaint.paint)), paint_brush(&(sce->toolsettings->vpaint->paint)), paint_brush(&(sce->toolsettings->wpaint->paint)), paint_brush(&(sce->toolsettings->sculpt->paint)))) { if (value) sce->toolsettings->sculpt_paint_settings |= flag; else sce->toolsettings->sculpt_paint_settings &= ~flag; } } }
static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int *width, int *height) { Brush *brush = 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 = paint_get_active_from_context(C); struct Brush *brush = paint_brush(paint); Object *ob = CTX_data_active_object(C); if (!ob) return OPERATOR_CANCELLED; if (ob->mode & OB_MODE_SCULPT) BKE_brush_sculpt_reset(brush); /* TODO: other modes */ 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 = paint_get_active(CTX_data_scene(C)); struct Brush *br = paint_brush(paint); if (br) br = copy_brush(br); else br = add_brush("Brush"); paint_brush_set(paint_get_active(CTX_data_scene(C)), br); return OPERATOR_FINISHED; }
void BKE_paint_init(Paint *p, const char col[3]) { Brush *brush; /* If there's no brush, create one */ brush = paint_brush(p); if (brush == NULL) brush = BKE_brush_add("Brush"); 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 = paint_get_active_from_context(C); struct Brush *br = paint_brush(paint); if (br) br = BKE_brush_copy(br); else br = BKE_brush_add("Brush"); paint_brush_set(paint, br); return OPERATOR_FINISHED; }
static int brush_generic_tool_set(Main *bmain, Paint *paint, const int tool, const size_t tool_offset, const int ob_mode) { struct Brush *brush, *brush_orig= paint_brush(paint); brush= brush_tool_cycle(bmain, brush_orig, tool, tool_offset, ob_mode); if(brush) { paint_brush_set(paint, brush); WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); return OPERATOR_FINISHED; } else { return OPERATOR_CANCELLED; } }
/*** Cursor ***/ static void paint_draw_smooth_stroke(bContext *C, int x, int y, void *customdata) { Brush *brush = paint_brush(paint_get_active(CTX_data_scene(C))); PaintStroke *stroke = customdata; glColor4ubv(paint_get_active(CTX_data_scene(C))->paint_cursor_col); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); if(stroke && brush && (brush->flag & BRUSH_SMOOTH_STROKE)) { ARegion *ar = CTX_wm_region(C); sdrawline(x, y, (int)stroke->last_mouse_position[0] - ar->winrct.xmin, (int)stroke->last_mouse_position[1] - ar->winrct.ymin); } glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); }
/* used for both 3d view and image window */ void paint_sample_color(Scene *scene, ARegion *ar, int x, int y) /* frontbuf */ { Brush *br = paint_brush(paint_get_active(scene)); 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 = paint_get_active_from_context(C); struct Brush *brush = 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 brush_curve_preset_poll(bContext *C) { Brush *br = paint_brush(paint_get_active(CTX_data_scene(C))); return br && br->curve; }
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; /* 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= paint_brush(paint_get_active(scene)); } 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) buttons_texture_users_find_nodetree(users, &ma->id, ma->nodetree, "Material"); if(la) buttons_texture_users_find_nodetree(users, &la->id, la->nodetree, "Lamp"); if(wrld) 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) { /* todo: these slots are not in the UI */ 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; 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->id.name+2); } }