2 * Copyright 2011, Blender Foundation.
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.
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.
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.
19 #ifndef __BLENDER_UTIL_H__
20 #define __BLENDER_UTIL_H__
23 #include "util_path.h"
25 #include "util_transform.h"
26 #include "util_types.h"
27 #include "util_vector.h"
29 /* Hacks to hook into Blender API
30 todo: clean this up ... */
37 ID *rna_Object_to_mesh(void *_self, void *reports, void *scene, int apply_modifiers, int settings);
38 void rna_Main_meshes_remove(void *bmain, void *reports, void *mesh);
39 void rna_Object_create_duplilist(void *ob, void *reports, void *sce);
40 void rna_Object_free_duplilist(void *ob, void *reports);
41 void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values);
42 void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values);
43 struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h);
44 void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result);
45 void RE_engine_end_result(struct RenderEngine *engine, struct RenderResult *result);
46 int RE_engine_test_break(struct RenderEngine *engine);
47 void RE_engine_update_stats(struct RenderEngine *engine, const char *stats, const char *info);
48 void RE_engine_update_progress(struct RenderEngine *engine, float progress);
49 void engine_tag_redraw(void *engine);
50 void engine_tag_update(void *engine);
51 int rna_Object_is_modified(void *ob, void *scene, int settings);
52 void BLI_timestr(double _time, char *str);
58 static inline BL::Mesh object_to_mesh(BL::Object self, BL::Scene scene, bool apply_modifiers, bool render)
60 ID *data = rna_Object_to_mesh(self.ptr.data, NULL, scene.ptr.data, apply_modifiers, (render)? 2: 1);
62 RNA_id_pointer_create(data, &ptr);
66 static inline void object_remove_mesh(BL::BlendData data, BL::Mesh mesh)
68 rna_Main_meshes_remove(data.ptr.data, NULL, mesh.ptr.data);
71 static inline void object_create_duplilist(BL::Object self, BL::Scene scene)
73 rna_Object_create_duplilist(self.ptr.data, NULL, scene.ptr.data);
76 static inline void object_free_duplilist(BL::Object self)
78 rna_Object_free_duplilist(self.ptr.data, NULL);
81 static inline bool object_is_modified(BL::Object self, BL::Scene scene, bool preview)
83 return rna_Object_is_modified(self.ptr.data, scene.ptr.data, (preview)? (1<<0): (1<<1))? true: false;
88 static inline Transform get_transform(BL::Array<float, 16> array)
92 /* we assume both types to be just 16 floats, and transpose because blender
93 use column major matrix order while we use row major */
94 memcpy(&tfm, &array, sizeof(float)*16);
95 tfm = transform_transpose(tfm);
100 static inline float2 get_float2(BL::Array<float, 2> array)
102 return make_float2(array[0], array[1]);
105 static inline float3 get_float3(BL::Array<float, 2> array)
107 return make_float3(array[0], array[1], 0.0f);
110 static inline float3 get_float3(BL::Array<float, 3> array)
112 return make_float3(array[0], array[1], array[2]);
115 static inline float3 get_float3(BL::Array<float, 4> array)
117 return make_float3(array[0], array[1], array[2]);
120 static inline int4 get_int4(BL::Array<int, 4> array)
122 return make_int4(array[0], array[1], array[2], array[3]);
125 static inline uint get_layer(BL::Array<int, 20> array)
129 for(uint i = 0; i < 20; i++)
136 /*static inline float3 get_float3(PointerRNA& ptr, const char *name)
139 RNA_float_get_array(&ptr, name, &f.x);
143 static inline bool get_boolean(PointerRNA& ptr, const char *name)
145 return RNA_boolean_get(&ptr, name)? true: false;
148 static inline float get_float(PointerRNA& ptr, const char *name)
150 return RNA_float_get(&ptr, name);
153 static inline int get_int(PointerRNA& ptr, const char *name)
155 return RNA_int_get(&ptr, name);
158 static inline int get_enum(PointerRNA& ptr, const char *name)
160 return RNA_enum_get(&ptr, name);
163 static inline string get_enum_identifier(PointerRNA& ptr, const char *name)
165 PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
166 const char *identifier = "";
167 int value = RNA_property_enum_get(&ptr, prop);
169 RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
171 return string(identifier);
176 static inline string blender_absolute_path(BL::BlendData b_data, BL::ID b_id, const string& path)
178 if(path.size() >= 2 && path[0] == '/' && path[1] == '/') {
182 dirname = blender_absolute_path(b_data, b_id.library(), b_id.library().filepath());
184 dirname = b_data.filepath();
186 return path_join(path_dirname(dirname), path.substr(2));
194 * Utility class to keep in sync with blender data.
195 * Used for objects, meshes, lights and shaders. */
197 template<typename K, typename T>
200 id_map(vector<T*> *scene_data_)
202 scene_data = scene_data_;
207 return find(id.ptr.id.data);
210 T *find(const K& key)
212 if(b_map.find(key) != b_map.end()) {
213 T *data = b_map[key];
220 void set_recalc(BL::ID id)
222 b_recalc.insert(id.ptr.data);
227 return !(b_recalc.empty());
235 bool sync(T **r_data, BL::ID id)
237 return sync(r_data, id, id, id.ptr.id.data);
240 bool sync(T **r_data, BL::ID id, BL::ID parent, const K& key)
246 /* add data if it didn't exist yet */
248 scene_data->push_back(data);
253 recalc = (b_recalc.find(id.ptr.data) != b_recalc.end());
255 recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end());
266 /* tag data as still in use */
267 used_set.insert(data);
270 void set_default(T *data)
275 bool post_sync(bool do_delete = true)
277 /* remove unused data */
278 vector<T*> new_scene_data;
279 typename vector<T*>::iterator it;
280 bool deleted = false;
282 for(it = scene_data->begin(); it != scene_data->end(); it++) {
285 if(do_delete && used_set.find(data) == used_set.end()) {
290 new_scene_data.push_back(data);
293 *scene_data = new_scene_data;
297 typedef pair<const K, T*> TMapPair;
298 typename map<K, T*>::iterator jt;
300 for(jt = b_map.begin(); jt != b_map.end(); jt++) {
301 TMapPair& pair = *jt;
303 if(used_set.find(pair.second) != used_set.end())
304 new_map[pair.first] = pair.second;
315 vector<T*> *scene_data;
328 ObjectKey(void *parent_, int index_, void *ob_)
329 : parent(parent_), index(index_), ob(ob_) {}
331 bool operator<(const ObjectKey& k) const
332 { return (parent < k.parent || (parent == k.parent && (index < k.index || (index == k.index && ob < k.ob)))); }
337 #endif /* __BLENDER_UTIL_H__ */