UI: Sculpt 'Inverse Cursor Color' Label
[blender.git] / source / blender / blenkernel / intern / world.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup bke
22  */
23
24 #include <math.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "MEM_guardedalloc.h"
29
30 /* Allow using deprecated functionality for .blend file I/O. */
31 #define DNA_DEPRECATED_ALLOW
32
33 #include "DNA_defaults.h"
34 #include "DNA_scene_types.h"
35 #include "DNA_texture_types.h"
36 #include "DNA_world_types.h"
37
38 #include "BLI_listbase.h"
39 #include "BLI_utildefines.h"
40
41 #include "BKE_anim_data.h"
42 #include "BKE_icons.h"
43 #include "BKE_idtype.h"
44 #include "BKE_lib_id.h"
45 #include "BKE_lib_query.h"
46 #include "BKE_main.h"
47 #include "BKE_node.h"
48 #include "BKE_world.h"
49
50 #include "BLT_translation.h"
51
52 #include "DRW_engine.h"
53
54 #include "DEG_depsgraph.h"
55
56 #include "GPU_material.h"
57
58 #include "BLO_read_write.h"
59
60 /** Free (or release) any data used by this world (does not free the world itself). */
61 static void world_free_data(ID *id)
62 {
63   World *wrld = (World *)id;
64
65   DRW_drawdata_free(id);
66
67   /* is no lib link block, but world extension */
68   if (wrld->nodetree) {
69     ntreeFreeEmbeddedTree(wrld->nodetree);
70     MEM_freeN(wrld->nodetree);
71     wrld->nodetree = NULL;
72   }
73
74   GPU_material_free(&wrld->gpumaterial);
75
76   BKE_icon_id_delete((struct ID *)wrld);
77   BKE_previewimg_free(&wrld->preview);
78 }
79
80 static void world_init_data(ID *id)
81 {
82   World *wrld = (World *)id;
83   BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wrld, id));
84
85   MEMCPY_STRUCT_AFTER(wrld, DNA_struct_default_get(World), id);
86 }
87
88 /**
89  * Only copy internal data of World ID from source
90  * to already allocated/initialized destination.
91  * You probably never want to use that directly,
92  * use #BKE_id_copy or #BKE_id_copy_ex for typical needs.
93  *
94  * WARNING! This function will not handle ID user count!
95  *
96  * \param flag: Copying options (see BKE_lib_id.h's LIB_ID_COPY_... flags for more).
97  */
98 static void world_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
99 {
100   World *wrld_dst = (World *)id_dst;
101   const World *wrld_src = (const World *)id_src;
102
103   const bool is_localized = (flag & LIB_ID_CREATE_LOCAL) != 0;
104   /* We always need allocation of our private ID data. */
105   const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
106
107   if (wrld_src->nodetree) {
108     if (is_localized) {
109       wrld_dst->nodetree = ntreeLocalize(wrld_src->nodetree);
110     }
111     else {
112       BKE_id_copy_ex(
113           bmain, (ID *)wrld_src->nodetree, (ID **)&wrld_dst->nodetree, flag_private_id_data);
114     }
115   }
116
117   BLI_listbase_clear(&wrld_dst->gpumaterial);
118   BLI_listbase_clear((ListBase *)&wrld_dst->drawdata);
119
120   if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
121     BKE_previewimg_id_copy(&wrld_dst->id, &wrld_src->id);
122   }
123   else {
124     wrld_dst->preview = NULL;
125   }
126 }
127
128 static void world_foreach_id(ID *id, LibraryForeachIDData *data)
129 {
130   World *world = (World *)id;
131
132   if (world->nodetree) {
133     /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
134     BKE_library_foreach_ID_embedded(data, (ID **)&world->nodetree);
135   }
136 }
137
138 static void world_blend_write(BlendWriter *writer, ID *id, const void *id_address)
139 {
140   World *wrld = (World *)id;
141   if (wrld->id.us > 0 || BLO_write_is_undo(writer)) {
142     /* Clean up, important in undo case to reduce false detection of changed datablocks. */
143     BLI_listbase_clear(&wrld->gpumaterial);
144
145     /* write LibData */
146     BLO_write_id_struct(writer, World, id_address, &wrld->id);
147     BKE_id_blend_write(writer, &wrld->id);
148
149     if (wrld->adt) {
150       BKE_animdata_blend_write(writer, wrld->adt);
151     }
152
153     /* nodetree is integral part of world, no libdata */
154     if (wrld->nodetree) {
155       BLO_write_struct(writer, bNodeTree, wrld->nodetree);
156       ntreeBlendWrite(writer, wrld->nodetree);
157     }
158
159     BKE_previewimg_blend_write(writer, wrld->preview);
160   }
161 }
162
163 static void world_blend_read_data(BlendDataReader *reader, ID *id)
164 {
165   World *wrld = (World *)id;
166   BLO_read_data_address(reader, &wrld->adt);
167   BKE_animdata_blend_read_data(reader, wrld->adt);
168
169   BLO_read_data_address(reader, &wrld->preview);
170   BKE_previewimg_blend_read(reader, wrld->preview);
171   BLI_listbase_clear(&wrld->gpumaterial);
172 }
173
174 static void world_blend_read_lib(BlendLibReader *reader, ID *id)
175 {
176   World *wrld = (World *)id;
177   BLO_read_id_address(reader, wrld->id.lib, &wrld->ipo); /* XXX deprecated, old animation system */
178 }
179
180 static void world_blend_read_expand(BlendExpander *expander, ID *id)
181 {
182   World *wrld = (World *)id;
183   BLO_expand(expander, wrld->ipo); /* XXX deprecated, old animation system */
184 }
185
186 IDTypeInfo IDType_ID_WO = {
187     .id_code = ID_WO,
188     .id_filter = FILTER_ID_WO,
189     .main_listbase_index = INDEX_ID_WO,
190     .struct_size = sizeof(World),
191     .name = "World",
192     .name_plural = "worlds",
193     .translation_context = BLT_I18NCONTEXT_ID_WORLD,
194     .flags = 0,
195
196     .init_data = world_init_data,
197     .copy_data = world_copy_data,
198     .free_data = world_free_data,
199     .make_local = NULL,
200     .foreach_id = world_foreach_id,
201     .foreach_cache = NULL,
202
203     .blend_write = world_blend_write,
204     .blend_read_data = world_blend_read_data,
205     .blend_read_lib = world_blend_read_lib,
206     .blend_read_expand = world_blend_read_expand,
207 };
208
209 World *BKE_world_add(Main *bmain, const char *name)
210 {
211   World *wrld;
212
213   wrld = BKE_id_new(bmain, ID_WO, name);
214
215   return wrld;
216 }
217
218 void BKE_world_eval(struct Depsgraph *depsgraph, World *world)
219 {
220   DEG_debug_print_eval(depsgraph, __func__, world->id.name, world);
221   GPU_material_free(&world->gpumaterial);
222 }