Blender V2.61 - r43446
|
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