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 #pragma once
20 
21 /** \file
22  * \ingroup bke
23  * \section aboutmain Main struct
24  * Main is the root of the 'data-base' of a Blender context. All data is put into lists, and all
25  * these lists are stored here.
26  *
27  * \note A Blender file is not much more than a binary dump of these lists. This list of lists is
28  * not serialized itself.
29  *
30  * \note `BKE_main` files are for operations over the Main database itself, or generating extra
31  * temp data to help working with it. Those should typically not affect the data-blocks themselves.
32  *
33  * \section Function Names
34  *
35  * - `BKE_main_` should be used for functions in that file.
36  */
37 
38 #include "DNA_listBase.h"
39 
40 #include "BLI_compiler_attrs.h"
41 #include "BLI_sys_types.h"
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 struct BLI_mempool;
48 struct BlendThumbnail;
49 struct GHash;
50 struct GSet;
51 struct ImBuf;
52 struct Library;
53 struct MainLock;
54 
55 /* Blender thumbnail, as written on file (width, height, and data as char RGBA). */
56 /* We pack pixel data after that struct. */
57 typedef struct BlendThumbnail {
58   int width, height;
59   char rect[0];
60 } BlendThumbnail;
61 
62 /* Structs caching relations between data-blocks in a given Main. */
63 typedef struct MainIDRelationsEntry {
64   struct MainIDRelationsEntry *next;
65   /* WARNING! for user_to_used,
66    * that pointer is really an ID** one, but for used_to_user, it’s only an ID* one! */
67   struct ID **id_pointer;
68   int usage_flag; /* Using IDWALK_ enums, in BKE_lib_query.h */
69 } MainIDRelationsEntry;
70 
71 typedef struct MainIDRelations {
72   struct GHash *id_user_to_used;
73   struct GHash *id_used_to_user;
74 
75   short flag;
76 
77   /* Private... */
78   struct BLI_mempool *entry_pool;
79 } MainIDRelations;
80 
81 enum {
82   /* Those bmain relations include pointers/usages from editors. */
83   MAINIDRELATIONS_INCLUDE_UI = 1 << 0,
84 };
85 
86 typedef struct Main {
87   struct Main *next, *prev;
88   char name[1024];                   /* 1024 = FILE_MAX */
89   short versionfile, subversionfile; /* see BLENDER_FILE_VERSION, BLENDER_FILE_SUBVERSION */
90   short minversionfile, minsubversionfile;
91   uint64_t build_commit_timestamp; /* commit's timestamp from buildinfo */
92   char build_hash[16];             /* hash from buildinfo */
93   char recovered;                  /* indicate the main->name (file) is the recovered one */
94   /** All current ID's exist in the last memfile undo step. */
95   char is_memfile_undo_written;
96   /**
97    * An ID needs its data to be flushed back.
98    * use "needs_flush_to_id" in edit data to flag data which needs updating.
99    */
100   char is_memfile_undo_flush_needed;
101   /**
102    * Indicates that next memfile undo step should not allow to re-use old bmain when re-read, but
103    * instead do a complete full re-read/update from stored memfile.
104    */
105   char use_memfile_full_barrier;
106 
107   /**
108    * When linking, disallow creation of new data-blocks.
109    * Make sure we don't do this by accident, see T76738.
110    */
111   char is_locked_for_linking;
112 
113   BlendThumbnail *blen_thumb;
114 
115   struct Library *curlib;
116   ListBase scenes;
117   ListBase libraries;
118   ListBase objects;
119   ListBase meshes;
120   ListBase curves;
121   ListBase metaballs;
122   ListBase materials;
123   ListBase textures;
124   ListBase images;
125   ListBase lattices;
126   ListBase lights;
127   ListBase cameras;
128   ListBase ipo; /* Deprecated (only for versioning). */
129   ListBase shapekeys;
130   ListBase worlds;
131   ListBase screens;
132   ListBase fonts;
133   ListBase texts;
134   ListBase speakers;
135   ListBase lightprobes;
136   ListBase sounds;
137   ListBase collections;
138   ListBase armatures;
139   ListBase actions;
140   ListBase nodetrees;
141   ListBase brushes;
142   ListBase particles;
143   ListBase palettes;
144   ListBase paintcurves;
145   ListBase wm; /* Singleton (exception). */
146   ListBase gpencils;
147   ListBase movieclips;
148   ListBase masks;
149   ListBase linestyles;
150   ListBase cachefiles;
151   ListBase workspaces;
152   ListBase hairs;
153   ListBase pointclouds;
154   ListBase volumes;
155   ListBase simulations;
156 
157   /**
158    * Must be generated, used and freed by same code - never assume this is valid data unless you
159    * know when, who and how it was created.
160    * Used by code doing a lot of remapping etc. at once to speed things up.
161    */
162   struct MainIDRelations *relations;
163 
164   struct MainLock *lock;
165 } Main;
166 
167 struct Main *BKE_main_new(void);
168 void BKE_main_free(struct Main *mainvar);
169 
170 void BKE_main_lock(struct Main *bmain);
171 void BKE_main_unlock(struct Main *bmain);
172 
173 void BKE_main_relations_create(struct Main *bmain, const short flag);
174 void BKE_main_relations_free(struct Main *bmain);
175 void BKE_main_relations_ID_remove(struct Main *bmain, struct ID *id);
176 
177 struct GSet *BKE_main_gset_create(struct Main *bmain, struct GSet *gset);
178 
179 /* *** Generic utils to loop over whole Main database. *** */
180 
181 #define FOREACH_MAIN_LISTBASE_ID_BEGIN(_lb, _id) \
182   { \
183     ID *_id_next = (_lb)->first; \
184     for ((_id) = _id_next; (_id) != NULL; (_id) = _id_next) { \
185       _id_next = (_id)->next;
186 
187 #define FOREACH_MAIN_LISTBASE_ID_END \
188   } \
189   } \
190   ((void)0)
191 
192 #define FOREACH_MAIN_LISTBASE_BEGIN(_bmain, _lb) \
193   { \
194     ListBase *_lbarray[MAX_LIBARRAY]; \
195     int _i = set_listbasepointers((_bmain), _lbarray); \
196     while (_i--) { \
197       (_lb) = _lbarray[_i];
198 
199 #define FOREACH_MAIN_LISTBASE_END \
200   } \
201   } \
202   ((void)0)
203 
204 /**
205  * DO NOT use break statement with that macro,
206  * use #FOREACH_MAIN_LISTBASE and #FOREACH_MAIN_LISTBASE_ID instead
207  * if you need that kind of control flow. */
208 #define FOREACH_MAIN_ID_BEGIN(_bmain, _id) \
209   { \
210     ListBase *_lb; \
211     FOREACH_MAIN_LISTBASE_BEGIN ((_bmain), _lb) { \
212       FOREACH_MAIN_LISTBASE_ID_BEGIN (_lb, (_id))
213 
214 #define FOREACH_MAIN_ID_END \
215   FOREACH_MAIN_LISTBASE_ID_END; \
216   } \
217   FOREACH_MAIN_LISTBASE_END; \
218   } \
219   ((void)0)
220 
221 struct BlendThumbnail *BKE_main_thumbnail_from_imbuf(struct Main *bmain, struct ImBuf *img);
222 struct ImBuf *BKE_main_thumbnail_to_imbuf(struct Main *bmain, struct BlendThumbnail *data);
223 void BKE_main_thumbnail_create(struct Main *bmain);
224 
225 const char *BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL();
226 const char *BKE_main_blendfile_path_from_global(void);
227 
228 struct ListBase *which_libbase(struct Main *bmain, short type);
229 
230 #define MAX_LIBARRAY 41
231 int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]);
232 
233 #define MAIN_VERSION_ATLEAST(main, ver, subver) \
234   ((main)->versionfile > (ver) || \
235    ((main)->versionfile == (ver) && (main)->subversionfile >= (subver)))
236 
237 #define MAIN_VERSION_OLDER(main, ver, subver) \
238   ((main)->versionfile < (ver) || \
239    ((main)->versionfile == (ver) && (main)->subversionfile < (subver)))
240 
241 #define BLEN_THUMB_SIZE 128
242 
243 #define BLEN_THUMB_MEMSIZE(_x, _y) \
244   (sizeof(BlendThumbnail) + ((size_t)(_x) * (size_t)(_y)) * sizeof(int))
245 /** Protect against buffer overflow vulnerability & negative sizes. */
246 #define BLEN_THUMB_MEMSIZE_IS_VALID(_x, _y) \
247   (((_x) > 0 && (_y) > 0) && ((uint64_t)(_x) * (uint64_t)(_y) < (SIZE_MAX / (sizeof(int) * 4))))
248 
249 #ifdef __cplusplus
250 }
251 #endif
252