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