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