~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/editors/space_buttons/buttons_texture.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ***** BEGIN GPL LICENSE BLOCK *****
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version. 
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software Foundation,
 
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
17
 *
 
18
 * The Original Code is Copyright (C) 2009 Blender Foundation.
 
19
 * All rights reserved.
 
20
 *
 
21
 * Contributor(s): Blender Foundation
 
22
 *
 
23
 * ***** END GPL LICENSE BLOCK *****
 
24
 */
 
25
 
 
26
/** \file blender/editors/space_buttons/buttons_texture.c
 
27
 *  \ingroup spbuttons
 
28
 */
 
29
 
 
30
 
 
31
#include <stdlib.h>
 
32
#include <string.h>
 
33
 
 
34
#include "MEM_guardedalloc.h"
 
35
 
 
36
#include "BLI_listbase.h"
 
37
#include "BLI_string.h"
 
38
#include "BLI_utildefines.h"
 
39
 
 
40
#include "DNA_brush_types.h"
 
41
#include "DNA_ID.h"
 
42
#include "DNA_lamp_types.h"
 
43
#include "DNA_material_types.h"
 
44
#include "DNA_node_types.h"
 
45
#include "DNA_object_types.h"
 
46
#include "DNA_object_force.h"
 
47
#include "DNA_particle_types.h"
 
48
#include "DNA_scene_types.h"
 
49
#include "DNA_screen_types.h"
 
50
#include "DNA_space_types.h"
 
51
#include "DNA_world_types.h"
 
52
 
 
53
#include "BKE_context.h"
 
54
#include "BKE_material.h"
 
55
#include "BKE_modifier.h"
 
56
#include "BKE_node.h"
 
57
#include "BKE_paint.h"
 
58
#include "BKE_particle.h"
 
59
#include "BKE_scene.h"
 
60
 
 
61
#include "RNA_access.h"
 
62
 
 
63
#include "UI_interface.h"
 
64
#include "UI_resources.h"
 
65
 
 
66
#include "ED_node.h"
 
67
#include "ED_screen.h"
 
68
 
 
69
#include "../interface/interface_intern.h"
 
70
 
 
71
#include "buttons_intern.h"     // own include
 
72
 
 
73
/************************* Texture User **************************/
 
74
 
 
75
static void buttons_texture_user_property_add(ListBase *users, ID *id, 
 
76
        PointerRNA ptr, PropertyRNA *prop,
 
77
        const char *category, int icon, const char *name)
 
78
{
 
79
        ButsTextureUser *user = MEM_callocN(sizeof(ButsTextureUser), "ButsTextureUser");
 
80
 
 
81
        user->id= id;
 
82
        user->ptr = ptr;
 
83
        user->prop = prop;
 
84
        user->category = category;
 
85
        user->icon = icon;
 
86
        user->name = name;
 
87
        user->index = BLI_countlist(users);
 
88
 
 
89
        BLI_addtail(users, user);
 
90
}
 
91
 
 
92
static void buttons_texture_user_node_add(ListBase *users, ID *id, 
 
93
        bNodeTree *ntree, bNode *node,
 
94
        const char *category, int icon, const char *name)
 
95
{
 
96
        ButsTextureUser *user = MEM_callocN(sizeof(ButsTextureUser), "ButsTextureUser");
 
97
 
 
98
        user->id= id;
 
99
        user->ntree = ntree;
 
100
        user->node = node;
 
101
        user->category = category;
 
102
        user->icon = icon;
 
103
        user->name = name;
 
104
        user->index = BLI_countlist(users);
 
105
 
 
106
        BLI_addtail(users, user);
 
107
}
 
108
 
 
109
static void buttons_texture_users_find_nodetree(ListBase *users, ID *id,
 
110
        bNodeTree *ntree, const char *category)
 
111
{
 
112
        bNode *node;
 
113
 
 
114
        if (ntree) {
 
115
                for (node=ntree->nodes.first; node; node=node->next) {
 
116
                        if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
 
117
                                PointerRNA ptr;
 
118
                                /* PropertyRNA *prop; */ /* UNUSED */
 
119
 
 
120
                                RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
 
121
                                /* prop = RNA_struct_find_property(&ptr, "texture"); */ /* UNUSED */
 
122
 
 
123
                                buttons_texture_user_node_add(users, id, ntree, node,
 
124
                                        category, RNA_struct_ui_icon(ptr.type), node->name);
 
125
                        }
 
126
                        else if (node->type == NODE_GROUP && node->id) {
 
127
                                buttons_texture_users_find_nodetree(users, id, (bNodeTree*)node->id, category);
 
128
                        }
 
129
                }
 
130
        }
 
131
}
 
132
 
 
133
static void buttons_texture_modifier_foreach(void *userData, Object *ob, ModifierData *md, const char *propname)
 
134
{
 
135
        PointerRNA ptr;
 
136
        PropertyRNA *prop;
 
137
        ListBase *users = userData;
 
138
 
 
139
        RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr);
 
140
        prop = RNA_struct_find_property(&ptr, propname);
 
141
 
 
142
        buttons_texture_user_property_add(users, &ob->id, ptr, prop,
 
143
                "Modifiers", RNA_struct_ui_icon(ptr.type), md->name);
 
144
}
 
145
 
 
146
static void buttons_texture_users_from_context(ListBase *users, const bContext *C, SpaceButs *sbuts)
 
147
{
 
148
        Scene *scene= NULL;
 
149
        Object *ob= NULL;
 
150
        Material *ma= NULL;
 
151
        Lamp *la= NULL;
 
152
        World *wrld= NULL;
 
153
        Brush *brush= NULL;
 
154
        ID *pinid = sbuts->pinid;
 
155
 
 
156
        /* get data from context */
 
157
        if (pinid) {
 
158
                if (GS(pinid->name) == ID_SCE)
 
159
                        scene= (Scene*)pinid;
 
160
                else if (GS(pinid->name) == ID_OB)
 
161
                        ob= (Object*)pinid;
 
162
                else if (GS(pinid->name) == ID_LA)
 
163
                        la= (Lamp*)pinid;
 
164
                else if (GS(pinid->name) == ID_WO)
 
165
                        wrld= (World*)pinid;
 
166
                else if (GS(pinid->name) == ID_MA)
 
167
                        ma= (Material*)pinid;
 
168
                else if (GS(pinid->name) == ID_BR)
 
169
                        brush= (Brush*)pinid;
 
170
        }
 
171
 
 
172
        if (!scene)
 
173
                scene= CTX_data_scene(C);
 
174
        
 
175
        if (!(pinid || pinid == &scene->id)) {
 
176
                ob= (scene->basact)? scene->basact->object: NULL;
 
177
                wrld= scene->world;
 
178
                brush= paint_brush(paint_get_active(scene));
 
179
        }
 
180
 
 
181
        if (ob && ob->type == OB_LAMP && !la)
 
182
                la= ob->data;
 
183
        if (ob && !ma)
 
184
                ma= give_current_material(ob, ob->actcol);
 
185
 
 
186
        /* fill users */
 
187
        users->first = users->last = NULL;
 
188
 
 
189
        if (ma)
 
190
                buttons_texture_users_find_nodetree(users, &ma->id, ma->nodetree, "Material");
 
191
        if (la)
 
192
                buttons_texture_users_find_nodetree(users, &la->id, la->nodetree, "Lamp");
 
193
        if (wrld)
 
194
                buttons_texture_users_find_nodetree(users, &wrld->id, wrld->nodetree, "World");
 
195
 
 
196
        if (ob) {
 
197
                ParticleSystem *psys= psys_get_current(ob);
 
198
                MTex *mtex;
 
199
                int a;
 
200
 
 
201
                /* modifiers */
 
202
                modifiers_foreachTexLink(ob, buttons_texture_modifier_foreach, users);
 
203
 
 
204
                /* particle systems */
 
205
                if (psys) {
 
206
                        /* todo: these slots are not in the UI */
 
207
                        for (a=0; a<MAX_MTEX; a++) {
 
208
                                mtex = psys->part->mtex[a];
 
209
 
 
210
                                if (mtex) {
 
211
                                        PointerRNA ptr;
 
212
                                        PropertyRNA *prop;
 
213
 
 
214
                                        RNA_pointer_create(&psys->part->id, &RNA_ParticleSettingsTextureSlot, mtex, &ptr);
 
215
                                        prop = RNA_struct_find_property(&ptr, "texture");
 
216
 
 
217
                                        buttons_texture_user_property_add(users, &psys->part->id, ptr, prop,
 
218
                                                "Particles", RNA_struct_ui_icon(&RNA_ParticleSettings), psys->name);
 
219
                                }
 
220
                        }
 
221
                }
 
222
 
 
223
                /* field */
 
224
                if (ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) {
 
225
                        PointerRNA ptr;
 
226
                        PropertyRNA *prop;
 
227
 
 
228
                        RNA_pointer_create(&ob->id, &RNA_FieldSettings, ob->pd, &ptr);
 
229
                        prop = RNA_struct_find_property(&ptr, "texture");
 
230
 
 
231
                        buttons_texture_user_property_add(users, &ob->id, ptr, prop,
 
232
                                "Fields", ICON_FORCE_TEXTURE, "Texture Field");
 
233
                }
 
234
        }
 
235
 
 
236
        /* brush */
 
237
        if (brush) {
 
238
                PointerRNA ptr;
 
239
                PropertyRNA *prop;
 
240
 
 
241
                RNA_pointer_create(&brush->id, &RNA_BrushTextureSlot, &brush->mtex, &ptr);
 
242
                prop= RNA_struct_find_property(&ptr, "texture");
 
243
 
 
244
                buttons_texture_user_property_add(users, &brush->id, ptr, prop,
 
245
                        "Brush", ICON_BRUSH_DATA, brush->id.name+2);
 
246
        }
 
247
}
 
248
 
 
249
void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
 
250
{
 
251
        /* gatheravailable texture users in context. runs on every draw of
 
252
         * properties editor, before the buttons are created. */
 
253
        ButsContextTexture *ct= sbuts->texuser;
 
254
        Scene *scene= CTX_data_scene(C);
 
255
 
 
256
        if (!scene_use_new_shading_nodes(scene)) {
 
257
                if (ct) {
 
258
                        BLI_freelistN(&ct->users);
 
259
                        MEM_freeN(ct);
 
260
                        sbuts->texuser= NULL;
 
261
                }
 
262
                
 
263
                return;
 
264
        }
 
265
 
 
266
        if (!ct) {
 
267
                ct= MEM_callocN(sizeof(ButsContextTexture), "ButsContextTexture");
 
268
                sbuts->texuser= ct;
 
269
        }
 
270
        else {
 
271
                BLI_freelistN(&ct->users);
 
272
        }
 
273
 
 
274
        buttons_texture_users_from_context(&ct->users, C, sbuts);
 
275
 
 
276
        /* set one user as active based on active index */
 
277
        if (ct->index >= BLI_countlist(&ct->users))
 
278
                ct->index= 0;
 
279
 
 
280
        ct->user = BLI_findlink(&ct->users, ct->index);
 
281
        ct->texture = NULL;
 
282
 
 
283
        if (ct->user) {
 
284
                if (ct->user->ptr.data) {
 
285
                        PointerRNA texptr;
 
286
                        Tex *tex;
 
287
 
 
288
                        /* get texture datablock pointer if it's a property */
 
289
                        texptr = RNA_property_pointer_get(&ct->user->ptr, ct->user->prop);
 
290
                        tex = (RNA_struct_is_a(texptr.type, &RNA_Texture))? texptr.data: NULL;
 
291
 
 
292
                        ct->texture = tex;
 
293
                }
 
294
                else if (ct->user->node && !(ct->user->node->flag & NODE_ACTIVE_TEXTURE)) {
 
295
                        ButsTextureUser *user;
 
296
 
 
297
                        /* detect change of active texture node in same node tree, in that
 
298
                         * case we also automatically switch to the other node */
 
299
                        for (user=ct->users.first; user; user=user->next) {
 
300
                                if (user->ntree == ct->user->ntree && user->node != ct->user->node) {
 
301
                                        if (user->node->flag & NODE_ACTIVE_TEXTURE) {
 
302
                                                ct->user = user;
 
303
                                                ct->index = BLI_findindex(&ct->users, user);
 
304
                                                break;
 
305
                                        }
 
306
                                }
 
307
                        }
 
308
                }
 
309
        }
 
310
}
 
311
 
 
312
static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg))
 
313
{
 
314
        /* callback when selecting a texture user in the menu */
 
315
        SpaceButs *sbuts = CTX_wm_space_buts(C);
 
316
        ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL;
 
317
        ButsTextureUser *user = (ButsTextureUser*)user_p;
 
318
        PointerRNA texptr;
 
319
        Tex *tex;
 
320
 
 
321
        if (!ct)
 
322
                return;
 
323
 
 
324
        /* set user as active */
 
325
        if (user->node) {
 
326
                ED_node_set_active(CTX_data_main(C), user->ntree, user->node);
 
327
                ct->texture = NULL;
 
328
        }
 
329
        else {
 
330
                texptr = RNA_property_pointer_get(&user->ptr, user->prop);
 
331
                tex = (RNA_struct_is_a(texptr.type, &RNA_Texture))? texptr.data: NULL;
 
332
 
 
333
                ct->texture = tex;
 
334
        }
 
335
 
 
336
        ct->user = user;
 
337
        ct->index = user->index;
 
338
}
 
339
 
 
340
static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUSED(arg))
 
341
{
 
342
        /* callback when opening texture user selection menu, to create buttons. */
 
343
        SpaceButs *sbuts = CTX_wm_space_buts(C);
 
344
        ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL;
 
345
        ButsTextureUser *user;
 
346
        uiBlock *block = uiLayoutGetBlock(layout);
 
347
        const char *last_category = NULL;
 
348
 
 
349
        for (user=ct->users.first; user; user=user->next) {
 
350
                uiBut *but;
 
351
                char name[UI_MAX_NAME_STR];
 
352
 
 
353
                /* add label per category */
 
354
                if (!last_category || strcmp(last_category, user->category) != 0) {
 
355
                        uiItemL(layout, user->category, ICON_NONE);
 
356
                        but= block->buttons.last;
 
357
                        but->flag= UI_TEXT_LEFT;
 
358
                }
 
359
 
 
360
                /* create button */
 
361
                BLI_snprintf(name, UI_MAX_NAME_STR, "  %s", user->name);
 
362
 
 
363
                but = uiDefIconTextBut(block, BUT, 0, user->icon, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
 
364
                        NULL, 0.0, 0.0, 0.0, 0.0, "");
 
365
                uiButSetNFunc(but, template_texture_select, MEM_dupallocN(user), NULL);
 
366
 
 
367
                last_category = user->category;
 
368
        }
 
369
}
 
370
 
 
371
void uiTemplateTextureUser(uiLayout *layout, bContext *C)
 
372
{
 
373
        /* texture user selection dropdown menu. the available users have been
 
374
         * gathered before drawing in ButsContextTexture, we merely need to
 
375
         * display the current item. */
 
376
        SpaceButs *sbuts = CTX_wm_space_buts(C);
 
377
        ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL;
 
378
        uiBlock *block = uiLayoutGetBlock(layout);
 
379
        uiBut *but;
 
380
        ButsTextureUser *user;
 
381
        char name[UI_MAX_NAME_STR];
 
382
 
 
383
        if (!ct)
 
384
                return;
 
385
 
 
386
        /* get current user */
 
387
        user= ct->user;
 
388
 
 
389
        if (!user) {
 
390
                uiItemL(layout, "No textures in context.", ICON_NONE);
 
391
                return;
 
392
        }
 
393
 
 
394
        /* create button */
 
395
        BLI_snprintf(name, UI_MAX_NAME_STR, "%s", user->name);
 
396
 
 
397
        if (user->icon) {
 
398
                but = uiDefIconTextMenuBut(block, template_texture_user_menu, NULL,
 
399
                        user->icon, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, "");
 
400
        }
 
401
        else {
 
402
                but = uiDefMenuBut(block, template_texture_user_menu, NULL,
 
403
                        name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, "");
 
404
        }
 
405
 
 
406
        /* some cosmetic tweaks */
 
407
        but->type= MENU;
 
408
        but->flag |= UI_TEXT_LEFT;
 
409
        but->flag &= ~UI_ICON_SUBMENU;
 
410
}
 
411
 
 
412
/************************* Texture Show **************************/
 
413
 
 
414
static void template_texture_show(bContext *C, void *data_p, void *prop_p)
 
415
{
 
416
        SpaceButs *sbuts = CTX_wm_space_buts(C);
 
417
        ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL;
 
418
        ButsTextureUser *user;
 
419
 
 
420
        if (!ct)
 
421
                return;
 
422
 
 
423
        for (user=ct->users.first; user; user=user->next)
 
424
                if (user->ptr.data == data_p && user->prop == prop_p)
 
425
                        break;
 
426
        
 
427
        if (user) {
 
428
                /* select texture */
 
429
                template_texture_select(C, user, NULL);
 
430
 
 
431
                /* change context */
 
432
                sbuts->mainb= BCONTEXT_TEXTURE;
 
433
                sbuts->mainbuser= sbuts->mainb;
 
434
                sbuts->preview= 1;
 
435
 
 
436
                /* redraw editor */
 
437
                ED_area_tag_redraw(CTX_wm_area(C));
 
438
        }
 
439
}
 
440
 
 
441
void uiTemplateTextureShow(uiLayout *layout, bContext *C, PointerRNA *ptr, PropertyRNA *prop)
 
442
{
 
443
        /* button to quickly show texture in texture tab */
 
444
        SpaceButs *sbuts = CTX_wm_space_buts(C);
 
445
        ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL;
 
446
        ButsTextureUser *user;
 
447
 
 
448
        /* only show button in other tabs in properties editor */
 
449
        if (!ct || sbuts->mainb == BCONTEXT_TEXTURE)
 
450
                return;
 
451
 
 
452
        /* find corresponding texture user */
 
453
        for (user=ct->users.first; user; user=user->next)
 
454
                if (user->ptr.data == ptr->data && user->prop == prop)
 
455
                        break;
 
456
        
 
457
        /* draw button */
 
458
        if (user) {
 
459
                uiBlock *block = uiLayoutGetBlock(layout);
 
460
                uiBut *but;
 
461
                
 
462
                but = uiDefIconBut(block, BUT, 0, ICON_BUTS, 0, 0, UI_UNIT_X, UI_UNIT_Y,
 
463
                        NULL, 0.0, 0.0, 0.0, 0.0, "Show texture in texture tab");
 
464
                uiButSetFunc(but, template_texture_show, user->ptr.data, user->prop);
 
465
        }
 
466
}
 
467