Blender V2.61 - r43446

blender_util.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 2011, Blender Foundation.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #ifndef __BLENDER_UTIL_H__
00020 #define __BLENDER_UTIL_H__
00021 
00022 #include "util_map.h"
00023 #include "util_path.h"
00024 #include "util_set.h"
00025 #include "util_transform.h"
00026 #include "util_types.h"
00027 #include "util_vector.h"
00028 
00029 /* Hacks to hook into Blender API
00030    todo: clean this up ... */
00031 
00032 extern "C" {
00033 
00034 struct RenderEngine;
00035 struct RenderResult;
00036 
00037 ID *rna_Object_to_mesh(void *_self, void *reports, void *scene, int apply_modifiers, int settings);
00038 void rna_Main_meshes_remove(void *bmain, void *reports, void *mesh);
00039 void rna_Object_create_duplilist(void *ob, void *reports, void *sce);
00040 void rna_Object_free_duplilist(void *ob, void *reports);
00041 void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values);
00042 void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values);
00043 struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h);
00044 void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result);
00045 void RE_engine_end_result(struct RenderEngine *engine, struct RenderResult *result);
00046 int RE_engine_test_break(struct RenderEngine *engine);
00047 void RE_engine_update_stats(struct RenderEngine *engine, const char *stats, const char *info);
00048 void RE_engine_update_progress(struct RenderEngine *engine, float progress);
00049 void engine_tag_redraw(void *engine);
00050 void engine_tag_update(void *engine);
00051 int rna_Object_is_modified(void *ob, void *scene, int settings);
00052 void BLI_timestr(double _time, char *str);
00053 
00054 }
00055 
00056 CCL_NAMESPACE_BEGIN
00057 
00058 static inline BL::Mesh object_to_mesh(BL::Object self, BL::Scene scene, bool apply_modifiers, bool render)
00059 {
00060     ID *data = rna_Object_to_mesh(self.ptr.data, NULL, scene.ptr.data, apply_modifiers, (render)? 2: 1);
00061     PointerRNA ptr;
00062     RNA_id_pointer_create(data, &ptr);
00063     return BL::Mesh(ptr);
00064 }
00065 
00066 static inline void object_remove_mesh(BL::BlendData data, BL::Mesh mesh)
00067 {
00068     rna_Main_meshes_remove(data.ptr.data, NULL, mesh.ptr.data);
00069 }
00070 
00071 static inline void object_create_duplilist(BL::Object self, BL::Scene scene)
00072 {
00073     rna_Object_create_duplilist(self.ptr.data, NULL, scene.ptr.data);
00074 }
00075 
00076 static inline void object_free_duplilist(BL::Object self)
00077 {
00078     rna_Object_free_duplilist(self.ptr.data, NULL);
00079 }
00080 
00081 static inline bool object_is_modified(BL::Object self, BL::Scene scene, bool preview)
00082 {
00083     return rna_Object_is_modified(self.ptr.data, scene.ptr.data, (preview)? (1<<0): (1<<1))? true: false;
00084 }
00085 
00086 /* Utilities */
00087 
00088 static inline Transform get_transform(BL::Array<float, 16> array)
00089 {
00090     Transform tfm;
00091 
00092     /* we assume both types to be just 16 floats, and transpose because blender
00093        use column major matrix order while we use row major */
00094     memcpy(&tfm, &array, sizeof(float)*16);
00095     tfm = transform_transpose(tfm);
00096 
00097     return tfm;
00098 }
00099 
00100 static inline float2 get_float2(BL::Array<float, 2> array)
00101 {
00102     return make_float2(array[0], array[1]);
00103 }
00104 
00105 static inline float3 get_float3(BL::Array<float, 2> array)
00106 {
00107     return make_float3(array[0], array[1], 0.0f);
00108 }
00109 
00110 static inline float3 get_float3(BL::Array<float, 3> array)
00111 {
00112     return make_float3(array[0], array[1], array[2]);
00113 }
00114 
00115 static inline float3 get_float3(BL::Array<float, 4> array)
00116 {
00117     return make_float3(array[0], array[1], array[2]);
00118 }
00119 
00120 static inline int4 get_int4(BL::Array<int, 4> array)
00121 {
00122     return make_int4(array[0], array[1], array[2], array[3]);
00123 }
00124 
00125 static inline uint get_layer(BL::Array<int, 20> array)
00126 {
00127     uint layer = 0;
00128 
00129     for(uint i = 0; i < 20; i++)
00130         if(array[i])
00131             layer |= (1 << i);
00132     
00133     return layer;
00134 }
00135 
00136 /*static inline float3 get_float3(PointerRNA& ptr, const char *name)
00137 {
00138     float3 f;
00139     RNA_float_get_array(&ptr, name, &f.x);
00140     return f;
00141 }*/
00142 
00143 static inline bool get_boolean(PointerRNA& ptr, const char *name)
00144 {
00145     return RNA_boolean_get(&ptr, name)? true: false;
00146 }
00147 
00148 static inline float get_float(PointerRNA& ptr, const char *name)
00149 {
00150     return RNA_float_get(&ptr, name);
00151 }
00152 
00153 static inline int get_int(PointerRNA& ptr, const char *name)
00154 {
00155     return RNA_int_get(&ptr, name);
00156 }
00157 
00158 static inline int get_enum(PointerRNA& ptr, const char *name)
00159 {
00160     return RNA_enum_get(&ptr, name);
00161 }
00162 
00163 static inline string get_enum_identifier(PointerRNA& ptr, const char *name)
00164 {
00165     PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
00166     const char *identifier = "";
00167     int value = RNA_property_enum_get(&ptr, prop);
00168 
00169     RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
00170 
00171     return string(identifier);
00172 }
00173 
00174 /* Relative Paths */
00175 
00176 static inline string blender_absolute_path(BL::BlendData b_data, BL::ID b_id, const string& path)
00177 {
00178     if(path.size() >= 2 && path[0] == '/' && path[1] == '/') {
00179         string dirname;
00180         
00181         if(b_id.library())
00182             dirname = blender_absolute_path(b_data, b_id.library(), b_id.library().filepath());
00183         else
00184             dirname = b_data.filepath();
00185 
00186         return path_join(path_dirname(dirname), path.substr(2));
00187     }
00188 
00189     return path;
00190 }
00191 
00192 /* ID Map
00193  *
00194  * Utility class to keep in sync with blender data.
00195  * Used for objects, meshes, lights and shaders. */
00196 
00197 template<typename K, typename T>
00198 class id_map {
00199 public:
00200     id_map(vector<T*> *scene_data_)
00201     {
00202         scene_data = scene_data_;
00203     }
00204 
00205     T *find(BL::ID id)
00206     {
00207         return find(id.ptr.id.data);
00208     }
00209 
00210     T *find(const K& key)
00211     {
00212         if(b_map.find(key) != b_map.end()) {
00213             T *data = b_map[key];
00214             return data;
00215         }
00216 
00217         return NULL;
00218     }
00219 
00220     void set_recalc(BL::ID id)
00221     {
00222         b_recalc.insert(id.ptr.data);
00223     }
00224 
00225     bool has_recalc()
00226     {
00227         return !(b_recalc.empty());
00228     }
00229 
00230     void pre_sync()
00231     {
00232         used_set.clear();
00233     }
00234 
00235     bool sync(T **r_data, BL::ID id)
00236     {
00237         return sync(r_data, id, id, id.ptr.id.data);
00238     }
00239 
00240     bool sync(T **r_data, BL::ID id, BL::ID parent, const K& key)
00241     {
00242         T *data = find(key);
00243         bool recalc;
00244 
00245         if(!data) {
00246             /* add data if it didn't exist yet */
00247             data = new T();
00248             scene_data->push_back(data);
00249             b_map[key] = data;
00250             recalc = true;
00251         }
00252         else {
00253             recalc = (b_recalc.find(id.ptr.data) != b_recalc.end());
00254             if(parent.ptr.data)
00255                 recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end());
00256         }
00257 
00258         used(data);
00259 
00260         *r_data = data;
00261         return recalc;
00262     }
00263 
00264     void used(T *data)
00265     {
00266         /* tag data as still in use */
00267         used_set.insert(data);
00268     }
00269 
00270     void set_default(T *data)
00271     {
00272         b_map[NULL] = data;
00273     }
00274 
00275     bool post_sync(bool do_delete = true)
00276     {
00277         /* remove unused data */
00278         vector<T*> new_scene_data;
00279         typename vector<T*>::iterator it;
00280         bool deleted = false;
00281 
00282         for(it = scene_data->begin(); it != scene_data->end(); it++) {
00283             T *data = *it;
00284 
00285             if(do_delete && used_set.find(data) == used_set.end()) {
00286                 delete data;
00287                 deleted = true;
00288             }
00289             else
00290                 new_scene_data.push_back(data);
00291         }
00292 
00293         *scene_data = new_scene_data;
00294 
00295         /* update mapping */
00296         map<K, T*> new_map;
00297         typedef pair<const K, T*> TMapPair;
00298         typename map<K, T*>::iterator jt;
00299 
00300         for(jt = b_map.begin(); jt != b_map.end(); jt++) {
00301             TMapPair& pair = *jt;
00302 
00303             if(used_set.find(pair.second) != used_set.end())
00304                 new_map[pair.first] = pair.second;
00305         }
00306 
00307         used_set.clear();
00308         b_recalc.clear();
00309         b_map = new_map;
00310 
00311         return deleted;
00312     }
00313 
00314 protected:
00315     vector<T*> *scene_data;
00316     map<K, T*> b_map;
00317     set<T*> used_set;
00318     set<void*> b_recalc;
00319 };
00320 
00321 /* Object Key */
00322 
00323 struct ObjectKey {
00324     void *parent;
00325     int index;
00326     void *ob;
00327 
00328     ObjectKey(void *parent_, int index_, void *ob_)
00329     : parent(parent_), index(index_), ob(ob_) {}
00330 
00331     bool operator<(const ObjectKey& k) const
00332     { return (parent < k.parent || (parent == k.parent && (index < k.index || (index == k.index && ob < k.ob)))); }
00333 };
00334 
00335 CCL_NAMESPACE_END
00336 
00337 #endif /* __BLENDER_UTIL_H__ */
00338