Merge branch 'master' into temp_remove_particles
[blender.git] / intern / cycles / blender / blender_util.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __BLENDER_UTIL_H__
18 #define __BLENDER_UTIL_H__
19
20 #include "util_map.h"
21 #include "util_path.h"
22 #include "util_set.h"
23 #include "util_transform.h"
24 #include "util_types.h"
25 #include "util_vector.h"
26
27 /* Hacks to hook into Blender API
28  * todo: clean this up ... */
29
30 extern "C" {
31 size_t BLI_timecode_string_from_time_simple(char *str, size_t maxlen, double time_seconds);
32 void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
33 void BKE_image_user_file_path(void *iuser, void *ima, char *path);
34 unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame);
35 float *BKE_image_get_float_pixels_for_frame(void *image, int frame);
36 }
37
38 CCL_NAMESPACE_BEGIN
39
40 void python_thread_state_save(void **python_thread_state);
41 void python_thread_state_restore(void **python_thread_state);
42
43 static inline BL::Mesh object_to_mesh(BL::BlendData& data,
44                                       BL::Object& object,
45                                       BL::Scene& scene,
46                                       bool apply_modifiers,
47                                       bool render,
48                                       bool calc_undeformed)
49 {
50         BL::Mesh me = data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, false, calc_undeformed);
51         if((bool)me) {
52                 if(me.use_auto_smooth()) {
53                         me.calc_normals_split();
54                 }
55                 me.calc_tessface(true);
56         }
57         return me;
58 }
59
60 static inline void colorramp_to_array(BL::ColorRamp& ramp,
61                                       float4 *data,
62                                       int size)
63 {
64         for(int i = 0; i < size; i++) {
65                 float color[4];
66
67                 ramp.evaluate((float)i/(float)(size-1), color);
68                 data[i] = make_float4(color[0], color[1], color[2], color[3]);
69         }
70 }
71
72 static inline void curvemap_minmax_curve(/*const*/ BL::CurveMap& curve,
73                                          float *min_x,
74                                          float *max_x)
75 {
76         *min_x = min(*min_x, curve.points[0].location()[0]);
77         *max_x = max(*max_x, curve.points[curve.points.length() - 1].location()[0]);
78 }
79
80 static inline void curvemapping_minmax(/*const*/ BL::CurveMapping& cumap,
81                                        bool rgb_curve,
82                                        float *min_x,
83                                        float *max_x)
84 {
85         /* const int num_curves = cumap.curves.length(); */  /* Gives linking error so far. */
86         const int num_curves = rgb_curve? 4: 3;
87         *min_x = FLT_MAX;
88         *max_x = -FLT_MAX;
89         for(int i = 0; i < num_curves; ++i) {
90                 BL::CurveMap map(cumap.curves[i]);
91                 curvemap_minmax_curve(map, min_x, max_x);
92         }
93 }
94
95 static inline void curvemapping_to_array(BL::CurveMapping& cumap,
96                                          float *data,
97                                          int size)
98 {
99         cumap.update();
100         BL::CurveMap curve = cumap.curves[0];
101         for(int i = 0; i < size; i++) {
102                 float t = (float)i/(float)(size-1);
103                 data[i] = curve.evaluate(t);
104         }
105 }
106
107 static inline void curvemapping_color_to_array(BL::CurveMapping& cumap,
108                                                float4 *data,
109                                                int size,
110                                                bool rgb_curve)
111 {
112         float min_x = 0.0f, max_x = 1.0f;
113
114         /* TODO(sergey): There is no easy way to automatically guess what is
115          * the range to be used here for the case when mapping is applied on
116          * top of another mapping (i.e. R curve applied on top of common
117          * one).
118          *
119          * Using largest possible range form all curves works correct for the
120          * cases like vector curves and should be good enough heuristic for
121          * the color curves as well.
122          *
123          * There might be some better estimations here tho.
124          */
125         curvemapping_minmax(cumap, rgb_curve, &min_x, &max_x);
126
127         const float range_x = max_x - min_x;
128
129         cumap.update();
130
131         BL::CurveMap mapR = cumap.curves[0];
132         BL::CurveMap mapG = cumap.curves[1];
133         BL::CurveMap mapB = cumap.curves[2];
134
135         if(rgb_curve) {
136                 BL::CurveMap mapI = cumap.curves[3];
137
138                 for(int i = 0; i < size; i++) {
139                         float t = min_x + (float)i/(float)(size-1) * range_x;
140
141                         data[i][0] = mapR.evaluate(mapI.evaluate(t));
142                         data[i][1] = mapG.evaluate(mapI.evaluate(t));
143                         data[i][2] = mapB.evaluate(mapI.evaluate(t));
144                 }
145         }
146         else {
147                 for(int i = 0; i < size; i++) {
148                         float t = min_x + (float)i/(float)(size-1) * range_x;
149
150                         data[i][0] = mapR.evaluate(t);
151                         data[i][1] = mapG.evaluate(t);
152                         data[i][2] = mapB.evaluate(t);
153                 }
154         }
155 }
156
157 static inline bool BKE_object_is_modified(BL::Object& self,
158                                           BL::Scene& scene,
159                                           bool preview)
160 {
161         return self.is_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
162 }
163
164 static inline bool BKE_object_is_deform_modified(BL::Object& self,
165                                                  BL::Scene& scene,
166                                                  bool preview)
167 {
168         return self.is_deform_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
169 }
170
171 static inline int render_resolution_x(BL::RenderSettings& b_render)
172 {
173         return b_render.resolution_x()*b_render.resolution_percentage()/100;
174 }
175
176 static inline int render_resolution_y(BL::RenderSettings& b_render)
177 {
178         return b_render.resolution_y()*b_render.resolution_percentage()/100;
179 }
180
181 static inline string image_user_file_path(BL::ImageUser& iuser,
182                                           BL::Image& ima,
183                                           int cfra)
184 {
185         char filepath[1024];
186         BKE_image_user_frame_calc(iuser.ptr.data, cfra, 0);
187         BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
188         return string(filepath);
189 }
190
191 static inline int image_user_frame_number(BL::ImageUser& iuser, int cfra)
192 {
193         BKE_image_user_frame_calc(iuser.ptr.data, cfra, 0);
194         return iuser.frame_current();
195 }
196
197 static inline unsigned char *image_get_pixels_for_frame(BL::Image& image,
198                                                         int frame)
199 {
200         return BKE_image_get_pixels_for_frame(image.ptr.data, frame);
201 }
202
203 static inline float *image_get_float_pixels_for_frame(BL::Image& image,
204                                                       int frame)
205 {
206         return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame);
207 }
208
209 /* Utilities */
210
211 static inline Transform get_transform(const BL::Array<float, 16>& array)
212 {
213         Transform tfm;
214
215         /* we assume both types to be just 16 floats, and transpose because blender
216          * use column major matrix order while we use row major */
217         memcpy(&tfm, &array, sizeof(float)*16);
218         tfm = transform_transpose(tfm);
219
220         return tfm;
221 }
222
223 static inline float2 get_float2(const BL::Array<float, 2>& array)
224 {
225         return make_float2(array[0], array[1]);
226 }
227
228 static inline float3 get_float3(const BL::Array<float, 2>& array)
229 {
230         return make_float3(array[0], array[1], 0.0f);
231 }
232
233 static inline float3 get_float3(const BL::Array<float, 3>& array)
234 {
235         return make_float3(array[0], array[1], array[2]);
236 }
237
238 static inline float3 get_float3(const BL::Array<float, 4>& array)
239 {
240         return make_float3(array[0], array[1], array[2]);
241 }
242
243 static inline float4 get_float4(const BL::Array<float, 4>& array)
244 {
245         return make_float4(array[0], array[1], array[2], array[3]);
246 }
247
248 static inline int3 get_int3(const BL::Array<int, 3>& array)
249 {
250         return make_int3(array[0], array[1], array[2]);
251 }
252
253 static inline int4 get_int4(const BL::Array<int, 4>& array)
254 {
255         return make_int4(array[0], array[1], array[2], array[3]);
256 }
257
258 static inline uint get_layer(const BL::Array<int, 20>& array)
259 {
260         uint layer = 0;
261
262         for(uint i = 0; i < 20; i++)
263                 if(array[i])
264                         layer |= (1 << i);
265         
266         return layer;
267 }
268
269 static inline uint get_layer(const BL::Array<int, 20>& array,
270                              const BL::Array<int, 8>& local_array,
271                              bool use_local,
272                              bool is_light = false,
273                              uint scene_layers = (1 << 20) - 1)
274 {
275         uint layer = 0;
276
277         for(uint i = 0; i < 20; i++)
278                 if(array[i])
279                         layer |= (1 << i);
280
281         if(is_light) {
282                 /* Consider light is visible if it was visible without layer
283                  * override, which matches behavior of Blender Internal.
284                  */
285                 if(layer & scene_layers) {
286                         for(uint i = 0; i < 8; i++)
287                                 layer |= (1 << (20+i));
288                 }
289         }
290         else {
291                 for(uint i = 0; i < 8; i++)
292                         if(local_array[i])
293                                 layer |= (1 << (20+i));
294         }
295
296         /* we don't have spare bits for localview (normally 20-28) because
297          * PATH_RAY_LAYER_SHIFT uses 20-32. So - check if we have localview and if
298          * so, shift local view bits down to 1-8, since this is done for the view
299          * port only - it should be OK and not conflict with render layers. */
300         if(use_local)
301                 layer >>= 20;
302
303         return layer;
304 }
305
306 static inline float3 get_float3(PointerRNA& ptr, const char *name)
307 {
308         float3 f;
309         RNA_float_get_array(&ptr, name, &f.x);
310         return f;
311 }
312
313 static inline void set_float3(PointerRNA& ptr, const char *name, float3 value)
314 {
315         RNA_float_set_array(&ptr, name, &value.x);
316 }
317
318 static inline float4 get_float4(PointerRNA& ptr, const char *name)
319 {
320         float4 f;
321         RNA_float_get_array(&ptr, name, &f.x);
322         return f;
323 }
324
325 static inline void set_float4(PointerRNA& ptr, const char *name, float4 value)
326 {
327         RNA_float_set_array(&ptr, name, &value.x);
328 }
329
330 static inline bool get_boolean(PointerRNA& ptr, const char *name)
331 {
332         return RNA_boolean_get(&ptr, name)? true: false;
333 }
334
335 static inline void set_boolean(PointerRNA& ptr, const char *name, bool value)
336 {
337         RNA_boolean_set(&ptr, name, (int)value);
338 }
339
340 static inline float get_float(PointerRNA& ptr, const char *name)
341 {
342         return RNA_float_get(&ptr, name);
343 }
344
345 static inline void set_float(PointerRNA& ptr, const char *name, float value)
346 {
347         RNA_float_set(&ptr, name, value);
348 }
349
350 static inline int get_int(PointerRNA& ptr, const char *name)
351 {
352         return RNA_int_get(&ptr, name);
353 }
354
355 static inline void set_int(PointerRNA& ptr, const char *name, int value)
356 {
357         RNA_int_set(&ptr, name, value);
358 }
359
360 /* Get a RNA enum value with sanity check: if the RNA value is above num_values
361  * the function will return a fallback default value.
362  *
363  * NOTE: This function assumes that RNA enum values are a continuous sequence
364  * from 0 to num_values-1. Be careful to use it with enums where some values are
365  * deprecated!
366  */
367 static inline int get_enum(PointerRNA& ptr,
368                            const char *name,
369                            int num_values = -1,
370                            int default_value = -1)
371 {
372         int value = RNA_enum_get(&ptr, name);
373         if(num_values != -1 && value >= num_values) {
374                 assert(default_value != -1);
375                 value = default_value;
376         }
377         return value;
378 }
379
380 static inline string get_enum_identifier(PointerRNA& ptr, const char *name)
381 {
382         PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
383         const char *identifier = "";
384         int value = RNA_property_enum_get(&ptr, prop);
385
386         RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
387
388         return string(identifier);
389 }
390
391 static inline void set_enum(PointerRNA& ptr, const char *name, int value)
392 {
393         RNA_enum_set(&ptr, name, value);
394 }
395
396 static inline void set_enum(PointerRNA& ptr, const char *name, const string &identifier)
397 {
398         RNA_enum_set_identifier(NULL, &ptr, name, identifier.c_str());
399 }
400
401 static inline string get_string(PointerRNA& ptr, const char *name)
402 {
403         char cstrbuf[1024];
404         char *cstr = RNA_string_get_alloc(&ptr, name, cstrbuf, sizeof(cstrbuf));
405         string str(cstr);
406         if(cstr != cstrbuf)
407                 MEM_freeN(cstr);
408         
409         return str;
410 }
411
412 static inline void set_string(PointerRNA& ptr, const char *name, const string &value)
413 {
414         RNA_string_set(&ptr, name, value.c_str());
415 }
416
417 /* Relative Paths */
418
419 static inline string blender_absolute_path(BL::BlendData& b_data,
420                                            BL::ID& b_id,
421                                            const string& path)
422 {
423         if(path.size() >= 2 && path[0] == '/' && path[1] == '/') {
424                 string dirname;
425                 
426                 if(b_id.library()) {
427                         BL::ID b_library_id(b_id.library());
428                         dirname = blender_absolute_path(b_data,
429                                                         b_library_id,
430                                                         b_id.library().filepath());
431                 }
432                 else
433                         dirname = b_data.filepath();
434
435                 return path_join(path_dirname(dirname), path.substr(2));
436         }
437
438         return path;
439 }
440
441 /* Texture Space */
442
443 static inline void mesh_texture_space(BL::Mesh& b_mesh,
444                                       float3& loc,
445                                       float3& size)
446 {
447         loc = get_float3(b_mesh.texspace_location());
448         size = get_float3(b_mesh.texspace_size());
449
450         if(size.x != 0.0f) size.x = 0.5f/size.x;
451         if(size.y != 0.0f) size.y = 0.5f/size.y;
452         if(size.z != 0.0f) size.z = 0.5f/size.z;
453
454         loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
455 }
456
457 /* object used for motion blur */
458 static inline bool object_use_motion(BL::Object& b_parent, BL::Object& b_ob)
459 {
460         PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
461         bool use_motion = get_boolean(cobject, "use_motion_blur");
462         /* If motion blur is enabled for the object we also check
463          * whether it's enabled for the parent object as well.
464          *
465          * This way we can control motion blur from the dupligroup
466          * duplicator much easier.
467          */
468         if(use_motion && b_parent.ptr.data != b_ob.ptr.data) {
469                 PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
470                 use_motion &= get_boolean(parent_cobject, "use_motion_blur");
471         }
472         return use_motion;
473 }
474
475 /* object motion steps */
476 static inline uint object_motion_steps(BL::Object& b_ob)
477 {
478         PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
479         uint steps = get_int(cobject, "motion_steps");
480
481         /* use uneven number of steps so we get one keyframe at the current frame,
482          * and ue 2^(steps - 1) so objects with more/fewer steps still have samples
483          * at the same times, to avoid sampling at many different times */
484         return (2 << (steps - 1)) + 1;
485 }
486
487 /* object uses deformation motion blur */
488 static inline bool object_use_deform_motion(BL::Object& b_parent,
489                                             BL::Object& b_ob)
490 {
491         PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
492         bool use_deform_motion = get_boolean(cobject, "use_deform_motion");
493         /* If motion blur is enabled for the object we also check
494          * whether it's enabled for the parent object as well.
495          *
496          * This way we can control motion blur from the dupligroup
497          * duplicator much easier.
498          */
499         if(use_deform_motion && b_parent.ptr.data != b_ob.ptr.data) {
500                 PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
501                 use_deform_motion &= get_boolean(parent_cobject, "use_deform_motion");
502         }
503         return use_deform_motion;
504 }
505
506 static inline BL::SmokeDomainSettings object_smoke_domain_find(BL::Object& b_ob)
507 {
508         BL::Object::modifiers_iterator b_mod;
509
510         for(b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
511                 if(b_mod->is_a(&RNA_SmokeModifier)) {
512                         BL::SmokeModifier b_smd(*b_mod);
513
514                         if(b_smd.smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN)
515                                 return b_smd.domain_settings();
516                 }
517         }
518         
519         return BL::SmokeDomainSettings(PointerRNA_NULL);
520 }
521
522 /* ID Map
523  *
524  * Utility class to keep in sync with blender data.
525  * Used for objects, meshes, lights and shaders. */
526
527 template<typename K, typename T>
528 class id_map {
529 public:
530         id_map(vector<T*> *scene_data_)
531         {
532                 scene_data = scene_data_;
533         }
534
535         T *find(const BL::ID& id)
536         {
537                 return find(id.ptr.id.data);
538         }
539
540         T *find(const K& key)
541         {
542                 if(b_map.find(key) != b_map.end()) {
543                         T *data = b_map[key];
544                         return data;
545                 }
546
547                 return NULL;
548         }
549
550         void set_recalc(const BL::ID& id)
551         {
552                 b_recalc.insert(id.ptr.data);
553         }
554
555         bool has_recalc()
556         {
557                 return !(b_recalc.empty());
558         }
559
560         void pre_sync()
561         {
562                 used_set.clear();
563         }
564
565         bool sync(T **r_data, const BL::ID& id)
566         {
567                 return sync(r_data, id, id, id.ptr.id.data);
568         }
569
570         bool sync(T **r_data, const BL::ID& id, const BL::ID& parent, const K& key)
571         {
572                 T *data = find(key);
573                 bool recalc;
574
575                 if(!data) {
576                         /* add data if it didn't exist yet */
577                         data = new T();
578                         scene_data->push_back(data);
579                         b_map[key] = data;
580                         recalc = true;
581                 }
582                 else {
583                         recalc = (b_recalc.find(id.ptr.data) != b_recalc.end());
584                         if(parent.ptr.data)
585                                 recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end());
586                 }
587
588                 used(data);
589
590                 *r_data = data;
591                 return recalc;
592         }
593
594         bool is_used(const K& key)
595         {
596                 T *data = find(key);
597                 return (data) ? used_set.find(data) != used_set.end() : false;
598         }
599
600         void used(T *data)
601         {
602                 /* tag data as still in use */
603                 used_set.insert(data);
604         }
605
606         void set_default(T *data)
607         {
608                 b_map[NULL] = data;
609         }
610
611         bool post_sync(bool do_delete = true)
612         {
613                 /* remove unused data */
614                 vector<T*> new_scene_data;
615                 typename vector<T*>::iterator it;
616                 bool deleted = false;
617
618                 for(it = scene_data->begin(); it != scene_data->end(); it++) {
619                         T *data = *it;
620
621                         if(do_delete && used_set.find(data) == used_set.end()) {
622                                 delete data;
623                                 deleted = true;
624                         }
625                         else
626                                 new_scene_data.push_back(data);
627                 }
628
629                 *scene_data = new_scene_data;
630
631                 /* update mapping */
632                 map<K, T*> new_map;
633                 typedef pair<const K, T*> TMapPair;
634                 typename map<K, T*>::iterator jt;
635
636                 for(jt = b_map.begin(); jt != b_map.end(); jt++) {
637                         TMapPair& pair = *jt;
638
639                         if(used_set.find(pair.second) != used_set.end())
640                                 new_map[pair.first] = pair.second;
641                 }
642
643                 used_set.clear();
644                 b_recalc.clear();
645                 b_map = new_map;
646
647                 return deleted;
648         }
649
650 protected:
651         vector<T*> *scene_data;
652         map<K, T*> b_map;
653         set<T*> used_set;
654         set<void*> b_recalc;
655 };
656
657 /* Object Key */
658
659 enum { OBJECT_PERSISTENT_ID_SIZE = 8 };
660
661 struct ObjectKey {
662         void *parent;
663         int id[OBJECT_PERSISTENT_ID_SIZE];
664         void *ob;
665
666         ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_)
667         : parent(parent_), ob(ob_)
668         {
669                 if(id_)
670                         memcpy(id, id_, sizeof(id));
671                 else
672                         memset(id, 0, sizeof(id));
673         }
674
675         bool operator<(const ObjectKey& k) const
676         {
677                 if(ob < k.ob) {
678                         return true;
679                 }
680                 else if(ob == k.ob) {
681                         if(parent < k.parent)
682                                 return true;
683                         else if(parent == k.parent)
684                                 return memcmp(id, k.id, sizeof(id)) < 0;
685                 }
686
687                 return false;
688         }
689 };
690
691 CCL_NAMESPACE_END
692
693 #endif /* __BLENDER_UTIL_H__ */
694