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 ... */
33 void BLI_timestr(double _time, char *str);
34 void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
35 void BKE_image_user_file_path(void *iuser, void *ima, char *path);
40 static inline BL::Mesh object_to_mesh(BL::Object self, BL::Scene scene, bool apply_modifiers, bool render)
42 return self.to_mesh(scene, apply_modifiers, (render)? 2: 1);
45 static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size)
47 for(int i = 0; i < size; i++) {
50 ramp.evaluate(i/(float)(size-1), color);
51 data[i] = make_float4(color[0], color[1], color[2], color[3]);
55 static inline bool BKE_object_is_modified(BL::Object self, BL::Scene scene, bool preview)
57 return self.is_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
60 static inline bool BKE_object_is_deform_modified(BL::Object self, BL::Scene scene, bool preview)
62 return self.is_deform_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
65 static inline string image_user_file_path(BL::ImageUser iuser, BL::Image ima, int cfra)
68 BKE_image_user_frame_calc(iuser.ptr.data, cfra, 0);
69 BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
70 return string(filepath);
75 static inline Transform get_transform(BL::Array<float, 16> array)
79 /* we assume both types to be just 16 floats, and transpose because blender
80 * use column major matrix order while we use row major */
81 memcpy(&tfm, &array, sizeof(float)*16);
82 tfm = transform_transpose(tfm);
87 static inline float2 get_float2(BL::Array<float, 2> array)
89 return make_float2(array[0], array[1]);
92 static inline float3 get_float3(BL::Array<float, 2> array)
94 return make_float3(array[0], array[1], 0.0f);
97 static inline float3 get_float3(BL::Array<float, 3> array)
99 return make_float3(array[0], array[1], array[2]);
102 static inline float3 get_float3(BL::Array<float, 4> array)
104 return make_float3(array[0], array[1], array[2]);
107 static inline float4 get_float4(BL::Array<float, 4> array)
109 return make_float4(array[0], array[1], array[2], array[3]);
112 static inline int4 get_int4(BL::Array<int, 4> array)
114 return make_int4(array[0], array[1], array[2], array[3]);
117 static inline uint get_layer(BL::Array<int, 20> array)
121 for(uint i = 0; i < 20; i++)
128 static inline uint get_layer(BL::Array<int, 20> array, BL::Array<int, 8> local_array, bool use_local, bool is_light = false)
132 for(uint i = 0; i < 20; i++)
137 /* consider lamps on all local view layers */
138 for(uint i = 0; i < 8; i++)
139 layer |= (1 << (20+i));
142 for(uint i = 0; i < 8; i++)
144 layer |= (1 << (20+i));
147 /* we don't have spare bits for localview (normally 20-28) because
148 * PATH_RAY_LAYER_SHIFT uses 20-32. So - check if we have localview and if
149 * so, shift local view bits down to 1-8, since this is done for the view
150 * port only - it should be OK and not conflict with render layers. */
158 static inline float3 get_float3(PointerRNA& ptr, const char *name)
161 RNA_float_get_array(&ptr, name, &f.x);
166 static inline bool get_boolean(PointerRNA& ptr, const char *name)
168 return RNA_boolean_get(&ptr, name)? true: false;
171 static inline float get_float(PointerRNA& ptr, const char *name)
173 return RNA_float_get(&ptr, name);
176 static inline int get_int(PointerRNA& ptr, const char *name)
178 return RNA_int_get(&ptr, name);
181 static inline int get_enum(PointerRNA& ptr, const char *name)
183 return RNA_enum_get(&ptr, name);
186 static inline string get_enum_identifier(PointerRNA& ptr, const char *name)
188 PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
189 const char *identifier = "";
190 int value = RNA_property_enum_get(&ptr, prop);
192 RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
194 return string(identifier);
199 static inline string blender_absolute_path(BL::BlendData b_data, BL::ID b_id, const string& path)
201 if(path.size() >= 2 && path[0] == '/' && path[1] == '/') {
205 dirname = blender_absolute_path(b_data, b_id.library(), b_id.library().filepath());
207 dirname = b_data.filepath();
209 return path_join(path_dirname(dirname), path.substr(2));
217 * Utility class to keep in sync with blender data.
218 * Used for objects, meshes, lights and shaders. */
220 template<typename K, typename T>
223 id_map(vector<T*> *scene_data_)
225 scene_data = scene_data_;
230 return find(id.ptr.id.data);
233 T *find(const K& key)
235 if(b_map.find(key) != b_map.end()) {
236 T *data = b_map[key];
243 void set_recalc(BL::ID id)
245 b_recalc.insert(id.ptr.data);
250 return !(b_recalc.empty());
258 bool sync(T **r_data, BL::ID id)
260 return sync(r_data, id, id, id.ptr.id.data);
263 bool sync(T **r_data, BL::ID id, BL::ID parent, const K& key)
269 /* add data if it didn't exist yet */
271 scene_data->push_back(data);
276 recalc = (b_recalc.find(id.ptr.data) != b_recalc.end());
278 recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end());
289 /* tag data as still in use */
290 used_set.insert(data);
293 void set_default(T *data)
298 bool post_sync(bool do_delete = true)
300 /* remove unused data */
301 vector<T*> new_scene_data;
302 typename vector<T*>::iterator it;
303 bool deleted = false;
305 for(it = scene_data->begin(); it != scene_data->end(); it++) {
308 if(do_delete && used_set.find(data) == used_set.end()) {
313 new_scene_data.push_back(data);
316 *scene_data = new_scene_data;
320 typedef pair<const K, T*> TMapPair;
321 typename map<K, T*>::iterator jt;
323 for(jt = b_map.begin(); jt != b_map.end(); jt++) {
324 TMapPair& pair = *jt;
326 if(used_set.find(pair.second) != used_set.end())
327 new_map[pair.first] = pair.second;
338 vector<T*> *scene_data;
351 ObjectKey(void *parent_, int index_, void *ob_)
352 : parent(parent_), index(index_), ob(ob_) {}
354 bool operator<(const ObjectKey& k) const
355 { return (parent < k.parent || (parent == k.parent && (index < k.index || (index == k.index && ob < k.ob)))); }
358 struct ParticleSystemKey {
362 ParticleSystemKey(void *ob_, void *psys_)
363 : ob(ob_), psys(psys_) {}
365 bool operator<(const ParticleSystemKey& k) const
366 { return (ob < k.ob && psys < k.psys); }
371 #endif /* __BLENDER_UTIL_H__ */