Cycles: svn merge -r40266:40358 https://svn.blender.org/svnroot/bf-blender/trunk...
[blender.git] / intern / cycles / blender / blender_util.h
1 /*
2  * Copyright 2011, Blender Foundation.
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
19 #ifndef __BLENDER_UTIL_H__
20 #define __BLENDER_UTIL_H__
21
22 #include "util_map.h"
23 #include "util_path.h"
24 #include "util_set.h"
25 #include "util_transform.h"
26 #include "util_types.h"
27 #include "util_vector.h"
28
29 /* Hacks to hook into Blender API */
30
31 extern "C" {
32
33 struct RenderEngine;
34 struct RenderResult;
35
36 ID *rna_Object_to_mesh(void *_self, void *reports, void *scene, int apply_modifiers, int settings);
37 void rna_Main_meshes_remove(void *bmain, void *reports, void *mesh);
38 void rna_Object_create_duplilist(void *ob, void *reports, void *sce);
39 void rna_Object_free_duplilist(void *ob, void *reports);
40 void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values);
41 void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values);
42 struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h);
43 void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result);
44 void RE_engine_end_result(struct RenderEngine *engine, struct RenderResult *result);
45 int RE_engine_test_break(struct RenderEngine *engine);
46 void RE_engine_update_stats(struct RenderEngine *engine, const char *stats, const char *info);
47 void RE_engine_update_progress(struct RenderEngine *engine, float progress);
48 void engine_tag_redraw(void *engine);
49 void engine_tag_update(void *engine);
50 int rna_Object_is_modified(void *ob, void *scene, int settings);
51 void BLI_timestr(double _time, char *str);
52
53 }
54
55 CCL_NAMESPACE_BEGIN
56
57 static inline BL::Mesh object_to_mesh(BL::Object self, BL::Scene scene, bool apply_modifiers, bool render)
58 {
59         ID *data = rna_Object_to_mesh(self.ptr.data, NULL, scene.ptr.data, apply_modifiers, render);
60         PointerRNA ptr;
61         RNA_id_pointer_create(data, &ptr);
62         return BL::Mesh(ptr);
63 }
64
65 static inline void object_remove_mesh(BL::BlendData data, BL::Mesh mesh)
66 {
67         rna_Main_meshes_remove(data.ptr.data, NULL, mesh.ptr.data);
68 }
69
70 static inline void object_create_duplilist(BL::Object self, BL::Scene scene)
71 {
72         rna_Object_create_duplilist(self.ptr.data, NULL, scene.ptr.data);
73 }
74
75 static inline void object_free_duplilist(BL::Object self)
76 {
77         rna_Object_free_duplilist(self.ptr.data, NULL);
78 }
79
80 static inline bool object_is_modified(BL::Object self, BL::Scene scene, bool preview)
81 {
82         return rna_Object_is_modified(self.ptr.data, scene.ptr.data, (preview)? (1<<0): (1<<1))? true: false;
83 }
84
85 /* Utilities */
86
87 static inline Transform get_transform(BL::Array<float, 16> array)
88 {
89         Transform tfm;
90
91         /* we assume both types to be just 16 floats, and transpose because blender
92            use column major matrix order while we use row major */
93         memcpy(&tfm, &array, sizeof(float)*16);
94         tfm = transform_transpose(tfm);
95
96         return tfm;
97 }
98
99 static inline float2 get_float2(BL::Array<float, 2> array)
100 {
101         return make_float2(array[0], array[1]);
102 }
103
104 static inline float3 get_float3(BL::Array<float, 2> array)
105 {
106         return make_float3(array[0], array[1], 0.0f);
107 }
108
109 static inline float3 get_float3(BL::Array<float, 3> array)
110 {
111         return make_float3(array[0], array[1], array[2]);
112 }
113
114 static inline float3 get_float3(BL::Array<float, 4> array)
115 {
116         return make_float3(array[0], array[1], array[2]);
117 }
118
119 static inline int4 get_int4(BL::Array<int, 4> array)
120 {
121         return make_int4(array[0], array[1], array[2], array[3]);
122 }
123
124 static inline uint get_layer(BL::Array<int, 20> array)
125 {
126         uint layer = 0;
127
128         for(uint i = 0; i < 20; i++)
129                 if(array[i])
130                         layer |= (1 << i);
131         
132         return layer;
133 }
134
135 /*static inline float3 get_float3(PointerRNA& ptr, const char *name)
136 {
137         float3 f;
138         RNA_float_get_array(&ptr, name, &f.x);
139         return f;
140 }*/
141
142 static inline bool get_boolean(PointerRNA& ptr, const char *name)
143 {
144         return RNA_boolean_get(&ptr, name)? true: false;
145 }
146
147 static inline float get_float(PointerRNA& ptr, const char *name)
148 {
149         return RNA_float_get(&ptr, name);
150 }
151
152 static inline int get_int(PointerRNA& ptr, const char *name)
153 {
154         return RNA_int_get(&ptr, name);
155 }
156
157 static inline int get_enum(PointerRNA& ptr, const char *name)
158 {
159         return RNA_enum_get(&ptr, name);
160 }
161
162 static inline string get_enum_identifier(PointerRNA& ptr, const char *name)
163 {
164         PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
165         const char *identifier = "";
166         int value = RNA_property_enum_get(&ptr, prop);
167
168         RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
169
170         return string(identifier);
171 }
172
173 /* Relative Paths */
174
175 static inline string blender_absolute_path(BL::BlendData b_data, BL::ID b_id, const string& path)
176 {
177         if(path.size() >= 2 && path[0] == '/' && path[1] == '/') {
178                 string dirname = (b_id.library())? b_id.library().filepath(): b_data.filepath();
179                 return path_join(path_dirname(dirname), path.substr(2));
180         }
181
182         return path;
183 }
184
185 /* ID Map
186  *
187  * Utility class to keep in sync with blender data.
188  * Used for objects, meshes, lights and shaders. */
189
190 template<typename K, typename T>
191 class id_map {
192 public:
193         id_map(vector<T*> *scene_data_)
194         {
195                 scene_data = scene_data_;
196         }
197
198         T *find(BL::ID id)
199         {
200                 return find(id.ptr.id.data);
201         }
202
203         T *find(const K& key)
204         {
205                 if(b_map.find(key) != b_map.end()) {
206                         T *data = b_map[key];
207                         return data;
208                 }
209
210                 return NULL;
211         }
212
213         void set_recalc(BL::ID id)
214         {
215                 b_recalc.insert(id.ptr.data);
216         }
217
218         bool has_recalc()
219         {
220                 return !(b_recalc.empty());
221         }
222
223         void pre_sync()
224         {
225                 used_set.clear();
226         }
227
228         bool sync(T **r_data, BL::ID id)
229         {
230                 return sync(r_data, id, id, id.ptr.id.data);
231         }
232
233         bool sync(T **r_data, BL::ID id, BL::ID parent, const K& key)
234         {
235                 T *data = find(key);
236                 bool recalc;
237
238                 if(!data) {
239                         /* add data if it didn't exist yet */
240                         data = new T();
241                         scene_data->push_back(data);
242                         b_map[key] = data;
243                         recalc = true;
244                 }
245                 else {
246                         recalc = (b_recalc.find(id.ptr.data) != b_recalc.end());
247                         if(parent.ptr.data)
248                                 recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end());
249                 }
250
251                 used(data);
252
253                 *r_data = data;
254                 return recalc;
255         }
256
257         void used(T *data)
258         {
259                 /* tag data as still in use */
260                 used_set.insert(data);
261         }
262
263         void set_default(T *data)
264         {
265                 b_map[NULL] = data;
266         }
267
268         bool post_sync(bool do_delete = true)
269         {
270                 /* remove unused data */
271                 vector<T*> new_scene_data;
272                 typename vector<T*>::iterator it;
273                 bool deleted = false;
274
275                 for(it = scene_data->begin(); it != scene_data->end(); it++) {
276                         T *data = *it;
277
278                         if(do_delete && used_set.find(data) == used_set.end()) {
279                                 delete data;
280                                 deleted = true;
281                         }
282                         else
283                                 new_scene_data.push_back(data);
284                 }
285
286                 *scene_data = new_scene_data;
287
288                 /* update mapping */
289                 map<K, T*> new_map;
290                 typedef pair<const K, T*> TMapPair;
291                 typename map<K, T*>::iterator jt;
292
293                 for(jt = b_map.begin(); jt != b_map.end(); jt++) {
294                         TMapPair& pair = *jt;
295
296                         if(used_set.find(pair.second) != used_set.end())
297                                 new_map[pair.first] = pair.second;
298                 }
299
300                 used_set.clear();
301                 b_recalc.clear();
302                 b_map = new_map;
303
304                 return deleted;
305         }
306
307 protected:
308         vector<T*> *scene_data;
309         map<K, T*> b_map;
310         set<T*> used_set;
311         set<void*> b_recalc;
312 };
313
314 /* Object Key */
315
316 struct ObjectKey {
317         void *parent;
318         int index;
319         void *ob;
320
321         ObjectKey(void *parent_, int index_, void *ob_)
322         : parent(parent_), index(index_), ob(ob_) {}
323
324         bool operator<(const ObjectKey& k) const
325         { return (parent < k.parent || (parent == k.parent && (index < k.index || (index == k.index && ob < k.ob)))); }
326 };
327
328 CCL_NAMESPACE_END
329
330 #endif /* __BLENDER_UTIL_H__ */
331