Cycles: Expose user-defined shutter curve to the interface
[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, BL::Object object, BL::Scene scene, bool apply_modifiers, bool render, bool calc_undeformed)
44 {
45         BL::Mesh me = data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, false, calc_undeformed);
46         if((bool)me) {
47                 if(me.use_auto_smooth()) {
48                         me.calc_normals_split();
49                 }
50                 me.calc_tessface(true);
51         }
52         return me;
53 }
54
55 static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size)
56 {
57         for(int i = 0; i < size; i++) {
58                 float color[4];
59
60                 ramp.evaluate((float)i/(float)(size-1), color);
61                 data[i] = make_float4(color[0], color[1], color[2], color[3]);
62         }
63 }
64
65 static inline void curvemapping_to_array(BL::CurveMapping cumap, float *data, int size)
66 {
67         cumap.update();
68         BL::CurveMap curve = cumap.curves[0];
69         for(int i = 0; i < size; i++) {
70                 float t = (float)i/(float)(size-1);
71                 data[i] = curve.evaluate(t);
72         }
73 }
74
75 static inline void curvemapping_color_to_array(BL::CurveMapping cumap, float4 *data, int size, bool rgb_curve)
76 {
77         cumap.update();
78
79         BL::CurveMap mapR = cumap.curves[0];
80         BL::CurveMap mapG = cumap.curves[1];
81         BL::CurveMap mapB = cumap.curves[2];
82
83         if(rgb_curve) {
84                 BL::CurveMap mapI = cumap.curves[3];
85
86                 for(int i = 0; i < size; i++) {
87                         float t = (float)i/(float)(size-1);
88
89                         data[i][0] = mapR.evaluate(mapI.evaluate(t));
90                         data[i][1] = mapG.evaluate(mapI.evaluate(t));
91                         data[i][2] = mapB.evaluate(mapI.evaluate(t));
92                 }
93         }
94         else {
95                 for(int i = 0; i < size; i++) {
96                         float t = (float)i/(float)(size-1);
97
98                         data[i][0] = mapR.evaluate(t);
99                         data[i][1] = mapG.evaluate(t);
100                         data[i][2] = mapB.evaluate(t);
101                 }
102         }
103 }
104
105 static inline bool BKE_object_is_modified(BL::Object self, BL::Scene scene, bool preview)
106 {
107         return self.is_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
108 }
109
110 static inline bool BKE_object_is_deform_modified(BL::Object self, BL::Scene scene, bool preview)
111 {
112         return self.is_deform_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
113 }
114
115 static inline int render_resolution_x(BL::RenderSettings b_render)
116 {
117         return b_render.resolution_x()*b_render.resolution_percentage()/100;
118 }
119
120 static inline int render_resolution_y(BL::RenderSettings b_render)
121 {
122         return b_render.resolution_y()*b_render.resolution_percentage()/100;
123 }
124
125 static inline string image_user_file_path(BL::ImageUser iuser, BL::Image ima, int cfra)
126 {
127         char filepath[1024];
128         BKE_image_user_frame_calc(iuser.ptr.data, cfra, 0);
129         BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
130         return string(filepath);
131 }
132
133 static inline int image_user_frame_number(BL::ImageUser iuser, int cfra)
134 {
135         BKE_image_user_frame_calc(iuser.ptr.data, cfra, 0);
136         return iuser.frame_current();
137 }
138
139 static inline unsigned char *image_get_pixels_for_frame(BL::Image image, int frame)
140 {
141         return BKE_image_get_pixels_for_frame(image.ptr.data, frame);
142 }
143
144 static inline float *image_get_float_pixels_for_frame(BL::Image image, int frame)
145 {
146         return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame);
147 }
148
149 /* Utilities */
150
151 static inline Transform get_transform(BL::Array<float, 16> array)
152 {
153         Transform tfm;
154
155         /* we assume both types to be just 16 floats, and transpose because blender
156          * use column major matrix order while we use row major */
157         memcpy(&tfm, &array, sizeof(float)*16);
158         tfm = transform_transpose(tfm);
159
160         return tfm;
161 }
162
163 static inline float2 get_float2(BL::Array<float, 2> array)
164 {
165         return make_float2(array[0], array[1]);
166 }
167
168 static inline float3 get_float3(BL::Array<float, 2> array)
169 {
170         return make_float3(array[0], array[1], 0.0f);
171 }
172
173 static inline float3 get_float3(BL::Array<float, 3> array)
174 {
175         return make_float3(array[0], array[1], array[2]);
176 }
177
178 static inline float3 get_float3(BL::Array<float, 4> array)
179 {
180         return make_float3(array[0], array[1], array[2]);
181 }
182
183 static inline float4 get_float4(BL::Array<float, 4> array)
184 {
185         return make_float4(array[0], array[1], array[2], array[3]);
186 }
187
188 static inline int3 get_int3(BL::Array<int, 3> array)
189 {
190         return make_int3(array[0], array[1], array[2]);
191 }
192
193 static inline int4 get_int4(BL::Array<int, 4> array)
194 {
195         return make_int4(array[0], array[1], array[2], array[3]);
196 }
197
198 static inline uint get_layer(BL::Array<int, 20> array)
199 {
200         uint layer = 0;
201
202         for(uint i = 0; i < 20; i++)
203                 if(array[i])
204                         layer |= (1 << i);
205         
206         return layer;
207 }
208
209 static inline uint get_layer(BL::Array<int, 20> array,
210                              BL::Array<int, 8> local_array,
211                              bool use_local,
212                              bool is_light = false,
213                              uint scene_layers = (1 << 20) - 1)
214 {
215         uint layer = 0;
216
217         for(uint i = 0; i < 20; i++)
218                 if(array[i])
219                         layer |= (1 << i);
220
221         if(is_light) {
222                 /* Consider light is visible if it was visible without layer
223                  * override, which matches behavior of Blender Internal.
224                  */
225                 if(layer & scene_layers) {
226                         for(uint i = 0; i < 8; i++)
227                                 layer |= (1 << (20+i));
228                 }
229         }
230         else {
231                 for(uint i = 0; i < 8; i++)
232                         if(local_array[i])
233                                 layer |= (1 << (20+i));
234         }
235
236         /* we don't have spare bits for localview (normally 20-28) because
237          * PATH_RAY_LAYER_SHIFT uses 20-32. So - check if we have localview and if
238          * so, shift local view bits down to 1-8, since this is done for the view
239          * port only - it should be OK and not conflict with render layers. */
240         if(use_local)
241                 layer >>= 20;
242
243         return layer;
244 }
245
246 static inline float3 get_float3(PointerRNA& ptr, const char *name)
247 {
248         float3 f;
249         RNA_float_get_array(&ptr, name, &f.x);
250         return f;
251 }
252
253 static inline void set_float3(PointerRNA& ptr, const char *name, float3 value)
254 {
255         RNA_float_set_array(&ptr, name, &value.x);
256 }
257
258 static inline float4 get_float4(PointerRNA& ptr, const char *name)
259 {
260         float4 f;
261         RNA_float_get_array(&ptr, name, &f.x);
262         return f;
263 }
264
265 static inline void set_float4(PointerRNA& ptr, const char *name, float4 value)
266 {
267         RNA_float_set_array(&ptr, name, &value.x);
268 }
269
270 static inline bool get_boolean(PointerRNA& ptr, const char *name)
271 {
272         return RNA_boolean_get(&ptr, name)? true: false;
273 }
274
275 static inline void set_boolean(PointerRNA& ptr, const char *name, bool value)
276 {
277         RNA_boolean_set(&ptr, name, (int)value);
278 }
279
280 static inline float get_float(PointerRNA& ptr, const char *name)
281 {
282         return RNA_float_get(&ptr, name);
283 }
284
285 static inline void set_float(PointerRNA& ptr, const char *name, float value)
286 {
287         RNA_float_set(&ptr, name, value);
288 }
289
290 static inline int get_int(PointerRNA& ptr, const char *name)
291 {
292         return RNA_int_get(&ptr, name);
293 }
294
295 static inline void set_int(PointerRNA& ptr, const char *name, int value)
296 {
297         RNA_int_set(&ptr, name, value);
298 }
299
300 static inline int get_enum(PointerRNA& ptr, const char *name)
301 {
302         return RNA_enum_get(&ptr, name);
303 }
304
305 static inline string get_enum_identifier(PointerRNA& ptr, const char *name)
306 {
307         PropertyRNA *prop = RNA_struct_find_property(&ptr, name);
308         const char *identifier = "";
309         int value = RNA_property_enum_get(&ptr, prop);
310
311         RNA_property_enum_identifier(NULL, &ptr, prop, value, &identifier);
312
313         return string(identifier);
314 }
315
316 static inline void set_enum(PointerRNA& ptr, const char *name, int value)
317 {
318         RNA_enum_set(&ptr, name, value);
319 }
320
321 static inline void set_enum(PointerRNA& ptr, const char *name, const string &identifier)
322 {
323         RNA_enum_set_identifier(&ptr, name, identifier.c_str());
324 }
325
326 static inline string get_string(PointerRNA& ptr, const char *name)
327 {
328         char cstrbuf[1024];
329         char *cstr = RNA_string_get_alloc(&ptr, name, cstrbuf, sizeof(cstrbuf));
330         string str(cstr);
331         if(cstr != cstrbuf)
332                 MEM_freeN(cstr);
333         
334         return str;
335 }
336
337 static inline void set_string(PointerRNA& ptr, const char *name, const string &value)
338 {
339         RNA_string_set(&ptr, name, value.c_str());
340 }
341
342 /* Relative Paths */
343
344 static inline string blender_absolute_path(BL::BlendData b_data, BL::ID b_id, const string& path)
345 {
346         if(path.size() >= 2 && path[0] == '/' && path[1] == '/') {
347                 string dirname;
348                 
349                 if(b_id.library())
350                         dirname = blender_absolute_path(b_data, b_id.library(), b_id.library().filepath());
351                 else
352                         dirname = b_data.filepath();
353
354                 return path_join(path_dirname(dirname), path.substr(2));
355         }
356
357         return path;
358 }
359
360 /* Texture Space */
361
362 static inline void mesh_texture_space(BL::Mesh b_mesh, float3& loc, float3& size)
363 {
364         loc = get_float3(b_mesh.texspace_location());
365         size = get_float3(b_mesh.texspace_size());
366
367         if(size.x != 0.0f) size.x = 0.5f/size.x;
368         if(size.y != 0.0f) size.y = 0.5f/size.y;
369         if(size.z != 0.0f) size.z = 0.5f/size.z;
370
371         loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
372 }
373
374 /* object used for motion blur */
375 static inline bool object_use_motion(BL::Object b_parent, BL::Object b_ob)
376 {
377         PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
378         bool use_motion = get_boolean(cobject, "use_motion_blur");
379         /* If motion blur is enabled for the object we also check
380          * whether it's enabled for the parent object as well.
381          *
382          * This way we can control motion blur from the dupligroup
383          * duplicator much easier.
384          */
385         if(use_motion && b_parent.ptr.data != b_ob.ptr.data) {
386                 PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
387                 use_motion &= get_boolean(parent_cobject, "use_motion_blur");
388         }
389         return use_motion;
390 }
391
392 /* object motion steps */
393 static inline uint object_motion_steps(BL::Object b_ob)
394 {
395         PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
396         uint steps = get_int(cobject, "motion_steps");
397
398         /* use uneven number of steps so we get one keyframe at the current frame,
399          * and ue 2^(steps - 1) so objects with more/fewer steps still have samples
400          * at the same times, to avoid sampling at many different times */
401         return (2 << (steps - 1)) + 1;
402 }
403
404 /* object uses deformation motion blur */
405 static inline bool object_use_deform_motion(BL::Object b_parent, BL::Object b_ob)
406 {
407         PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
408         bool use_deform_motion = get_boolean(cobject, "use_deform_motion");
409         /* If motion blur is enabled for the object we also check
410          * whether it's enabled for the parent object as well.
411          *
412          * This way we can control motion blur from the dupligroup
413          * duplicator much easier.
414          */
415         if(use_deform_motion && b_parent.ptr.data != b_ob.ptr.data) {
416                 PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
417                 use_deform_motion &= get_boolean(parent_cobject, "use_deform_motion");
418         }
419         return use_deform_motion;
420 }
421
422 static inline BL::SmokeDomainSettings object_smoke_domain_find(BL::Object b_ob)
423 {
424         BL::Object::modifiers_iterator b_mod;
425
426         for(b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
427                 if(b_mod->is_a(&RNA_SmokeModifier)) {
428                         BL::SmokeModifier b_smd(*b_mod);
429
430                         if(b_smd.smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN)
431                                 return b_smd.domain_settings();
432                 }
433         }
434         
435         return BL::SmokeDomainSettings(PointerRNA_NULL);
436 }
437
438 /* ID Map
439  *
440  * Utility class to keep in sync with blender data.
441  * Used for objects, meshes, lights and shaders. */
442
443 template<typename K, typename T>
444 class id_map {
445 public:
446         id_map(vector<T*> *scene_data_)
447         {
448                 scene_data = scene_data_;
449         }
450
451         T *find(BL::ID id)
452         {
453                 return find(id.ptr.id.data);
454         }
455
456         T *find(const K& key)
457         {
458                 if(b_map.find(key) != b_map.end()) {
459                         T *data = b_map[key];
460                         return data;
461                 }
462
463                 return NULL;
464         }
465
466         void set_recalc(BL::ID id)
467         {
468                 b_recalc.insert(id.ptr.data);
469         }
470
471         bool has_recalc()
472         {
473                 return !(b_recalc.empty());
474         }
475
476         void pre_sync()
477         {
478                 used_set.clear();
479         }
480
481         bool sync(T **r_data, BL::ID id)
482         {
483                 return sync(r_data, id, id, id.ptr.id.data);
484         }
485
486         bool sync(T **r_data, BL::ID id, BL::ID parent, const K& key)
487         {
488                 T *data = find(key);
489                 bool recalc;
490
491                 if(!data) {
492                         /* add data if it didn't exist yet */
493                         data = new T();
494                         scene_data->push_back(data);
495                         b_map[key] = data;
496                         recalc = true;
497                 }
498                 else {
499                         recalc = (b_recalc.find(id.ptr.data) != b_recalc.end());
500                         if(parent.ptr.data)
501                                 recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end());
502                 }
503
504                 used(data);
505
506                 *r_data = data;
507                 return recalc;
508         }
509
510         bool is_used(const K& key)
511         {
512                 T *data = find(key);
513                 return (data) ? used_set.find(data) != used_set.end() : false;
514         }
515
516         void used(T *data)
517         {
518                 /* tag data as still in use */
519                 used_set.insert(data);
520         }
521
522         void set_default(T *data)
523         {
524                 b_map[NULL] = data;
525         }
526
527         bool post_sync(bool do_delete = true)
528         {
529                 /* remove unused data */
530                 vector<T*> new_scene_data;
531                 typename vector<T*>::iterator it;
532                 bool deleted = false;
533
534                 for(it = scene_data->begin(); it != scene_data->end(); it++) {
535                         T *data = *it;
536
537                         if(do_delete && used_set.find(data) == used_set.end()) {
538                                 delete data;
539                                 deleted = true;
540                         }
541                         else
542                                 new_scene_data.push_back(data);
543                 }
544
545                 *scene_data = new_scene_data;
546
547                 /* update mapping */
548                 map<K, T*> new_map;
549                 typedef pair<const K, T*> TMapPair;
550                 typename map<K, T*>::iterator jt;
551
552                 for(jt = b_map.begin(); jt != b_map.end(); jt++) {
553                         TMapPair& pair = *jt;
554
555                         if(used_set.find(pair.second) != used_set.end())
556                                 new_map[pair.first] = pair.second;
557                 }
558
559                 used_set.clear();
560                 b_recalc.clear();
561                 b_map = new_map;
562
563                 return deleted;
564         }
565
566 protected:
567         vector<T*> *scene_data;
568         map<K, T*> b_map;
569         set<T*> used_set;
570         set<void*> b_recalc;
571 };
572
573 /* Object Key */
574
575 enum { OBJECT_PERSISTENT_ID_SIZE = 8 };
576
577 struct ObjectKey {
578         void *parent;
579         int id[OBJECT_PERSISTENT_ID_SIZE];
580         void *ob;
581
582         ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_)
583         : parent(parent_), ob(ob_)
584         {
585                 if(id_)
586                         memcpy(id, id_, sizeof(id));
587                 else
588                         memset(id, 0, sizeof(id));
589         }
590
591         bool operator<(const ObjectKey& k) const
592         {
593                 if(ob < k.ob) {
594                         return true;
595                 }
596                 else if(ob == k.ob) {
597                         if(parent < k.parent)
598                                 return true;
599                         else if(parent == k.parent)
600                                 return memcmp(id, k.id, sizeof(id)) < 0;
601                 }
602
603                 return false;
604         }
605 };
606
607 /* Particle System Key */
608
609 struct ParticleSystemKey {
610         void *ob;
611         int id[OBJECT_PERSISTENT_ID_SIZE];
612
613         ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE])
614         : ob(ob_)
615         {
616                 if(id_)
617                         memcpy(id, id_, sizeof(id));
618                 else
619                         memset(id, 0, sizeof(id));
620         }
621
622         bool operator<(const ParticleSystemKey& k) const
623         {
624                 /* first id is particle index, we don't compare that */
625                 if(ob < k.ob)
626                         return true;
627                 else if(ob == k.ob)
628                         return memcmp(id+1, k.id+1, sizeof(int)*(OBJECT_PERSISTENT_ID_SIZE-1)) < 0;
629
630                 return false;
631         }
632 };
633
634 CCL_NAMESPACE_END
635
636 #endif /* __BLENDER_UTIL_H__ */
637