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