Cycles: Code cleanup, spaces around keywords
[blender-staging.git] / intern / cycles / blender / blender_object.cpp
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 #include "camera.h"
18 #include "integrator.h"
19 #include "graph.h"
20 #include "light.h"
21 #include "mesh.h"
22 #include "object.h"
23 #include "scene.h"
24 #include "nodes.h"
25 #include "particles.h"
26 #include "shader.h"
27
28 #include "blender_sync.h"
29 #include "blender_util.h"
30
31 #include "util_foreach.h"
32 #include "util_hash.h"
33 #include "util_logging.h"
34
35 CCL_NAMESPACE_BEGIN
36
37 /* Utilities */
38
39 bool BlenderSync::BKE_object_is_modified(BL::Object b_ob)
40 {
41         /* test if we can instance or if the object is modified */
42         if(b_ob.type() == BL::Object::type_META) {
43                 /* multi-user and dupli metaballs are fused, can't instance */
44                 return true;
45         }
46         else if(ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
47                 /* modifiers */
48                 return true;
49         }
50         else {
51                 /* object level material links */
52                 BL::Object::material_slots_iterator slot;
53                 for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
54                         if(slot->link() == BL::MaterialSlot::link_OBJECT)
55                                 return true;
56         }
57
58         return false;
59 }
60
61 bool BlenderSync::object_is_mesh(BL::Object b_ob)
62 {
63         BL::ID b_ob_data = b_ob.data();
64
65         return (b_ob_data && (b_ob_data.is_a(&RNA_Mesh) ||
66                 b_ob_data.is_a(&RNA_Curve) || b_ob_data.is_a(&RNA_MetaBall)));
67 }
68
69 bool BlenderSync::object_is_light(BL::Object b_ob)
70 {
71         BL::ID b_ob_data = b_ob.data();
72
73         return (b_ob_data && b_ob_data.is_a(&RNA_Lamp));
74 }
75
76 static uint object_ray_visibility(BL::Object b_ob)
77 {
78         PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility");
79         uint flag = 0;
80
81         flag |= get_boolean(cvisibility, "camera")? PATH_RAY_CAMERA: 0;
82         flag |= get_boolean(cvisibility, "diffuse")? PATH_RAY_DIFFUSE: 0;
83         flag |= get_boolean(cvisibility, "glossy")? PATH_RAY_GLOSSY: 0;
84         flag |= get_boolean(cvisibility, "transmission")? PATH_RAY_TRANSMIT: 0;
85         flag |= get_boolean(cvisibility, "shadow")? PATH_RAY_SHADOW: 0;
86         flag |= get_boolean(cvisibility, "scatter")? PATH_RAY_VOLUME_SCATTER: 0;
87
88         return flag;
89 }
90
91 /* Light */
92
93 void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm)
94 {
95         /* test if we need to sync */
96         Light *light;
97         ObjectKey key(b_parent, persistent_id, b_ob);
98
99         if(!light_map.sync(&light, b_ob, b_parent, key))
100                 return;
101         
102         BL::Lamp b_lamp(b_ob.data());
103
104         /* type */
105         switch(b_lamp.type()) {
106                 case BL::Lamp::type_POINT: {
107                         BL::PointLamp b_point_lamp(b_lamp);
108                         light->size = b_point_lamp.shadow_soft_size();
109                         light->type = LIGHT_POINT;
110                         break;
111                 }
112                 case BL::Lamp::type_SPOT: {
113                         BL::SpotLamp b_spot_lamp(b_lamp);
114                         light->size = b_spot_lamp.shadow_soft_size();
115                         light->type = LIGHT_SPOT;
116                         light->spot_angle = b_spot_lamp.spot_size();
117                         light->spot_smooth = b_spot_lamp.spot_blend();
118                         break;
119                 }
120                 case BL::Lamp::type_HEMI: {
121                         light->type = LIGHT_DISTANT;
122                         light->size = 0.0f;
123                         break;
124                 }
125                 case BL::Lamp::type_SUN: {
126                         BL::SunLamp b_sun_lamp(b_lamp);
127                         light->size = b_sun_lamp.shadow_soft_size();
128                         light->type = LIGHT_DISTANT;
129                         break;
130                 }
131                 case BL::Lamp::type_AREA: {
132                         BL::AreaLamp b_area_lamp(b_lamp);
133                         light->size = 1.0f;
134                         light->axisu = transform_get_column(&tfm, 0);
135                         light->axisv = transform_get_column(&tfm, 1);
136                         light->sizeu = b_area_lamp.size();
137                         if(b_area_lamp.shape() == BL::AreaLamp::shape_RECTANGLE)
138                                 light->sizev = b_area_lamp.size_y();
139                         else
140                                 light->sizev = light->sizeu;
141                         light->type = LIGHT_AREA;
142                         break;
143                 }
144         }
145
146         /* location and (inverted!) direction */
147         light->co = transform_get_column(&tfm, 3);
148         light->dir = -transform_get_column(&tfm, 2);
149
150         /* shader */
151         vector<uint> used_shaders;
152
153         find_shader(b_lamp, used_shaders, scene->default_light);
154
155         if(used_shaders.size() == 0)
156                 used_shaders.push_back(scene->default_light);
157
158         light->shader = used_shaders[0];
159
160         /* shadow */
161         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
162         PointerRNA clamp = RNA_pointer_get(&b_lamp.ptr, "cycles");
163         light->cast_shadow = get_boolean(clamp, "cast_shadow");
164         light->use_mis = get_boolean(clamp, "use_multiple_importance_sampling");
165         
166         int samples = get_int(clamp, "samples");
167         if(get_boolean(cscene, "use_square_samples"))
168                 light->samples = samples * samples;
169         else
170                 light->samples = samples;
171
172         light->max_bounces = get_int(clamp, "max_bounces");
173
174         /* visibility */
175         uint visibility = object_ray_visibility(b_ob);
176         light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
177         light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0;
178         light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0;
179         light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0;
180
181         /* tag */
182         light->tag_update(scene);
183 }
184
185 void BlenderSync::sync_background_light()
186 {
187         BL::World b_world = b_scene.world();
188
189         if(b_world) {
190                 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
191                 PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
192                 bool sample_as_light = get_boolean(cworld, "sample_as_light");
193
194                 if(sample_as_light) {
195                         /* test if we need to sync */
196                         Light *light;
197                         ObjectKey key(b_world, 0, b_world);
198
199                         if(light_map.sync(&light, b_world, b_world, key) ||
200                            world_recalc ||
201                            b_world.ptr.data != world_map)
202                         {
203                                 light->type = LIGHT_BACKGROUND;
204                                 light->map_resolution  = get_int(cworld, "sample_map_resolution");
205                                 light->shader = scene->default_background;
206                                 
207                                 int samples = get_int(cworld, "samples");
208                                 if(get_boolean(cscene, "use_square_samples"))
209                                         light->samples = samples * samples;
210                                 else
211                                         light->samples = samples;
212
213                                 light->tag_update(scene);
214                                 light_map.set_recalc(b_world);
215                         }
216                 }
217         }
218
219         world_map = b_world.ptr.data;
220         world_recalc = false;
221 }
222
223 /* Object */
224
225 Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob,
226                                  Transform& tfm, uint layer_flag, float motion_time, bool hide_tris)
227 {
228         BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
229         bool motion = motion_time != 0.0f;
230         
231         /* light is handled separately */
232         if(object_is_light(b_ob)) {
233                 /* don't use lamps for excluded layers used as mask layer */
234                 if(!motion && !((layer_flag & render_layer.holdout_layer) && (layer_flag & render_layer.exclude_layer)))
235                         sync_light(b_parent, persistent_id, b_ob, tfm);
236
237                 return NULL;
238         }
239
240         /* only interested in object that we can create meshes from */
241         if(!object_is_mesh(b_ob))
242                 return NULL;
243
244         /* key to lookup object */
245         ObjectKey key(b_parent, persistent_id, b_ob);
246         Object *object;
247
248         /* motion vector case */
249         if(motion) {
250                 object = object_map.find(key);
251
252                 if(object && (scene->need_motion() == Scene::MOTION_PASS || object_use_motion(b_ob))) {
253                         /* object transformation */
254                         if(tfm != object->tfm) {
255                                 VLOG(1) << "Object " << b_ob.name() << " motion detected.";
256                                 if(motion_time == -1.0f) {
257                                         object->motion.pre = tfm;
258                                         object->use_motion = true;
259                                 }
260                                 else if(motion_time == 1.0f) {
261                                         object->motion.post = tfm;
262                                         object->use_motion = true;
263                                 }
264                         }
265
266                         /* mesh deformation */
267                         if(object->mesh)
268                                 sync_mesh_motion(b_ob, object, motion_time);
269                 }
270
271                 return object;
272         }
273
274         /* test if we need to sync */
275         bool object_updated = false;
276
277         if(object_map.sync(&object, b_ob, b_parent, key))
278                 object_updated = true;
279         
280         bool use_holdout = (layer_flag & render_layer.holdout_layer) != 0;
281         
282         /* mesh sync */
283         object->mesh = sync_mesh(b_ob, object_updated, hide_tris);
284
285         /* special case not tracked by object update flags */
286
287         /* holdout */
288         if(use_holdout != object->use_holdout) {
289                 object->use_holdout = use_holdout;
290                 scene->object_manager->tag_update(scene);
291                 object_updated = true;
292         }
293
294         /* visibility flags for both parent and child */
295         uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
296         if(b_parent.ptr.data != b_ob.ptr.data) {
297                 visibility &= object_ray_visibility(b_parent);
298         }
299
300         /* make holdout objects on excluded layer invisible for non-camera rays */
301         if(use_holdout && (layer_flag & render_layer.exclude_layer))
302                 visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
303
304         /* camera flag is not actually used, instead is tested against render layer
305          * flags */
306         if(visibility & PATH_RAY_CAMERA) {
307                 visibility |= layer_flag << PATH_RAY_LAYER_SHIFT;
308                 visibility &= ~PATH_RAY_CAMERA;
309         }
310
311         if(visibility != object->visibility) {
312                 object->visibility = visibility;
313                 object_updated = true;
314         }
315
316         /* object sync
317          * transform comparison should not be needed, but duplis don't work perfect
318          * in the depsgraph and may not signal changes, so this is a workaround */
319         if(object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) {
320                 object->name = b_ob.name().c_str();
321                 object->pass_id = b_ob.pass_index();
322                 object->tfm = tfm;
323                 object->motion.pre = tfm;
324                 object->motion.post = tfm;
325                 object->use_motion = false;
326
327                 /* motion blur */
328                 if(scene->need_motion() == Scene::MOTION_BLUR && object->mesh) {
329                         Mesh *mesh = object->mesh;
330
331                         mesh->use_motion_blur = false;
332
333                         if(object_use_motion(b_ob)) {
334                                 if(object_use_deform_motion(b_ob)) {
335                                         mesh->motion_steps = object_motion_steps(b_ob);
336                                         mesh->use_motion_blur = true;
337                                 }
338
339                                 vector<float> times = object->motion_times();
340                                 foreach(float time, times)
341                                         motion_times.insert(time);
342                         }
343                 }
344
345                 /* random number */
346                 object->random_id = hash_string(object->name.c_str());
347
348                 if(persistent_id) {
349                         for(int i = 0; i < OBJECT_PERSISTENT_ID_SIZE; i++)
350                                 object->random_id = hash_int_2d(object->random_id, persistent_id[i]);
351                 }
352                 else
353                         object->random_id = hash_int_2d(object->random_id, 0);
354
355                 if(b_parent.ptr.data != b_ob.ptr.data)
356                         object->random_id ^= hash_int(hash_string(b_parent.name().c_str()));
357
358                 /* dupli texture coordinates */
359                 if(b_dupli_ob) {
360                         object->dupli_generated = 0.5f*get_float3(b_dupli_ob.orco()) - make_float3(0.5f, 0.5f, 0.5f);
361                         object->dupli_uv = get_float2(b_dupli_ob.uv());
362                 }
363                 else {
364                         object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
365                         object->dupli_uv = make_float2(0.0f, 0.0f);
366                 }
367
368                 object->tag_update(scene);
369         }
370
371         return object;
372 }
373
374 static bool object_render_hide_original(BL::Object::type_enum ob_type, BL::Object::dupli_type_enum dupli_type)
375 {
376         /* metaball exception, they duplicate self */
377         if(ob_type == BL::Object::type_META)
378                 return false;
379
380         return (dupli_type == BL::Object::dupli_type_VERTS ||
381                 dupli_type == BL::Object::dupli_type_FACES ||
382                 dupli_type == BL::Object::dupli_type_FRAMES);
383 }
384
385 static bool object_render_hide(BL::Object b_ob, bool top_level, bool parent_hide, bool& hide_triangles)
386 {
387         /* check if we should render or hide particle emitter */
388         BL::Object::particle_systems_iterator b_psys;
389
390         bool hair_present = false;
391         bool show_emitter = false;
392         bool hide_emitter = false;
393         bool hide_as_dupli_parent = false;
394         bool hide_as_dupli_child_original = false;
395
396         for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
397                 if((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) &&
398                    (b_psys->settings().type()==BL::ParticleSettings::type_HAIR))
399                         hair_present = true;
400
401                 if(b_psys->settings().use_render_emitter())
402                         show_emitter = true;
403                 else
404                         hide_emitter = true;
405         }
406
407         if(show_emitter)
408                 hide_emitter = false;
409
410         /* duplicators hidden by default, except dupliframes which duplicate self */
411         if(b_ob.is_duplicator())
412                 if(top_level || b_ob.dupli_type() != BL::Object::dupli_type_FRAMES)
413                         hide_as_dupli_parent = true;
414
415         /* hide original object for duplis */
416         BL::Object parent = b_ob.parent();
417         while(parent) {
418                 if(object_render_hide_original(b_ob.type(),
419                                                parent.dupli_type()))
420                 {
421                         if(parent_hide) {
422                                 hide_as_dupli_child_original = true;
423                                 break;
424                         }
425                 }
426                 parent = parent.parent();
427         }
428         
429         hide_triangles = hide_emitter;
430
431         if(show_emitter) {
432                 return false;
433         }
434         else if(hair_present) {
435                 return hide_as_dupli_child_original;
436         }
437         else {
438                 return (hide_as_dupli_parent || hide_as_dupli_child_original);
439         }
440 }
441
442 static bool object_render_hide_duplis(BL::Object b_ob)
443 {
444         BL::Object parent = b_ob.parent();
445
446         return (parent && object_render_hide_original(b_ob.type(), parent.dupli_type()));
447 }
448
449 /* Object Loop */
450
451 void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
452 {
453         /* layer data */
454         uint scene_layer = render_layer.scene_layer;
455         bool motion = motion_time != 0.0f;
456         
457         if(!motion) {
458                 /* prepare for sync */
459                 light_map.pre_sync();
460                 mesh_map.pre_sync();
461                 object_map.pre_sync();
462                 particle_system_map.pre_sync();
463                 motion_times.clear();
464         }
465         else {
466                 mesh_motion_synced.clear();
467         }
468
469         /* object loop */
470         BL::Scene::object_bases_iterator b_base;
471         BL::Scene b_sce = b_scene;
472         /* modifier result type (not exposed as enum in C++ API)
473          * 1 : DAG_EVAL_PREVIEW
474          * 2 : DAG_EVAL_RENDER
475          */
476         int dupli_settings = preview ? 1 : 2;
477
478         bool cancel = false;
479
480         for(; b_sce && !cancel; b_sce = b_sce.background_set()) {
481                 for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) {
482                         BL::Object b_ob = b_base->object();
483                         bool hide = (render_layer.use_viewport_visibility)? b_ob.hide(): b_ob.hide_render();
484                         uint ob_layer = get_layer(b_base->layers(), b_base->layers_local_view(), render_layer.use_localview, object_is_light(b_ob));
485                         hide = hide || !(ob_layer & scene_layer);
486
487                         if(!hide) {
488                                 progress.set_sync_status("Synchronizing object", b_ob.name());
489
490                                 if(b_ob.is_duplicator() && !object_render_hide_duplis(b_ob)) {
491                                         /* dupli objects */
492                                         b_ob.dupli_list_create(b_scene, dupli_settings);
493
494                                         BL::Object::dupli_list_iterator b_dup;
495
496                                         for(b_ob.dupli_list.begin(b_dup); b_dup != b_ob.dupli_list.end(); ++b_dup) {
497                                                 Transform tfm = get_transform(b_dup->matrix());
498                                                 BL::Object b_dup_ob = b_dup->object();
499                                                 bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render();
500                                                 bool in_dupli_group = (b_dup->type() == BL::DupliObject::type_GROUP);
501                                                 bool hide_tris;
502
503                                                 if(!(b_dup->hide() || dup_hide || object_render_hide(b_dup_ob, false, in_dupli_group, hide_tris))) {
504                                                         /* the persistent_id allows us to match dupli objects
505                                                          * between frames and updates */
506                                                         BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
507
508                                                         /* sync object and mesh or light data */
509                                                         Object *object = sync_object(b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion_time, hide_tris);
510
511                                                         /* sync possible particle data, note particle_id
512                                                          * starts counting at 1, first is dummy particle */
513                                                         if(!motion && object) {
514                                                                 sync_dupli_particle(b_ob, *b_dup, object);
515                                                         }
516
517                                                 }
518                                         }
519
520                                         b_ob.dupli_list_clear();
521                                 }
522
523                                 /* test if object needs to be hidden */
524                                 bool hide_tris;
525
526                                 if(!object_render_hide(b_ob, true, true, hide_tris)) {
527                                         /* object itself */
528                                         Transform tfm = get_transform(b_ob.matrix_world());
529                                         sync_object(b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion_time, hide_tris);
530                                 }
531                         }
532
533                         cancel = progress.get_cancel();
534                 }
535         }
536
537         progress.set_sync_status("");
538
539         if(!cancel && !motion) {
540                 sync_background_light();
541
542                 /* handle removed data and modified pointers */
543                 if(light_map.post_sync())
544                         scene->light_manager->tag_update(scene);
545                 if(mesh_map.post_sync())
546                         scene->mesh_manager->tag_update(scene);
547                 if(object_map.post_sync())
548                         scene->object_manager->tag_update(scene);
549                 if(particle_system_map.post_sync())
550                         scene->particle_system_manager->tag_update(scene);
551         }
552
553         if(motion)
554                 mesh_motion_synced.clear();
555 }
556
557 void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state)
558 {
559         if(scene->need_motion() == Scene::MOTION_NONE)
560                 return;
561
562         /* get camera object here to deal with camera switch */
563         BL::Object b_cam = b_scene.camera();
564         if(b_override)
565                 b_cam = b_override;
566
567         Camera prevcam = *(scene->camera);
568
569         int frame_center = b_scene.frame_current();
570
571         /* always sample these times for camera motion */
572         motion_times.insert(-1.0f);
573         motion_times.insert(1.0f);
574
575         /* note iteration over motion_times set happens in sorted order */
576         foreach(float relative_time, motion_times) {
577                 /* fixed shutter time to get previous and next frame for motion pass */
578                 float shuttertime;
579
580                 if(scene->need_motion() == Scene::MOTION_PASS)
581                         shuttertime = 2.0f;
582                 else
583                         shuttertime = scene->camera->shuttertime;
584
585                 /* compute frame and subframe time */
586                 float time = frame_center + relative_time * shuttertime * 0.5f;
587                 int frame = (int)floorf(time);
588                 float subframe = time - frame;
589
590                 /* change frame */
591                 python_thread_state_restore(python_thread_state);
592                 b_engine.frame_set(frame, subframe);
593                 python_thread_state_save(python_thread_state);
594
595                 /* sync camera, only supports two times at the moment */
596                 if(relative_time == -1.0f || relative_time == 1.0f)
597                         sync_camera_motion(b_cam, relative_time);
598
599                 /* sync object */
600                 sync_objects(b_v3d, relative_time);
601         }
602
603         /* we need to set the python thread state again because this
604          * function assumes it is being executed from python and will
605          * try to save the thread state */
606         python_thread_state_restore(python_thread_state);
607         b_engine.frame_set(frame_center, 0.0f);
608         python_thread_state_save(python_thread_state);
609
610         /* tag camera for motion update */
611         if(scene->camera->motion_modified(prevcam))
612                 scene->camera->tag_update();
613 }
614
615 CCL_NAMESPACE_END
616