daa872239ce69f63174cb5043edb351840d94199
[blender-staging.git] / intern / cycles / render / 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 "device/device.h"
19 #include "render/light.h"
20 #include "render/mesh.h"
21 #include "render/curves.h"
22 #include "render/object.h"
23 #include "render/particles.h"
24 #include "render/scene.h"
25
26 #include "util/util_foreach.h"
27 #include "util/util_logging.h"
28 #include "util/util_map.h"
29 #include "util/util_progress.h"
30 #include "util/util_vector.h"
31
32 #include "subd/subd_patch_table.h"
33
34 CCL_NAMESPACE_BEGIN
35
36 /* Object */
37
38 NODE_DEFINE(Object)
39 {
40         NodeType* type = NodeType::add("object", create);
41
42         SOCKET_NODE(mesh, "Mesh", &Mesh::node_type);
43         SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
44         SOCKET_UINT(visibility, "Visibility", ~0);
45         SOCKET_UINT(random_id, "Random ID", 0);
46         SOCKET_INT(pass_id, "Pass ID", 0);
47         SOCKET_BOOLEAN(use_holdout, "Use Holdout", false);
48         SOCKET_BOOLEAN(hide_on_missing_motion, "Hide on Missing Motion", false);
49         SOCKET_POINT(dupli_generated, "Dupli Generated", make_float3(0.0f, 0.0f, 0.0f));
50         SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f));
51
52         SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false);
53
54         return type;
55 }
56
57 Object::Object()
58 : Node(node_type)
59 {
60         particle_system = NULL;
61         particle_index = 0;
62         bounds = BoundBox::empty;
63         motion.pre = transform_empty();
64         motion.mid = transform_empty();
65         motion.post = transform_empty();
66         use_motion = false;
67 }
68
69 Object::~Object()
70 {
71 }
72
73 void Object::compute_bounds(bool motion_blur)
74 {
75         BoundBox mbounds = mesh->bounds;
76
77         if(motion_blur && use_motion) {
78                 MotionTransform mtfm = motion;
79
80                 if(hide_on_missing_motion) {
81                         /* Hide objects that have no valid previous or next transform, for
82                          * example particle that stop existing. TODO: add support for this
83                          * case in the kernel so we don't get render artifacts. */
84                         if(mtfm.pre == transform_empty() ||
85                            mtfm.post == transform_empty()) {
86                                 bounds = BoundBox::empty;
87                                 return;
88                         }
89                 }
90
91                 /* In case of missing motion information for previous/next frame,
92                  * assume there is no motion. */
93                 if(mtfm.pre == transform_empty()) {
94                         mtfm.pre = tfm;
95                 }
96                 if(mtfm.post == transform_empty()) {
97                         mtfm.post = tfm;
98                 }
99
100                 DecompMotionTransform decomp;
101                 transform_motion_decompose(&decomp, &mtfm, &tfm);
102
103                 bounds = BoundBox::empty;
104
105                 /* todo: this is really terrible. according to pbrt there is a better
106                  * way to find this iteratively, but did not find implementation yet
107                  * or try to implement myself */
108                 for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
109                         Transform ttfm;
110
111                         transform_motion_interpolate(&ttfm, &decomp, t);
112                         bounds.grow(mbounds.transformed(&ttfm));
113                 }
114         }
115         else {
116                 if(mesh->transform_applied) {
117                         bounds = mbounds;
118                 }
119                 else {
120                         bounds = mbounds.transformed(&tfm);
121                 }
122         }
123 }
124
125 void Object::apply_transform(bool apply_to_motion)
126 {
127         if(!mesh || tfm == transform_identity())
128                 return;
129         
130         /* triangles */
131         if(mesh->verts.size()) {
132                 /* store matrix to transform later. when accessing these as attributes we
133                  * do not want the transform to be applied for consistency between static
134                  * and dynamic BVH, so we do it on packing. */
135                 mesh->transform_normal = transform_transpose(transform_inverse(tfm));
136
137                 /* apply to mesh vertices */
138                 for(size_t i = 0; i < mesh->verts.size(); i++)
139                         mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
140                 
141                 if(apply_to_motion) {
142                         Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
143
144                         if(attr) {
145                                 size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
146                                 float3 *vert_steps = attr->data_float3();
147
148                                 for(size_t i = 0; i < steps_size; i++)
149                                         vert_steps[i] = transform_point(&tfm, vert_steps[i]);
150                         }
151
152                         Attribute *attr_N = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
153
154                         if(attr_N) {
155                                 Transform ntfm = mesh->transform_normal;
156                                 size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
157                                 float3 *normal_steps = attr_N->data_float3();
158
159                                 for(size_t i = 0; i < steps_size; i++)
160                                         normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
161                         }
162                 }
163         }
164
165         /* curves */
166         if(mesh->curve_keys.size()) {
167                 /* compute uniform scale */
168                 float3 c0 = transform_get_column(&tfm, 0);
169                 float3 c1 = transform_get_column(&tfm, 1);
170                 float3 c2 = transform_get_column(&tfm, 2);
171                 float scalar = powf(fabsf(dot(cross(c0, c1), c2)), 1.0f/3.0f);
172
173                 /* apply transform to curve keys */
174                 for(size_t i = 0; i < mesh->curve_keys.size(); i++) {
175                         float3 co = transform_point(&tfm, mesh->curve_keys[i]);
176                         float radius = mesh->curve_radius[i] * scalar;
177
178                         /* scale for curve radius is only correct for uniform scale */
179                         mesh->curve_keys[i] = co;
180                         mesh->curve_radius[i] = radius;
181                 }
182
183                 if(apply_to_motion) {
184                         Attribute *curve_attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
185
186                         if(curve_attr) {
187                                 /* apply transform to motion curve keys */
188                                 size_t steps_size = mesh->curve_keys.size() * (mesh->motion_steps - 1);
189                                 float4 *key_steps = curve_attr->data_float4();
190
191                                 for(size_t i = 0; i < steps_size; i++) {
192                                         float3 co = transform_point(&tfm, float4_to_float3(key_steps[i]));
193                                         float radius = key_steps[i].w * scalar;
194
195                                         /* scale for curve radius is only correct for uniform scale */
196                                         key_steps[i] = float3_to_float4(co);
197                                         key_steps[i].w = radius;
198                                 }
199                         }
200                 }
201         }
202
203         /* we keep normals pointing in same direction on negative scale, notify
204          * mesh about this in it (re)calculates normals */
205         if(transform_negative_scale(tfm))
206                 mesh->transform_negative_scaled = true;
207
208         if(bounds.valid()) {
209                 mesh->compute_bounds();
210                 compute_bounds(false);
211         }
212
213         /* tfm is not reset to identity, all code that uses it needs to check the
214          * transform_applied boolean */
215 }
216
217 void Object::tag_update(Scene *scene)
218 {
219         if(mesh) {
220                 if(mesh->transform_applied)
221                         mesh->need_update = true;
222
223                 foreach(Shader *shader, mesh->used_shaders) {
224                         if(shader->use_mis && shader->has_surface_emission)
225                                 scene->light_manager->need_update = true;
226                 }
227         }
228
229         scene->camera->need_flags_update = true;
230         scene->curve_system_manager->need_update = true;
231         scene->mesh_manager->need_update = true;
232         scene->object_manager->need_update = true;
233 }
234
235 vector<float> Object::motion_times()
236 {
237         /* compute times at which we sample motion for this object */
238         vector<float> times;
239
240         if(!mesh || mesh->motion_steps == 1)
241                 return times;
242
243         int motion_steps = mesh->motion_steps;
244
245         for(int step = 0; step < motion_steps; step++) {
246                 if(step != motion_steps / 2) {
247                         float time = 2.0f * step / (motion_steps - 1) - 1.0f;
248                         times.push_back(time);
249                 }
250         }
251
252         return times;
253 }
254
255 bool Object::is_traceable()
256 {
257         /* Mesh itself can be empty,can skip all such objects. */
258         if(!bounds.valid() || bounds.size() == make_float3(0.0f, 0.0f, 0.0f)) {
259                 return false;
260         }
261         /* TODO(sergey): Check for mesh vertices/curves. visibility flags. */
262         return true;
263 }
264
265 uint Object::visibility_for_tracing() const {
266         uint trace_visibility = visibility;
267         if (is_shadow_catcher) {
268                 trace_visibility &= ~PATH_RAY_SHADOW_NON_CATCHER;
269         }
270         else {
271                 trace_visibility &= ~PATH_RAY_SHADOW_CATCHER;
272         }
273         return trace_visibility;
274 }
275
276 /* Object Manager */
277
278 ObjectManager::ObjectManager()
279 {
280         need_update = true;
281         need_flags_update = true;
282 }
283
284 ObjectManager::~ObjectManager()
285 {
286 }
287
288 void ObjectManager::device_update_object_transform(UpdateObejctTransformState *state,
289                                                    Object *ob,
290                                                    int object_index)
291 {
292         float4 *objects = state->objects;
293         float4 *objects_vector = state->objects_vector;
294
295         Mesh *mesh = ob->mesh;
296         uint flag = 0;
297
298         /* Compute transformations. */
299         Transform tfm = ob->tfm;
300         Transform itfm = transform_inverse(tfm);
301
302         /* Compute surface area. for uniform scale we can do avoid the many
303          * transform calls and share computation for instances.
304          *
305          * TODO(brecht): Correct for displacement, and move to a better place.
306          */
307         float uniform_scale;
308         float surface_area = 0.0f;
309         float pass_id = ob->pass_id;
310         float random_number = (float)ob->random_id * (1.0f/(float)0xFFFFFFFF);
311         int particle_index = (ob->particle_system)
312                 ? ob->particle_index + state->particle_offset[ob->particle_system]
313                 : 0;
314
315         if(transform_uniform_scale(tfm, uniform_scale)) {
316                 map<Mesh*, float>::iterator it;
317
318                 /* NOTE: This isn't fully optimal and could in theory lead to multiple
319                  * threads calculating area of the same mesh in parallel. However, this
320                  * also prevents suspending all the threads when some mesh's area is
321                  * not yet known.
322                  */
323                 state->surface_area_lock.lock();
324                 it = state->surface_area_map.find(mesh);
325                 state->surface_area_lock.unlock();
326
327                 if(it == state->surface_area_map.end()) {
328                         size_t num_triangles = mesh->num_triangles();
329                         for(size_t j = 0; j < num_triangles; j++) {
330                                 Mesh::Triangle t = mesh->get_triangle(j);
331                                 float3 p1 = mesh->verts[t.v[0]];
332                                 float3 p2 = mesh->verts[t.v[1]];
333                                 float3 p3 = mesh->verts[t.v[2]];
334
335                                 surface_area += triangle_area(p1, p2, p3);
336                         }
337
338                         state->surface_area_lock.lock();
339                         state->surface_area_map[mesh] = surface_area;
340                         state->surface_area_lock.unlock();
341                 }
342                 else {
343                         surface_area = it->second;
344                 }
345
346                 surface_area *= uniform_scale;
347         }
348         else {
349                 size_t num_triangles = mesh->num_triangles();
350                 for(size_t j = 0; j < num_triangles; j++) {
351                         Mesh::Triangle t = mesh->get_triangle(j);
352                         float3 p1 = transform_point(&tfm, mesh->verts[t.v[0]]);
353                         float3 p2 = transform_point(&tfm, mesh->verts[t.v[1]]);
354                         float3 p3 = transform_point(&tfm, mesh->verts[t.v[2]]);
355
356                         surface_area += triangle_area(p1, p2, p3);
357                 }
358         }
359
360         /* Pack in texture. */
361         int offset = object_index*OBJECT_SIZE;
362
363         /* OBJECT_TRANSFORM */
364         memcpy(&objects[offset], &tfm, sizeof(float4)*3);
365         /* OBJECT_INVERSE_TRANSFORM */
366         memcpy(&objects[offset+4], &itfm, sizeof(float4)*3);
367         /* OBJECT_PROPERTIES */
368         objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(particle_index));
369
370         if(mesh->use_motion_blur) {
371                 state->have_motion = true;
372         }
373         if(mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
374                 flag |= SD_OBJECT_HAS_VERTEX_MOTION;
375         }
376
377         if(state->need_motion == Scene::MOTION_PASS) {
378                 /* Motion transformations, is world/object space depending if mesh
379                  * comes with deformed position in object space, or if we transform
380                  * the shading point in world space.
381                  */
382                 MotionTransform mtfm = ob->motion;
383
384                 /* In case of missing motion information for previous/next frame,
385                  * assume there is no motion. */
386                 if(!ob->use_motion || mtfm.pre == transform_empty()) {
387                         mtfm.pre = ob->tfm;
388                 }
389                 if(!ob->use_motion || mtfm.post == transform_empty()) {
390                         mtfm.post = ob->tfm;
391                 }
392
393                 if(!mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
394                         mtfm.pre = mtfm.pre * itfm;
395                         mtfm.post = mtfm.post * itfm;
396                 }
397
398                 memcpy(&objects_vector[object_index*OBJECT_VECTOR_SIZE+0], &mtfm.pre, sizeof(float4)*3);
399                 memcpy(&objects_vector[object_index*OBJECT_VECTOR_SIZE+3], &mtfm.post, sizeof(float4)*3);
400         }
401 #ifdef __OBJECT_MOTION__
402         else if(state->need_motion == Scene::MOTION_BLUR) {
403                 if(ob->use_motion) {
404                         /* decompose transformations for interpolation. */
405                         DecompMotionTransform decomp;
406
407                         transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
408                         memcpy(&objects[offset], &decomp, sizeof(float4)*8);
409                         flag |= SD_OBJECT_MOTION;
410                         state->have_motion = true;
411                 }
412         }
413 #endif
414
415         /* Dupli object coords and motion info. */
416         int totalsteps = mesh->motion_steps;
417         int numsteps = (totalsteps - 1)/2;
418         int numverts = mesh->verts.size();
419         int numkeys = mesh->curve_keys.size();
420
421         objects[offset+9] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], __int_as_float(numkeys));
422         objects[offset+10] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], __int_as_float(numsteps), __int_as_float(numverts));
423
424         /* Object flag. */
425         if(ob->use_holdout) {
426                 flag |= SD_OBJECT_HOLDOUT_MASK;
427         }
428         state->object_flag[object_index] = flag;
429
430         /* Have curves. */
431         if(mesh->num_curves()) {
432                 state->have_curves = true;
433         }
434 }
435
436 bool ObjectManager::device_update_object_transform_pop_work(
437         UpdateObejctTransformState *state,
438         int *start_index,
439         int *num_objects)
440 {
441         /* Tweakable parameter, number of objects per chunk.
442          * Too small value will cause some extra overhead due to spin lock,
443          * too big value might not use all threads nicely.
444          */
445         static const int OBJECTS_PER_TASK = 32;
446         bool have_work = false;
447         state->queue_lock.lock();
448         int num_scene_objects = state->scene->objects.size();
449         if(state->queue_start_object < num_scene_objects) {
450                 int count = min(OBJECTS_PER_TASK,
451                                 num_scene_objects - state->queue_start_object);
452                 *start_index = state->queue_start_object;
453                 *num_objects = count;
454                 state->queue_start_object += count;
455                 have_work = true;
456         }
457         state->queue_lock.unlock();
458         return have_work;
459 }
460
461 void ObjectManager::device_update_object_transform_task(
462         UpdateObejctTransformState *state)
463 {
464         int start_index, num_objects;
465         while(device_update_object_transform_pop_work(state,
466                                                       &start_index,
467                                                       &num_objects))
468         {
469                 for(int i = 0; i < num_objects; ++i) {
470                         const int object_index = start_index + i;
471                         Object *ob = state->scene->objects[object_index];
472                         device_update_object_transform(state, ob, object_index);
473                 }
474         }
475 }
476
477 void ObjectManager::device_update_transforms(Device *device,
478                                              DeviceScene *dscene,
479                                              Scene *scene,
480                                              uint *object_flag,
481                                              Progress& progress)
482 {
483         UpdateObejctTransformState state;
484         state.need_motion = scene->need_motion(device->info.advanced_shading);
485         state.have_motion = false;
486         state.have_curves = false;
487         state.scene = scene;
488         state.queue_start_object = 0;
489
490         state.object_flag = object_flag;
491         state.objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
492         if(state.need_motion == Scene::MOTION_PASS) {
493                 state.objects_vector = dscene->objects_vector.resize(OBJECT_VECTOR_SIZE*scene->objects.size());
494         }
495         else {
496                 state.objects_vector = NULL;
497         }
498
499         /* Particle system device offsets
500          * 0 is dummy particle, index starts at 1.
501          */
502         int numparticles = 1;
503         foreach(ParticleSystem *psys, scene->particle_systems) {
504                 state.particle_offset[psys] = numparticles;
505                 numparticles += psys->particles.size();
506         }
507
508         /* NOTE: If it's just a handful of objects we deal with them in a single
509          * thread to avoid threading overhead. However, this threshold is might
510          * need some tweaks to make mid-complex scenes optimal.
511          */
512         if(scene->objects.size() < 64) {
513                 int object_index = 0;
514                 foreach(Object *ob, scene->objects) {
515                         device_update_object_transform(&state, ob, object_index);
516                         object_index++;
517                         if(progress.get_cancel()) {
518                                 return;
519                         }
520                 }
521         }
522         else {
523                 const int num_threads = TaskScheduler::num_threads();
524                 TaskPool pool;
525                 for(int i = 0; i < num_threads; ++i) {
526                         pool.push(function_bind(
527                                 &ObjectManager::device_update_object_transform_task,
528                                 this,
529                                 &state));
530                 }
531                 pool.wait_work();
532                 if(progress.get_cancel()) {
533                         return;
534                 }
535         }
536
537         device->tex_alloc(dscene->objects);
538         if(state.need_motion == Scene::MOTION_PASS) {
539                 device->tex_alloc(dscene->objects_vector);
540         }
541
542         dscene->data.bvh.have_motion = state.have_motion;
543         dscene->data.bvh.have_curves = state.have_curves;
544         dscene->data.bvh.have_instancing = true;
545 }
546
547 void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
548 {
549         if(!need_update)
550                 return;
551
552         VLOG(1) << "Total " << scene->objects.size() << " objects.";
553
554         device_free(device, dscene);
555
556         if(scene->objects.size() == 0)
557                 return;
558
559         /* object info flag */
560         uint *object_flag = dscene->object_flag.resize(scene->objects.size());
561
562         /* set object transform matrices, before applying static transforms */
563         progress.set_status("Updating Objects", "Copying Transformations to device");
564         device_update_transforms(device, dscene, scene, object_flag, progress);
565
566         if(progress.get_cancel()) return;
567
568         /* prepare for static BVH building */
569         /* todo: do before to support getting object level coords? */
570         if(scene->params.bvh_type == SceneParams::BVH_STATIC) {
571                 progress.set_status("Updating Objects", "Applying Static Transformations");
572                 apply_static_transforms(dscene, scene, object_flag, progress);
573         }
574 }
575
576 void ObjectManager::device_update_flags(Device *device,
577                                         DeviceScene *dscene,
578                                         Scene *scene,
579                                         Progress& /*progress*/,
580                                         bool bounds_valid)
581 {
582         if(!need_update && !need_flags_update)
583                 return;
584
585         need_update = false;
586         need_flags_update = false;
587
588         if(scene->objects.size() == 0)
589                 return;
590
591         /* object info flag */
592         uint *object_flag = dscene->object_flag.get_data();
593
594         vector<Object *> volume_objects;
595         bool has_volume_objects = false;
596         foreach(Object *object, scene->objects) {
597                 if(object->mesh->has_volume) {
598                         if(bounds_valid) {
599                                 volume_objects.push_back(object);
600                         }
601                         has_volume_objects = true;
602                 }
603         }
604
605         int object_index = 0;
606         foreach(Object *object, scene->objects) {
607                 if(object->mesh->has_volume) {
608                         object_flag[object_index] |= SD_OBJECT_HAS_VOLUME;
609                 }
610                 else {
611                         object_flag[object_index] &= ~SD_OBJECT_HAS_VOLUME;
612                 }
613                 if(object->is_shadow_catcher) {
614                         object_flag[object_index] |= SD_OBJECT_SHADOW_CATCHER;
615                 }
616                 else {
617                         object_flag[object_index] &= ~SD_OBJECT_SHADOW_CATCHER;
618                 }
619
620                 if(bounds_valid) {
621                         foreach(Object *volume_object, volume_objects) {
622                                 if(object == volume_object) {
623                                         continue;
624                                 }
625                                 if(object->bounds.intersects(volume_object->bounds)) {
626                                         object_flag[object_index] |= SD_OBJECT_INTERSECTS_VOLUME;
627                                         break;
628                                 }
629                         }
630                 }
631                 else if(has_volume_objects) {
632                         /* Not really valid, but can't make more reliable in the case
633                          * of bounds not being up to date.
634                          */
635                         object_flag[object_index] |= SD_OBJECT_INTERSECTS_VOLUME;
636                 }
637                 ++object_index;
638         }
639
640         /* allocate object flag */
641         device->tex_alloc(dscene->object_flag);
642 }
643
644 void ObjectManager::device_update_patch_map_offsets(Device *device, DeviceScene *dscene, Scene *scene)
645 {
646         if(scene->objects.size() == 0) {
647                 return;
648         }
649
650         uint4* objects = (uint4*)dscene->objects.get_data();
651
652         bool update = false;
653
654         int object_index = 0;
655         foreach(Object *object, scene->objects) {
656                 int offset = object_index*OBJECT_SIZE + 11;
657
658                 Mesh* mesh = object->mesh;
659
660                 if(mesh->patch_table) {
661                         uint patch_map_offset = 2*(mesh->patch_table_offset + mesh->patch_table->total_size() -
662                                                    mesh->patch_table->num_nodes * PATCH_NODE_SIZE) - mesh->patch_offset;
663
664                         if(objects[offset].x != patch_map_offset) {
665                                 objects[offset].x = patch_map_offset;
666                                 update = true;
667                         }
668                 }
669
670                 object_index++;
671         }
672
673         if(update) {
674                 device->tex_free(dscene->objects);
675                 device->tex_alloc(dscene->objects);
676         }
677 }
678
679 void ObjectManager::device_free(Device *device, DeviceScene *dscene)
680 {
681         device->tex_free(dscene->objects);
682         dscene->objects.clear();
683
684         device->tex_free(dscene->objects_vector);
685         dscene->objects_vector.clear();
686
687         device->tex_free(dscene->object_flag);
688         dscene->object_flag.clear();
689 }
690
691 void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, uint *object_flag, Progress& progress)
692 {
693         /* todo: normals and displacement should be done before applying transform! */
694         /* todo: create objects/meshes in right order! */
695
696         /* counter mesh users */
697         map<Mesh*, int> mesh_users;
698 #ifdef __OBJECT_MOTION__
699         Scene::MotionType need_motion = scene->need_motion();
700         bool motion_blur = need_motion == Scene::MOTION_BLUR;
701         bool apply_to_motion = need_motion != Scene::MOTION_PASS;
702 #else
703         bool motion_blur = false;
704         bool apply_to_motion = false;
705 #endif
706         int i = 0;
707         bool have_instancing = false;
708
709         foreach(Object *object, scene->objects) {
710                 map<Mesh*, int>::iterator it = mesh_users.find(object->mesh);
711
712                 if(it == mesh_users.end())
713                         mesh_users[object->mesh] = 1;
714                 else
715                         it->second++;
716         }
717
718         if(progress.get_cancel()) return;
719
720         /* apply transforms for objects with single user meshes */
721         foreach(Object *object, scene->objects) {
722                 /* Annoying feedback loop here: we can't use is_instanced() because
723                  * it'll use uninitialized transform_applied flag.
724                  *
725                  * Could be solved by moving reference counter to Mesh.
726                  */
727                 if((mesh_users[object->mesh] == 1 && !object->mesh->has_surface_bssrdf) &&
728                    !object->mesh->has_true_displacement() && object->mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
729                 {
730                         if(!(motion_blur && object->use_motion)) {
731                                 if(!object->mesh->transform_applied) {
732                                         object->apply_transform(apply_to_motion);
733                                         object->mesh->transform_applied = true;
734
735                                         if(progress.get_cancel()) return;
736                                 }
737
738                                 object_flag[i] |= SD_OBJECT_TRANSFORM_APPLIED;
739                                 if(object->mesh->transform_negative_scaled)
740                                         object_flag[i] |= SD_OBJECT_NEGATIVE_SCALE_APPLIED;
741                         }
742                         else
743                                 have_instancing = true;
744                 }
745                 else
746                         have_instancing = true;
747
748                 i++;
749         }
750
751         dscene->data.bvh.have_instancing = have_instancing;
752 }
753
754 void ObjectManager::tag_update(Scene *scene)
755 {
756         need_update = true;
757         scene->curve_system_manager->need_update = true;
758         scene->mesh_manager->need_update = true;
759         scene->light_manager->need_update = true;
760 }
761
762 CCL_NAMESPACE_END
763