Fix inconsistent/broken Cycles object visibility for instances.
[blender.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 "render/camera.h"
18 #include "render/integrator.h"
19 #include "render/graph.h"
20 #include "render/light.h"
21 #include "render/mesh.h"
22 #include "render/object.h"
23 #include "render/scene.h"
24 #include "render/nodes.h"
25 #include "render/particles.h"
26 #include "render/shader.h"
27
28 #include "blender/blender_object_cull.h"
29 #include "blender/blender_sync.h"
30 #include "blender/blender_util.h"
31
32 #include "util/util_foreach.h"
33 #include "util/util_hash.h"
34 #include "util/util_logging.h"
35
36 CCL_NAMESPACE_BEGIN
37
38 /* Utilities */
39
40 bool BlenderSync::BKE_object_is_modified(BL::Object& b_ob)
41 {
42         /* test if we can instance or if the object is modified */
43         if(b_ob.type() == BL::Object::type_META) {
44                 /* multi-user and dupli metaballs are fused, can't instance */
45                 return true;
46         }
47         else if(ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
48                 /* modifiers */
49                 return true;
50         }
51         else {
52                 /* object level material links */
53                 BL::Object::material_slots_iterator slot;
54                 for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
55                         if(slot->link() == BL::MaterialSlot::link_OBJECT)
56                                 return true;
57         }
58
59         return false;
60 }
61
62 bool BlenderSync::object_is_mesh(BL::Object& b_ob)
63 {
64         BL::ID b_ob_data = b_ob.data();
65
66         if(!b_ob_data) {
67                 return false;
68         }
69
70         if(b_ob.type() == BL::Object::type_CURVE) {
71                 /* Skip exporting curves without faces, overhead can be
72                  * significant if there are many for path animation. */
73                 BL::Curve b_curve(b_ob.data());
74
75                 return (b_curve.bevel_object() ||
76                         b_curve.extrude() != 0.0f ||
77                         b_curve.bevel_depth() != 0.0f ||
78                         b_curve.dimensions() == BL::Curve::dimensions_2D ||
79                         b_ob.modifiers.length());
80         }
81         else {
82                 return (b_ob_data.is_a(&RNA_Mesh) ||
83                         b_ob_data.is_a(&RNA_Curve) ||
84                         b_ob_data.is_a(&RNA_MetaBall));
85         }
86 }
87
88 bool BlenderSync::object_is_light(BL::Object& b_ob)
89 {
90         BL::ID b_ob_data = b_ob.data();
91
92         return (b_ob_data && b_ob_data.is_a(&RNA_Light));
93 }
94
95 static uint object_ray_visibility(BL::Object& b_ob)
96 {
97         PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility");
98         uint flag = 0;
99
100         flag |= get_boolean(cvisibility, "camera")? PATH_RAY_CAMERA: 0;
101         flag |= get_boolean(cvisibility, "diffuse")? PATH_RAY_DIFFUSE: 0;
102         flag |= get_boolean(cvisibility, "glossy")? PATH_RAY_GLOSSY: 0;
103         flag |= get_boolean(cvisibility, "transmission")? PATH_RAY_TRANSMIT: 0;
104         flag |= get_boolean(cvisibility, "shadow")? PATH_RAY_SHADOW: 0;
105         flag |= get_boolean(cvisibility, "scatter")? PATH_RAY_VOLUME_SCATTER: 0;
106
107         return flag;
108 }
109
110 /* Light */
111
112 void BlenderSync::sync_light(BL::Object& b_parent,
113                              int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
114                              BL::Object& b_ob,
115                              BL::Object& b_ob_instance,
116                              int random_id,
117                              Transform& tfm,
118                              bool *use_portal)
119 {
120         /* test if we need to sync */
121         Light *light;
122         ObjectKey key(b_parent, persistent_id, b_ob_instance);
123
124         if(!light_map.sync(&light, b_ob, b_parent, key)) {
125                 if(light->is_portal)
126                         *use_portal = true;
127                 return;
128         }
129
130         BL::Light b_light(b_ob.data());
131
132         /* type */
133         switch(b_light.type()) {
134                 case BL::Light::type_POINT: {
135                         BL::PointLight b_point_light(b_light);
136                         light->size = b_point_light.shadow_soft_size();
137                         light->type = LIGHT_POINT;
138                         break;
139                 }
140                 case BL::Light::type_SPOT: {
141                         BL::SpotLight b_spot_light(b_light);
142                         light->size = b_spot_light.shadow_soft_size();
143                         light->type = LIGHT_SPOT;
144                         light->spot_angle = b_spot_light.spot_size();
145                         light->spot_smooth = b_spot_light.spot_blend();
146                         break;
147                 }
148                 /* Hemi were removed from 2.8 */
149                 // case BL::Light::type_HEMI: {
150                 //      light->type = LIGHT_DISTANT;
151                 //      light->size = 0.0f;
152                 //      break;
153                 // }
154                 case BL::Light::type_SUN: {
155                         BL::SunLight b_sun_light(b_light);
156                         light->size = b_sun_light.shadow_soft_size();
157                         light->type = LIGHT_DISTANT;
158                         break;
159                 }
160                 case BL::Light::type_AREA: {
161                         BL::AreaLight b_area_light(b_light);
162                         light->size = 1.0f;
163                         light->axisu = transform_get_column(&tfm, 0);
164                         light->axisv = transform_get_column(&tfm, 1);
165                         light->sizeu = b_area_light.size();
166                         switch(b_area_light.shape()) {
167                                 case BL::AreaLight::shape_SQUARE:
168                                         light->sizev = light->sizeu;
169                                         light->round = false;
170                                         break;
171                                 case BL::AreaLight::shape_RECTANGLE:
172                                         light->sizev = b_area_light.size_y();
173                                         light->round = false;
174                                         break;
175                                 case BL::AreaLight::shape_DISK:
176                                         light->sizev = light->sizeu;
177                                         light->round = true;
178                                         break;
179                                 case BL::AreaLight::shape_ELLIPSE:
180                                         light->sizev = b_area_light.size_y();
181                                         light->round = true;
182                                         break;
183                         }
184                         light->type = LIGHT_AREA;
185                         break;
186                 }
187         }
188
189         /* location and (inverted!) direction */
190         light->co = transform_get_column(&tfm, 3);
191         light->dir = -transform_get_column(&tfm, 2);
192         light->tfm = tfm;
193
194         /* shader */
195         vector<Shader*> used_shaders;
196         find_shader(b_light, used_shaders, scene->default_light);
197         light->shader = used_shaders[0];
198
199         /* shadow */
200         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
201         PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
202         light->cast_shadow = get_boolean(clight, "cast_shadow");
203         light->use_mis = get_boolean(clight, "use_multiple_importance_sampling");
204
205         int samples = get_int(clight, "samples");
206         if(get_boolean(cscene, "use_square_samples"))
207                 light->samples = samples * samples;
208         else
209                 light->samples = samples;
210
211         light->max_bounces = get_int(clight, "max_bounces");
212
213         if(b_ob != b_ob_instance) {
214                 light->random_id = random_id;
215         }
216         else {
217                 light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
218         }
219
220         if(light->type == LIGHT_AREA)
221                 light->is_portal = get_boolean(clight, "is_portal");
222         else
223                 light->is_portal = false;
224
225         if(light->is_portal)
226                 *use_portal = true;
227
228         /* visibility */
229         uint visibility = object_ray_visibility(b_ob);
230         light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
231         light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0;
232         light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0;
233         light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0;
234
235         /* tag */
236         light->tag_update(scene);
237 }
238
239 void BlenderSync::sync_background_light(bool use_portal)
240 {
241         BL::World b_world = b_scene.world();
242
243         if(b_world) {
244                 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
245                 PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
246
247                 enum SamplingMethod {
248                         SAMPLING_NONE = 0,
249                         SAMPLING_AUTOMATIC,
250                         SAMPLING_MANUAL,
251                         SAMPLING_NUM
252                 };
253                 int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
254                 bool sample_as_light = (sampling_method != SAMPLING_NONE);
255
256                 if(sample_as_light || use_portal) {
257                         /* test if we need to sync */
258                         Light *light;
259                         ObjectKey key(b_world, 0, b_world);
260
261                         if(light_map.sync(&light, b_world, b_world, key) ||
262                             world_recalc ||
263                             b_world.ptr.data != world_map)
264                         {
265                                 light->type = LIGHT_BACKGROUND;
266                                 if(sampling_method == SAMPLING_MANUAL) {
267                                         light->map_resolution = get_int(cworld, "sample_map_resolution");
268                                 }
269                                 else {
270                                         light->map_resolution = 0;
271                                 }
272                                 light->shader = scene->default_background;
273                                 light->use_mis = sample_as_light;
274                                 light->max_bounces = get_int(cworld, "max_bounces");
275
276                                 int samples = get_int(cworld, "samples");
277                                 if(get_boolean(cscene, "use_square_samples"))
278                                         light->samples = samples * samples;
279                                 else
280                                         light->samples = samples;
281
282                                 light->tag_update(scene);
283                                 light_map.set_recalc(b_world);
284                         }
285                 }
286         }
287
288         world_map = b_world.ptr.data;
289         world_recalc = false;
290 }
291
292 /* Object */
293
294 Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
295                                  BL::ViewLayer& b_view_layer,
296                                  BL::DepsgraphObjectInstance& b_instance,
297                                  float motion_time,
298                                  bool show_self,
299                                  bool show_particles,
300                                  BlenderObjectCulling& culling,
301                                  bool *use_portal)
302 {
303         const bool is_instance = b_instance.is_instance();
304         BL::Object b_ob = b_instance.object();
305         BL::Object b_parent = is_instance ? b_instance.parent()
306                                           : b_instance.object();
307         BL::Object b_ob_instance = is_instance ? b_instance.instance_object()
308                                                : b_ob;
309         const bool motion = motion_time != 0.0f;
310         /*const*/ Transform tfm = get_transform(b_ob.matrix_world());
311         int *persistent_id = NULL;
312         BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
313         if(is_instance) {
314                 persistent_id_array = b_instance.persistent_id();
315                 persistent_id = persistent_id_array.data;
316         }
317
318         /* light is handled separately */
319         if(!motion && object_is_light(b_ob)) {
320                 /* TODO: don't use lights for excluded layers used as mask layer,
321                  * when dynamic overrides are back. */
322 #if 0
323                 if(!((layer_flag & view_layer.holdout_layer) &&
324                      (layer_flag & view_layer.exclude_layer)))
325 #endif
326                 {
327                         sync_light(b_parent,
328                                    persistent_id,
329                                    b_ob,
330                                    b_ob_instance,
331                                    is_instance ? b_instance.random_id() : 0,
332                                    tfm,
333                                    use_portal);
334                 }
335
336                 return NULL;
337         }
338
339         /* only interested in object that we can create meshes from */
340         if(!object_is_mesh(b_ob)) {
341                 return NULL;
342         }
343
344         /* Perform object culling. */
345         if(culling.test(scene, b_ob, tfm)) {
346                 return NULL;
347         }
348
349         /* Visibility flags for both parent and child. */
350         PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
351         bool use_holdout = get_boolean(cobject, "is_holdout") ||
352                            b_parent.holdout_get(b_view_layer);
353         uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
354
355         if(b_parent.ptr.data != b_ob.ptr.data) {
356                 visibility &= object_ray_visibility(b_parent);
357         }
358
359         /* TODO: make holdout objects on excluded layer invisible for non-camera rays. */
360 #if 0
361         if(use_holdout && (layer_flag & view_layer.exclude_layer)) {
362                 visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
363         }
364 #endif
365
366         /* Clear camera visibility for indirect only objects. */
367         bool use_indirect_only = b_parent.indirect_only_get(b_view_layer);
368         if(use_indirect_only) {
369                 visibility &= ~PATH_RAY_CAMERA;
370         }
371
372         /* Don't export completely invisible objects. */
373         if(visibility == 0) {
374                 return NULL;
375         }
376
377         /* key to lookup object */
378         ObjectKey key(b_parent, persistent_id, b_ob_instance);
379         Object *object;
380
381         /* motion vector case */
382         if(motion) {
383                 object = object_map.find(key);
384
385                 if(object && object->use_motion()) {
386                         /* Set transform at matching motion time step. */
387                         int time_index = object->motion_step(motion_time);
388                         if(time_index >= 0) {
389                                 object->motion[time_index] = tfm;
390                         }
391
392                         /* mesh deformation */
393                         if(object->mesh)
394                                 sync_mesh_motion(b_depsgraph, b_ob, object, motion_time);
395                 }
396
397                 return object;
398         }
399
400         /* test if we need to sync */
401         bool object_updated = false;
402
403         if(object_map.sync(&object, b_ob, b_parent, key))
404                 object_updated = true;
405
406         /* mesh sync */
407         object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, show_self, show_particles);
408
409         /* special case not tracked by object update flags */
410
411         /* holdout */
412         if(use_holdout != object->use_holdout) {
413                 object->use_holdout = use_holdout;
414                 scene->object_manager->tag_update(scene);
415                 object_updated = true;
416         }
417
418         if(visibility != object->visibility) {
419                 object->visibility = visibility;
420                 object_updated = true;
421         }
422
423         bool is_shadow_catcher = get_boolean(cobject, "is_shadow_catcher");
424         if(is_shadow_catcher != object->is_shadow_catcher) {
425                 object->is_shadow_catcher = is_shadow_catcher;
426                 object_updated = true;
427         }
428
429         /* sync the asset name for Cryptomatte */
430         BL::Object parent = b_ob.parent();
431         ustring parent_name;
432         if(parent) {
433                 while(parent.parent()) {
434                         parent = parent.parent();
435                 }
436                 parent_name = parent.name();
437         }
438         else {
439                 parent_name = b_ob.name();
440         }
441         if(object->asset_name != parent_name) {
442                 object->asset_name = parent_name;
443                 object_updated = true;
444         }
445
446         /* object sync
447          * transform comparison should not be needed, but duplis don't work perfect
448          * in the depsgraph and may not signal changes, so this is a workaround */
449         if(object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) {
450                 object->name = b_ob.name().c_str();
451                 object->pass_id = b_ob.pass_index();
452                 object->tfm = tfm;
453                 object->motion.clear();
454
455                 /* motion blur */
456                 Scene::MotionType need_motion = scene->need_motion();
457                 if(need_motion != Scene::MOTION_NONE && object->mesh) {
458                         Mesh *mesh = object->mesh;
459                         mesh->use_motion_blur = false;
460                         mesh->motion_steps = 0;
461
462                         uint motion_steps;
463
464                         if(scene->need_motion() == Scene::MOTION_BLUR) {
465                                 motion_steps = object_motion_steps(b_parent, b_ob);
466                                 mesh->motion_steps = motion_steps;
467                                 if(motion_steps && object_use_deform_motion(b_parent, b_ob)) {
468                                         mesh->use_motion_blur = true;
469                                 }
470                         }
471                         else {
472                                 motion_steps = 3;
473                                 mesh->motion_steps = motion_steps;
474                         }
475
476                         object->motion.clear();
477                         object->motion.resize(motion_steps, transform_empty());
478
479                         if(motion_steps) {
480                                 object->motion[motion_steps/2] = tfm;
481
482                                 for(size_t step = 0; step < motion_steps; step++) {
483                                         motion_times.insert(object->motion_time(step));
484                                 }
485                         }
486                 }
487
488                 /* dupli texture coordinates and random_id */
489                 if(is_instance) {
490                         object->dupli_generated = 0.5f*get_float3(b_instance.orco()) - make_float3(0.5f, 0.5f, 0.5f);
491                         object->dupli_uv = get_float2(b_instance.uv());
492                         object->random_id = b_instance.random_id();
493
494                         /* Sync possible particle data. */
495                         sync_dupli_particle(b_ob, b_instance, object);
496                 }
497                 else {
498                         object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
499                         object->dupli_uv = make_float2(0.0f, 0.0f);
500                         object->random_id =  hash_int_2d(hash_string(object->name.c_str()), 0);
501                 }
502
503                 object->tag_update(scene);
504         }
505
506         return object;
507 }
508
509 /* Object Loop */
510
511 void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
512 {
513         /* layer data */
514         bool motion = motion_time != 0.0f;
515
516         if(!motion) {
517                 /* prepare for sync */
518                 light_map.pre_sync();
519                 mesh_map.pre_sync();
520                 object_map.pre_sync();
521                 particle_system_map.pre_sync();
522                 motion_times.clear();
523         }
524         else {
525                 mesh_motion_synced.clear();
526         }
527
528         /* initialize culling */
529         BlenderObjectCulling culling(scene, b_scene);
530
531         /* object loop */
532         bool cancel = false;
533         bool use_portal = false;
534
535         BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
536
537         BL::Depsgraph::object_instances_iterator b_instance_iter;
538         for(b_depsgraph.object_instances.begin(b_instance_iter);
539             b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
540             ++b_instance_iter)
541         {
542                 BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
543                 BL::Object b_ob = b_instance.object();
544
545                 progress.set_sync_status("Synchronizing object", b_ob.name());
546
547                 /* load per-object culling data */
548                 culling.init_object(scene, b_ob);
549
550                 /* test if object needs to be hidden */
551                 const bool show_self = b_instance.show_self();
552                 const bool show_particles = b_instance.show_particles();
553
554                  if(show_self || show_particles) {
555                         /* object itself */
556                         sync_object(b_depsgraph,
557                                     b_view_layer,
558                                     b_instance,
559                                     motion_time,
560                                     show_self,
561                                     show_particles,
562                                     culling,
563                                     &use_portal);
564                  }
565
566                 cancel = progress.get_cancel();
567         }
568
569         progress.set_sync_status("");
570
571         if(!cancel && !motion) {
572                 sync_background_light(use_portal);
573
574                 /* handle removed data and modified pointers */
575                 if(light_map.post_sync())
576                         scene->light_manager->tag_update(scene);
577                 if(mesh_map.post_sync())
578                         scene->mesh_manager->tag_update(scene);
579                 if(object_map.post_sync())
580                         scene->object_manager->tag_update(scene);
581                 if(particle_system_map.post_sync())
582                         scene->particle_system_manager->tag_update(scene);
583         }
584
585         if(motion)
586                 mesh_motion_synced.clear();
587 }
588
589 void BlenderSync::sync_motion(BL::RenderSettings& b_render,
590                               BL::Depsgraph& b_depsgraph,
591                               BL::Object& b_override,
592                               int width, int height,
593                               void **python_thread_state)
594 {
595         if(scene->need_motion() == Scene::MOTION_NONE)
596                 return;
597
598         /* get camera object here to deal with camera switch */
599         BL::Object b_cam = b_scene.camera();
600         if(b_override)
601                 b_cam = b_override;
602
603         Camera prevcam = *(scene->camera);
604
605         int frame_center = b_scene.frame_current();
606         float subframe_center = b_scene.frame_subframe();
607         float frame_center_delta = 0.0f;
608
609         if(scene->need_motion() != Scene::MOTION_PASS &&
610            scene->camera->motion_position != Camera::MOTION_POSITION_CENTER)
611         {
612                 float shuttertime = scene->camera->shuttertime;
613                 if(scene->camera->motion_position == Camera::MOTION_POSITION_END) {
614                         frame_center_delta = -shuttertime * 0.5f;
615                 }
616                 else {
617                         assert(scene->camera->motion_position == Camera::MOTION_POSITION_START);
618                         frame_center_delta = shuttertime * 0.5f;
619                 }
620
621                 float time = frame_center + subframe_center + frame_center_delta;
622                 int frame = (int)floorf(time);
623                 float subframe = time - frame;
624                 python_thread_state_restore(python_thread_state);
625                 b_engine.frame_set(frame, subframe);
626                 python_thread_state_save(python_thread_state);
627                 sync_camera_motion(b_render, b_cam, width, height, 0.0f);
628                 sync_objects(b_depsgraph, 0.0f);
629         }
630
631         /* always sample these times for camera motion */
632         motion_times.insert(-1.0f);
633         motion_times.insert(1.0f);
634
635         /* note iteration over motion_times set happens in sorted order */
636         foreach(float relative_time, motion_times) {
637                 /* center time is already handled. */
638                 if(relative_time == 0.0f) {
639                         continue;
640                 }
641
642                 VLOG(1) << "Synchronizing motion for the relative time "
643                         << relative_time << ".";
644
645                 /* fixed shutter time to get previous and next frame for motion pass */
646                 float shuttertime = scene->motion_shutter_time();
647
648                 /* compute frame and subframe time */
649                 float time = frame_center + subframe_center + frame_center_delta + relative_time * shuttertime * 0.5f;
650                 int frame = (int)floorf(time);
651                 float subframe = time - frame;
652
653                 /* change frame */
654                 python_thread_state_restore(python_thread_state);
655                 b_engine.frame_set(frame, subframe);
656                 python_thread_state_save(python_thread_state);
657
658                 /* sync camera, only supports two times at the moment */
659                 if(relative_time == -1.0f || relative_time == 1.0f) {
660                         sync_camera_motion(b_render,
661                                            b_cam,
662                                            width, height,
663                                            relative_time);
664                 }
665
666                 /* sync object */
667                 sync_objects(b_depsgraph, relative_time);
668         }
669
670         /* we need to set the python thread state again because this
671          * function assumes it is being executed from python and will
672          * try to save the thread state */
673         python_thread_state_restore(python_thread_state);
674         b_engine.frame_set(frame_center, subframe_center);
675         python_thread_state_save(python_thread_state);
676
677         /* tag camera for motion update */
678         if(scene->camera->motion_modified(prevcam))
679                 scene->camera->tag_update();
680 }
681
682 CCL_NAMESPACE_END