Fix for DeviceScene::attributes_uchar4 not released properly
[blender-staging.git] / intern / cycles / render / mesh.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 "bvh.h"
18 #include "bvh_build.h"
19
20 #include "camera.h"
21 #include "curves.h"
22 #include "device.h"
23 #include "shader.h"
24 #include "light.h"
25 #include "mesh.h"
26 #include "object.h"
27 #include "scene.h"
28
29 #include "osl_globals.h"
30
31 #include "util_cache.h"
32 #include "util_foreach.h"
33 #include "util_progress.h"
34 #include "util_set.h"
35
36 CCL_NAMESPACE_BEGIN
37
38 /* Triangle */
39
40 void Mesh::Triangle::bounds_grow(const float3 *verts, BoundBox& bounds) const
41 {
42         bounds.grow(verts[v[0]]);
43         bounds.grow(verts[v[1]]);
44         bounds.grow(verts[v[2]]);
45 }
46
47 /* Curve */
48
49 void Mesh::Curve::bounds_grow(const int k, const float4 *curve_keys, BoundBox& bounds) const
50 {
51         float3 P[4];
52
53         P[0] = float4_to_float3(curve_keys[max(first_key + k - 1,first_key)]);
54         P[1] = float4_to_float3(curve_keys[first_key + k]);
55         P[2] = float4_to_float3(curve_keys[first_key + k + 1]);
56         P[3] = float4_to_float3(curve_keys[min(first_key + k + 2, first_key + num_keys - 1)]);
57
58         float3 lower;
59         float3 upper;
60
61         curvebounds(&lower.x, &upper.x, P, 0);
62         curvebounds(&lower.y, &upper.y, P, 1);
63         curvebounds(&lower.z, &upper.z, P, 2);
64
65         float mr = max(curve_keys[first_key + k].w, curve_keys[first_key + k + 1].w);
66
67         bounds.grow(lower, mr);
68         bounds.grow(upper, mr);
69 }
70
71 /* Mesh */
72
73 Mesh::Mesh()
74 {
75         need_update = true;
76         need_update_rebuild = false;
77         transform_applied = false;
78         transform_negative_scaled = false;
79         transform_normal = transform_identity();
80         displacement_method = DISPLACE_BUMP;
81         bounds = BoundBox::empty;
82
83         motion_steps = 3;
84         use_motion_blur = false;
85
86         bvh = NULL;
87
88         tri_offset = 0;
89         vert_offset = 0;
90
91         curve_offset = 0;
92         curvekey_offset = 0;
93
94         attributes.triangle_mesh = this;
95         curve_attributes.curve_mesh = this;
96 }
97
98 Mesh::~Mesh()
99 {
100         delete bvh;
101 }
102
103 void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys)
104 {
105         /* reserve space to add verts and triangles later */
106         verts.resize(numverts);
107         triangles.resize(numtris);
108         shader.resize(numtris);
109         smooth.resize(numtris);
110         curve_keys.resize(numcurvekeys);
111         curves.resize(numcurves);
112
113         attributes.reserve();
114         curve_attributes.reserve();
115 }
116
117 void Mesh::clear()
118 {
119         /* clear all verts and triangles */
120         verts.clear();
121         triangles.clear();
122         shader.clear();
123         smooth.clear();
124
125         curve_keys.clear();
126         curves.clear();
127
128         attributes.clear();
129         curve_attributes.clear();
130         used_shaders.clear();
131
132         transform_applied = false;
133         transform_negative_scaled = false;
134         transform_normal = transform_identity();
135 }
136
137 int Mesh::split_vertex(int vertex)
138 {
139         /* copy vertex location and vertex attributes */
140         verts.push_back(verts[vertex]);
141
142         foreach(Attribute& attr, attributes.attributes) {
143                 if(attr.element == ATTR_ELEMENT_VERTEX) {
144                         vector<char> tmp(attr.data_sizeof());
145                         memcpy(&tmp[0], attr.data() + tmp.size()*vertex, tmp.size());
146                         attr.add(&tmp[0]);
147                 }
148         }
149
150         return verts.size() - 1;
151 }
152
153 void Mesh::set_triangle(int i, int v0, int v1, int v2, int shader_, bool smooth_)
154 {
155         Triangle tri;
156         tri.v[0] = v0;
157         tri.v[1] = v1;
158         tri.v[2] = v2;
159
160         triangles[i] = tri;
161         shader[i] = shader_;
162         smooth[i] = smooth_;
163 }
164
165 void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
166 {
167         Triangle tri;
168         tri.v[0] = v0;
169         tri.v[1] = v1;
170         tri.v[2] = v2;
171
172         triangles.push_back(tri);
173         shader.push_back(shader_);
174         smooth.push_back(smooth_);
175 }
176
177 void Mesh::add_curve_key(float3 co, float radius)
178 {
179         float4 key = float3_to_float4(co);
180         key.w = radius;
181
182         curve_keys.push_back(key);
183 }
184
185 void Mesh::add_curve(int first_key, int num_keys, int shader)
186 {
187         Curve curve;
188         curve.first_key = first_key;
189         curve.num_keys = num_keys;
190         curve.shader = shader;
191
192         curves.push_back(curve);
193 }
194
195 void Mesh::compute_bounds()
196 {
197         BoundBox bnds = BoundBox::empty;
198         size_t verts_size = verts.size();
199         size_t curve_keys_size = curve_keys.size();
200
201         if(verts_size + curve_keys_size > 0) {
202                 for(size_t i = 0; i < verts_size; i++)
203                         bnds.grow(verts[i]);
204
205                 for(size_t i = 0; i < curve_keys_size; i++)
206                         bnds.grow(float4_to_float3(curve_keys[i]), curve_keys[i].w);
207
208                 Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
209                 if (use_motion_blur && attr) {
210                         size_t steps_size = verts.size() * (motion_steps - 1);
211                         float3 *vert_steps = attr->data_float3();
212         
213                         for (size_t i = 0; i < steps_size; i++)
214                                 bnds.grow(vert_steps[i]);
215                 }
216
217                 Attribute *curve_attr = curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
218                 if(use_motion_blur && curve_attr) {
219                         size_t steps_size = curve_keys.size() * (motion_steps - 1);
220                         float3 *key_steps = curve_attr->data_float3();
221         
222                         for (size_t i = 0; i < steps_size; i++)
223                                 bnds.grow(key_steps[i]);
224                 }
225
226                 if(!bnds.valid()) {
227                         bnds = BoundBox::empty;
228
229                         /* skip nan or inf coordinates */
230                         for(size_t i = 0; i < verts_size; i++)
231                                 bnds.grow_safe(verts[i]);
232
233                         for(size_t i = 0; i < curve_keys_size; i++)
234                                 bnds.grow_safe(float4_to_float3(curve_keys[i]), curve_keys[i].w);
235                         
236                         if (use_motion_blur && attr) {
237                                 size_t steps_size = verts.size() * (motion_steps - 1);
238                                 float3 *vert_steps = attr->data_float3();
239                 
240                                 for (size_t i = 0; i < steps_size; i++)
241                                         bnds.grow_safe(vert_steps[i]);
242                         }
243
244                         if (use_motion_blur && curve_attr) {
245                                 size_t steps_size = curve_keys.size() * (motion_steps - 1);
246                                 float3 *key_steps = curve_attr->data_float3();
247                 
248                                 for (size_t i = 0; i < steps_size; i++)
249                                         bnds.grow_safe(key_steps[i]);
250                         }
251                 }
252         }
253
254         if(!bnds.valid()) {
255                 /* empty mesh */
256                 bnds.grow(make_float3(0.0f, 0.0f, 0.0f));
257         }
258
259         bounds = bnds;
260 }
261
262 static float3 compute_face_normal(const Mesh::Triangle& t, float3 *verts)
263 {
264         float3 v0 = verts[t.v[0]];
265         float3 v1 = verts[t.v[1]];
266         float3 v2 = verts[t.v[2]];
267
268         float3 norm = cross(v1 - v0, v2 - v0);
269         float normlen = len(norm);
270
271         if(normlen == 0.0f)
272                 return make_float3(0.0f, 0.0f, 0.0f);
273
274         return norm / normlen;
275 }
276
277 void Mesh::add_face_normals()
278 {
279         /* don't compute if already there */
280         if(attributes.find(ATTR_STD_FACE_NORMAL))
281                 return;
282         
283         /* get attributes */
284         Attribute *attr_fN = attributes.add(ATTR_STD_FACE_NORMAL);
285         float3 *fN = attr_fN->data_float3();
286
287         /* compute face normals */
288         size_t triangles_size = triangles.size();
289         bool flip = transform_negative_scaled;
290
291         if(triangles_size) {
292                 float3 *verts_ptr = &verts[0];
293                 Triangle *triangles_ptr = &triangles[0];
294
295                 for(size_t i = 0; i < triangles_size; i++) {
296                         fN[i] = compute_face_normal(triangles_ptr[i], verts_ptr);
297
298                         if(flip)
299                                 fN[i] = -fN[i];
300                 }
301         }
302
303         /* expected to be in local space */
304         if(transform_applied) {
305                 Transform ntfm = transform_inverse(transform_normal);
306
307                 for(size_t i = 0; i < triangles_size; i++)
308                         fN[i] = normalize(transform_direction(&ntfm, fN[i]));
309         }
310 }
311
312 void Mesh::add_vertex_normals()
313 {
314         bool flip = transform_negative_scaled;
315         size_t verts_size = verts.size();
316         size_t triangles_size = triangles.size();
317
318         /* static vertex normals */
319         if(!attributes.find(ATTR_STD_VERTEX_NORMAL)) {
320                 /* get attributes */
321                 Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
322                 Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
323
324                 float3 *fN = attr_fN->data_float3();
325                 float3 *vN = attr_vN->data_float3();
326
327                 /* compute vertex normals */
328                 memset(vN, 0, verts.size()*sizeof(float3));
329
330                 if(triangles_size) {
331                         Triangle *triangles_ptr = &triangles[0];
332
333                         for(size_t i = 0; i < triangles_size; i++)
334                                 for(size_t j = 0; j < 3; j++)
335                                         vN[triangles_ptr[i].v[j]] += fN[i];
336                 }
337
338                 for(size_t i = 0; i < verts_size; i++) {
339                         vN[i] = normalize(vN[i]);
340                         if(flip)
341                                 vN[i] = -vN[i];
342                 }
343         }
344
345         /* motion vertex normals */
346         Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
347         Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
348
349         if(has_motion_blur() && attr_mP && !attr_mN) {
350                 /* create attribute */
351                 attr_mN = attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
352
353                 for(int step = 0; step < motion_steps - 1; step++) {
354                         float3 *mP = attr_mP->data_float3() + step*verts.size();
355                         float3 *mN = attr_mN->data_float3() + step*verts.size();
356
357                         /* compute */
358                         memset(mN, 0, verts.size()*sizeof(float3));
359
360                         if(triangles_size) {
361                                 Triangle *triangles_ptr = &triangles[0];
362
363                                 for(size_t i = 0; i < triangles_size; i++) {
364                                         for(size_t j = 0; j < 3; j++) {
365                                                 float3 fN = compute_face_normal(triangles_ptr[i], mP);
366                                                 mN[triangles_ptr[i].v[j]] += fN;
367                                         }
368                                 }
369                         }
370
371                         for(size_t i = 0; i < verts_size; i++) {
372                                 mN[i] = normalize(mN[i]);
373                                 if(flip)
374                                         mN[i] = -mN[i];
375                         }
376                 }
377         }
378 }
379
380 void Mesh::pack_normals(Scene *scene, float *tri_shader, float4 *vnormal)
381 {
382         Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
383
384         float3 *vN = attr_vN->data_float3();
385         int shader_id = 0;
386         uint last_shader = -1;
387         bool last_smooth = false;
388
389         size_t triangles_size = triangles.size();
390         uint *shader_ptr = (shader.size())? &shader[0]: NULL;
391
392         bool do_transform = transform_applied;
393         Transform ntfm = transform_normal;
394
395         /* save shader */
396         for(size_t i = 0; i < triangles_size; i++) {
397                 if(shader_ptr[i] != last_shader || last_smooth != smooth[i]) {
398                         last_shader = shader_ptr[i];
399                         last_smooth = smooth[i];
400                         shader_id = scene->shader_manager->get_shader_id(last_shader, this, last_smooth);
401                 }
402
403                 tri_shader[i] = __int_as_float(shader_id);
404         }
405
406         size_t verts_size = verts.size();
407
408         for(size_t i = 0; i < verts_size; i++) {
409                 float3 vNi = vN[i];
410
411                 if(do_transform)
412                         vNi = normalize(transform_direction(&ntfm, vNi));
413
414                 vnormal[i] = make_float4(vNi.x, vNi.y, vNi.z, 0.0f);
415         }
416 }
417
418 void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset)
419 {
420         size_t verts_size = verts.size();
421
422         if(verts_size) {
423                 float3 *verts_ptr = &verts[0];
424
425                 for(size_t i = 0; i < verts_size; i++) {
426                         float3 p = verts_ptr[i];
427                         tri_verts[i] = make_float4(p.x, p.y, p.z, 0.0f);
428                 }
429         }
430
431         size_t triangles_size = triangles.size();
432
433         if(triangles_size) {
434                 Triangle *triangles_ptr = &triangles[0];
435
436                 for(size_t i = 0; i < triangles_size; i++) {
437                         Triangle t = triangles_ptr[i];
438
439                         tri_vindex[i] = make_float4(
440                                 __int_as_float(t.v[0] + vert_offset),
441                                 __int_as_float(t.v[1] + vert_offset),
442                                 __int_as_float(t.v[2] + vert_offset),
443                                 0);
444                 }
445         }
446 }
447
448 void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset)
449 {
450         size_t curve_keys_size = curve_keys.size();
451         float4 *keys_ptr = NULL;
452
453         /* pack curve keys */
454         if(curve_keys_size) {
455                 keys_ptr = &curve_keys[0];
456
457                 for(size_t i = 0; i < curve_keys_size; i++)
458                         curve_key_co[i] = keys_ptr[i];
459         }
460
461         /* pack curve segments */
462         size_t curve_num = curves.size();
463
464         if(curve_num) {
465                 Curve *curve_ptr = &curves[0];
466                 int shader_id = 0;
467                 
468                 for(size_t i = 0; i < curve_num; i++) {
469                         Curve curve = curve_ptr[i];
470                         shader_id = scene->shader_manager->get_shader_id(curve.shader, this, false);
471
472                         curve_data[i] = make_float4(
473                                 __int_as_float(curve.first_key + curvekey_offset),
474                                 __int_as_float(curve.num_keys),
475                                 __int_as_float(shader_id),
476                                 0.0f);
477                 }
478         }
479 }
480
481 void Mesh::compute_bvh(SceneParams *params, Progress *progress, int n, int total)
482 {
483         if(progress->get_cancel())
484                 return;
485
486         compute_bounds();
487
488         if(!transform_applied) {
489                 string msg = "Updating Mesh BVH ";
490                 if(name == "")
491                         msg += string_printf("%u/%u", (uint)(n+1), (uint)total);
492                 else
493                         msg += string_printf("%s %u/%u", name.c_str(), (uint)(n+1), (uint)total);
494
495                 Object object;
496                 object.mesh = this;
497
498                 vector<Object*> objects;
499                 objects.push_back(&object);
500
501                 if(bvh && !need_update_rebuild) {
502                         progress->set_status(msg, "Refitting BVH");
503                         bvh->objects = objects;
504                         bvh->refit(*progress);
505                 }
506                 else {
507                         progress->set_status(msg, "Building BVH");
508
509                         BVHParams bparams;
510                         bparams.use_cache = params->use_bvh_cache;
511                         bparams.use_spatial_split = params->use_bvh_spatial_split;
512                         bparams.use_qbvh = params->use_qbvh;
513
514                         delete bvh;
515                         bvh = BVH::create(bparams, objects);
516                         bvh->build(*progress);
517                 }
518         }
519
520         need_update = false;
521         need_update_rebuild = false;
522 }
523
524 void Mesh::tag_update(Scene *scene, bool rebuild)
525 {
526         need_update = true;
527
528         if(rebuild) {
529                 need_update_rebuild = true;
530                 scene->light_manager->need_update = true;
531         }
532         else {
533                 foreach(uint sindex, used_shaders)
534                         if(scene->shaders[sindex]->has_surface_emission)
535                                 scene->light_manager->need_update = true;
536         }
537
538         scene->mesh_manager->need_update = true;
539         scene->object_manager->need_update = true;
540 }
541
542 bool Mesh::has_motion_blur() const
543 {
544         return (use_motion_blur &&
545                 (attributes.find(ATTR_STD_MOTION_VERTEX_POSITION) ||
546                  curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)));
547 }
548
549 /* Mesh Manager */
550
551 MeshManager::MeshManager()
552 {
553         bvh = NULL;
554         need_update = true;
555 }
556
557 MeshManager::~MeshManager()
558 {
559         delete bvh;
560 }
561
562 void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<AttributeRequestSet>& mesh_attributes)
563 {
564 #ifdef WITH_OSL
565         /* for OSL, a hash map is used to lookup the attribute by name. */
566         OSLGlobals *og = (OSLGlobals*)device->osl_memory();
567
568         og->object_name_map.clear();
569         og->attribute_map.clear();
570         og->object_names.clear();
571
572         og->attribute_map.resize(scene->objects.size()*ATTR_PRIM_TYPES);
573
574         for(size_t i = 0; i < scene->objects.size(); i++) {
575                 /* set object name to object index map */
576                 Object *object = scene->objects[i];
577                 og->object_name_map[object->name] = i;
578                 og->object_names.push_back(object->name);
579
580                 /* set object attributes */
581                 foreach(ParamValue& attr, object->attributes) {
582                         OSLGlobals::Attribute osl_attr;
583
584                         osl_attr.type = attr.type();
585                         osl_attr.elem = ATTR_ELEMENT_OBJECT;
586                         osl_attr.value = attr;
587                         osl_attr.offset = 0;
588
589                         og->attribute_map[i*ATTR_PRIM_TYPES][attr.name()] = osl_attr;
590                         og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr;
591                 }
592
593                 /* find mesh attributes */
594                 size_t j;
595
596                 for(j = 0; j < scene->meshes.size(); j++)
597                         if(scene->meshes[j] == object->mesh)
598                                 break;
599
600                 AttributeRequestSet& attributes = mesh_attributes[j];
601
602                 /* set object attributes */
603                 foreach(AttributeRequest& req, attributes.requests) {
604                         OSLGlobals::Attribute osl_attr;
605
606                         if(req.triangle_element != ATTR_ELEMENT_NONE) {
607                                 osl_attr.elem = req.triangle_element;
608                                 osl_attr.offset = req.triangle_offset;
609
610                                 if(req.triangle_type == TypeDesc::TypeFloat)
611                                         osl_attr.type = TypeDesc::TypeFloat;
612                                 else if(req.triangle_type == TypeDesc::TypeMatrix)
613                                         osl_attr.type = TypeDesc::TypeMatrix;
614                                 else
615                                         osl_attr.type = TypeDesc::TypeColor;
616
617                                 if(req.std != ATTR_STD_NONE) {
618                                         /* if standard attribute, add lookup by geom: name convention */
619                                         ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
620                                         og->attribute_map[i*ATTR_PRIM_TYPES][stdname] = osl_attr;
621                                 }
622                                 else if(req.name != ustring()) {
623                                         /* add lookup by mesh attribute name */
624                                         og->attribute_map[i*ATTR_PRIM_TYPES][req.name] = osl_attr;
625                                 }
626                         }
627
628                         if(req.curve_element != ATTR_ELEMENT_NONE) {
629                                 osl_attr.elem = req.curve_element;
630                                 osl_attr.offset = req.curve_offset;
631
632                                 if(req.curve_type == TypeDesc::TypeFloat)
633                                         osl_attr.type = TypeDesc::TypeFloat;
634                                 else if(req.curve_type == TypeDesc::TypeMatrix)
635                                         osl_attr.type = TypeDesc::TypeMatrix;
636                                 else
637                                         osl_attr.type = TypeDesc::TypeColor;
638
639                                 if(req.std != ATTR_STD_NONE) {
640                                         /* if standard attribute, add lookup by geom: name convention */
641                                         ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
642                                         og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][stdname] = osl_attr;
643                                 }
644                                 else if(req.name != ustring()) {
645                                         /* add lookup by mesh attribute name */
646                                         og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][req.name] = osl_attr;
647                                 }
648                         }
649                 }
650         }
651 #endif
652 }
653
654 void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Scene *scene, vector<AttributeRequestSet>& mesh_attributes)
655 {
656         /* for SVM, the attributes_map table is used to lookup the offset of an
657          * attribute, based on a unique shader attribute id. */
658
659         /* compute array stride */
660         int attr_map_stride = 0;
661
662         for(size_t i = 0; i < scene->meshes.size(); i++)
663                 attr_map_stride = max(attr_map_stride, (mesh_attributes[i].size() + 1)*ATTR_PRIM_TYPES);
664
665         if(attr_map_stride == 0)
666                 return;
667         
668         /* create attribute map */
669         uint4 *attr_map = dscene->attributes_map.resize(attr_map_stride*scene->objects.size());
670         memset(attr_map, 0, dscene->attributes_map.size()*sizeof(uint));
671
672         for(size_t i = 0; i < scene->objects.size(); i++) {
673                 Object *object = scene->objects[i];
674                 Mesh *mesh = object->mesh;
675
676                 /* find mesh attributes */
677                 size_t j;
678
679                 for(j = 0; j < scene->meshes.size(); j++)
680                         if(scene->meshes[j] == mesh)
681                                 break;
682
683                 AttributeRequestSet& attributes = mesh_attributes[j];
684
685                 /* set object attributes */
686                 int index = i*attr_map_stride;
687
688                 foreach(AttributeRequest& req, attributes.requests) {
689                         uint id;
690
691                         if(req.std == ATTR_STD_NONE)
692                                 id = scene->shader_manager->get_attribute_id(req.name);
693                         else
694                                 id = scene->shader_manager->get_attribute_id(req.std);
695
696                         if(mesh->triangles.size()) {
697                                 attr_map[index].x = id;
698                                 attr_map[index].y = req.triangle_element;
699                                 attr_map[index].z = as_uint(req.triangle_offset);
700
701                                 if(req.triangle_type == TypeDesc::TypeFloat)
702                                         attr_map[index].w = NODE_ATTR_FLOAT;
703                                 else if(req.triangle_type == TypeDesc::TypeMatrix)
704                                         attr_map[index].w = NODE_ATTR_MATRIX;
705                                 else
706                                         attr_map[index].w = NODE_ATTR_FLOAT3;
707                         }
708
709                         index++;
710
711                         if(mesh->curves.size()) {
712                                 attr_map[index].x = id;
713                                 attr_map[index].y = req.curve_element;
714                                 attr_map[index].z = as_uint(req.curve_offset);
715
716                                 if(req.curve_type == TypeDesc::TypeFloat)
717                                         attr_map[index].w = NODE_ATTR_FLOAT;
718                                 else if(req.curve_type == TypeDesc::TypeMatrix)
719                                         attr_map[index].w = NODE_ATTR_MATRIX;
720                                 else
721                                         attr_map[index].w = NODE_ATTR_FLOAT3;
722                         }
723
724                         index++;
725                 }
726
727                 /* terminator */
728                 attr_map[index].x = ATTR_STD_NONE;
729                 attr_map[index].y = 0;
730                 attr_map[index].z = 0;
731                 attr_map[index].w = 0;
732
733                 index++;
734
735                 attr_map[index].x = ATTR_STD_NONE;
736                 attr_map[index].y = 0;
737                 attr_map[index].z = 0;
738                 attr_map[index].w = 0;
739
740                 index++;
741         }
742
743         /* copy to device */
744         dscene->data.bvh.attributes_map_stride = attr_map_stride;
745         device->tex_alloc("__attributes_map", dscene->attributes_map);
746 }
747
748 static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_float, vector<float4>& attr_float3, vector<uchar4>& attr_uchar4,
749         Attribute *mattr, TypeDesc& type, int& offset, AttributeElement& element)
750 {
751         if(mattr) {
752                 /* store element and type */
753                 element = mattr->element;
754                 type = mattr->type;
755
756                 /* store attribute data in arrays */
757                 size_t size = mattr->element_size(
758                         mesh->verts.size(),
759                         mesh->triangles.size(),
760                         mesh->motion_steps,
761                         mesh->curves.size(),
762                         mesh->curve_keys.size());
763
764                 if(mattr->element == ATTR_ELEMENT_VOXEL) {
765                         /* store slot in offset value */
766                         VoxelAttribute *voxel_data = mattr->data_voxel();
767                         offset = voxel_data->slot;
768                 }
769                 if(mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
770                         uchar4 *data = mattr->data_uchar4();
771                         offset = attr_uchar4.size();
772
773                         attr_uchar4.resize(attr_uchar4.size() + size);
774
775                         for(size_t k = 0; k < size; k++)
776                                 attr_uchar4[offset+k] = data[k];
777                 }
778                 else if(mattr->type == TypeDesc::TypeFloat) {
779                         float *data = mattr->data_float();
780                         offset = attr_float.size();
781
782                         attr_float.resize(attr_float.size() + size);
783
784                         for(size_t k = 0; k < size; k++)
785                                 attr_float[offset+k] = data[k];
786                 }
787                 else if(mattr->type == TypeDesc::TypeMatrix) {
788                         Transform *tfm = mattr->data_transform();
789                         offset = attr_float3.size();
790
791                         attr_float3.resize(attr_float3.size() + size*4);
792
793                         for(size_t k = 0; k < size*4; k++)
794                                 attr_float3[offset+k] = (&tfm->x)[k];
795                 }
796                 else {
797                         float4 *data = mattr->data_float4();
798                         offset = attr_float3.size();
799
800                         attr_float3.resize(attr_float3.size() + size);
801
802                         for(size_t k = 0; k < size; k++)
803                                 attr_float3[offset+k] = data[k];
804                 }
805
806                 /* mesh vertex/curve index is global, not per object, so we sneak
807                  * a correction for that in here */
808                 if(element == ATTR_ELEMENT_VERTEX)
809                         offset -= mesh->vert_offset;
810                 else if(element == ATTR_ELEMENT_VERTEX_MOTION)
811                         offset -= mesh->vert_offset;
812                 else if(element == ATTR_ELEMENT_FACE)
813                         offset -= mesh->tri_offset;
814                 else if(element == ATTR_ELEMENT_CORNER || element == ATTR_ELEMENT_CORNER_BYTE)
815                         offset -= 3*mesh->tri_offset;
816                 else if(element == ATTR_ELEMENT_CURVE)
817                         offset -= mesh->curve_offset;
818                 else if(element == ATTR_ELEMENT_CURVE_KEY)
819                         offset -= mesh->curvekey_offset;
820                 else if(element == ATTR_ELEMENT_CURVE_KEY_MOTION)
821                         offset -= mesh->curvekey_offset;
822         }
823         else {
824                 /* attribute not found */
825                 element = ATTR_ELEMENT_NONE;
826                 offset = 0;
827         }
828 }
829
830 void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
831 {
832         progress.set_status("Updating Mesh", "Computing attributes");
833
834         /* gather per mesh requested attributes. as meshes may have multiple
835          * shaders assigned, this merges the requested attributes that have
836          * been set per shader by the shader manager */
837         vector<AttributeRequestSet> mesh_attributes(scene->meshes.size());
838
839         for(size_t i = 0; i < scene->meshes.size(); i++) {
840                 Mesh *mesh = scene->meshes[i];
841
842                 scene->need_global_attributes(mesh_attributes[i]);
843
844                 foreach(uint sindex, mesh->used_shaders) {
845                         Shader *shader = scene->shaders[sindex];
846                         mesh_attributes[i].add(shader->attributes);
847                 }
848         }
849
850         /* mesh attribute are stored in a single array per data type. here we fill
851          * those arrays, and set the offset and element type to create attribute
852          * maps next */
853         vector<float> attr_float;
854         vector<float4> attr_float3;
855         vector<uchar4> attr_uchar4;
856
857         for(size_t i = 0; i < scene->meshes.size(); i++) {
858                 Mesh *mesh = scene->meshes[i];
859                 AttributeRequestSet& attributes = mesh_attributes[i];
860
861                 /* todo: we now store std and name attributes from requests even if
862                  * they actually refer to the same mesh attributes, optimize */
863                 foreach(AttributeRequest& req, attributes.requests) {
864                         Attribute *triangle_mattr = mesh->attributes.find(req);
865                         Attribute *curve_mattr = mesh->curve_attributes.find(req);
866
867                         /* todo: get rid of this exception, it's only here for giving some
868                          * working texture coordinate for subdivision as we can't preserve
869                          * any attributes yet */
870                         if(!triangle_mattr && req.std == ATTR_STD_GENERATED) {
871                                 triangle_mattr = mesh->attributes.add(ATTR_STD_GENERATED);
872                                 if(mesh->verts.size())
873                                         memcpy(triangle_mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size());
874                         }
875
876                         update_attribute_element_offset(mesh, attr_float, attr_float3, attr_uchar4, triangle_mattr,
877                                 req.triangle_type, req.triangle_offset, req.triangle_element);
878
879                         update_attribute_element_offset(mesh, attr_float, attr_float3, attr_uchar4, curve_mattr,
880                                 req.curve_type, req.curve_offset, req.curve_element);
881         
882                         if(progress.get_cancel()) return;
883                 }
884         }
885
886         /* create attribute lookup maps */
887         if(scene->shader_manager->use_osl())
888                 update_osl_attributes(device, scene, mesh_attributes);
889
890         update_svm_attributes(device, dscene, scene, mesh_attributes);
891
892         if(progress.get_cancel()) return;
893
894         /* copy to device */
895         progress.set_status("Updating Mesh", "Copying Attributes to device");
896
897         if(attr_float.size()) {
898                 dscene->attributes_float.copy(&attr_float[0], attr_float.size());
899                 device->tex_alloc("__attributes_float", dscene->attributes_float);
900         }
901         if(attr_float3.size()) {
902                 dscene->attributes_float3.copy(&attr_float3[0], attr_float3.size());
903                 device->tex_alloc("__attributes_float3", dscene->attributes_float3);
904         }
905         if(attr_uchar4.size()) {
906                 dscene->attributes_uchar4.copy(&attr_uchar4[0], attr_uchar4.size());
907                 device->tex_alloc("__attributes_uchar4", dscene->attributes_uchar4);
908         }
909 }
910
911 void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
912 {
913         /* count and update offsets */
914         size_t vert_size = 0;
915         size_t tri_size = 0;
916
917         size_t curve_key_size = 0;
918         size_t curve_size = 0;
919
920         foreach(Mesh *mesh, scene->meshes) {
921                 mesh->vert_offset = vert_size;
922                 mesh->tri_offset = tri_size;
923
924                 mesh->curvekey_offset = curve_key_size;
925                 mesh->curve_offset = curve_size;
926
927                 vert_size += mesh->verts.size();
928                 tri_size += mesh->triangles.size();
929
930                 curve_key_size += mesh->curve_keys.size();
931                 curve_size += mesh->curves.size();
932         }
933
934         if(tri_size != 0) {
935                 /* normals */
936                 progress.set_status("Updating Mesh", "Computing normals");
937
938                 float *tri_shader = dscene->tri_shader.resize(tri_size);
939                 float4 *vnormal = dscene->tri_vnormal.resize(vert_size);
940                 float4 *tri_verts = dscene->tri_verts.resize(vert_size);
941                 float4 *tri_vindex = dscene->tri_vindex.resize(tri_size);
942
943                 foreach(Mesh *mesh, scene->meshes) {
944                         mesh->pack_normals(scene, &tri_shader[mesh->tri_offset], &vnormal[mesh->vert_offset]);
945                         mesh->pack_verts(&tri_verts[mesh->vert_offset], &tri_vindex[mesh->tri_offset], mesh->vert_offset);
946
947                         if(progress.get_cancel()) return;
948                 }
949
950                 /* vertex coordinates */
951                 progress.set_status("Updating Mesh", "Copying Mesh to device");
952
953                 device->tex_alloc("__tri_shader", dscene->tri_shader);
954                 device->tex_alloc("__tri_vnormal", dscene->tri_vnormal);
955                 device->tex_alloc("__tri_verts", dscene->tri_verts);
956                 device->tex_alloc("__tri_vindex", dscene->tri_vindex);
957         }
958
959         if(curve_size != 0) {
960                 progress.set_status("Updating Mesh", "Copying Strands to device");
961
962                 float4 *curve_keys = dscene->curve_keys.resize(curve_key_size);
963                 float4 *curves = dscene->curves.resize(curve_size);
964
965                 foreach(Mesh *mesh, scene->meshes) {
966                         mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curves[mesh->curve_offset], mesh->curvekey_offset);
967                         if(progress.get_cancel()) return;
968                 }
969
970                 device->tex_alloc("__curve_keys", dscene->curve_keys);
971                 device->tex_alloc("__curves", dscene->curves);
972         }
973 }
974
975 void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
976 {
977         /* bvh build */
978         progress.set_status("Updating Scene BVH", "Building");
979
980         BVHParams bparams;
981         bparams.top_level = true;
982         bparams.use_qbvh = scene->params.use_qbvh;
983         bparams.use_spatial_split = scene->params.use_bvh_spatial_split;
984         bparams.use_cache = scene->params.use_bvh_cache;
985
986         delete bvh;
987         bvh = BVH::create(bparams, scene->objects);
988         bvh->build(progress);
989
990         if(progress.get_cancel()) return;
991
992         /* copy to device */
993         progress.set_status("Updating Scene BVH", "Copying BVH to device");
994
995         PackedBVH& pack = bvh->pack;
996
997         if(pack.nodes.size()) {
998                 dscene->bvh_nodes.reference((float4*)&pack.nodes[0], pack.nodes.size());
999                 device->tex_alloc("__bvh_nodes", dscene->bvh_nodes);
1000         }
1001         if(pack.object_node.size()) {
1002                 dscene->object_node.reference((uint*)&pack.object_node[0], pack.object_node.size());
1003                 device->tex_alloc("__object_node", dscene->object_node);
1004         }
1005         if(pack.tri_woop.size()) {
1006                 dscene->tri_woop.reference(&pack.tri_woop[0], pack.tri_woop.size());
1007                 device->tex_alloc("__tri_woop", dscene->tri_woop);
1008         }
1009         if(pack.prim_type.size()) {
1010                 dscene->prim_type.reference((uint*)&pack.prim_type[0], pack.prim_type.size());
1011                 device->tex_alloc("__prim_type", dscene->prim_type);
1012         }
1013         if(pack.prim_visibility.size()) {
1014                 dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size());
1015                 device->tex_alloc("__prim_visibility", dscene->prim_visibility);
1016         }
1017         if(pack.prim_index.size()) {
1018                 dscene->prim_index.reference((uint*)&pack.prim_index[0], pack.prim_index.size());
1019                 device->tex_alloc("__prim_index", dscene->prim_index);
1020         }
1021         if(pack.prim_object.size()) {
1022                 dscene->prim_object.reference((uint*)&pack.prim_object[0], pack.prim_object.size());
1023                 device->tex_alloc("__prim_object", dscene->prim_object);
1024         }
1025
1026         dscene->data.bvh.root = pack.root_index;
1027 }
1028
1029 void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
1030 {
1031         if(!need_update)
1032                 return;
1033
1034         /* update normals */
1035         foreach(Mesh *mesh, scene->meshes) {
1036                 foreach(uint shader, mesh->used_shaders)
1037                         if(scene->shaders[shader]->need_update_attributes)
1038                                 mesh->need_update = true;
1039
1040                 if(mesh->need_update) {
1041                         mesh->add_face_normals();
1042                         mesh->add_vertex_normals();
1043
1044                         if(progress.get_cancel()) return;
1045                 }
1046         }
1047
1048         /* device update */
1049         device_free(device, dscene);
1050
1051         device_update_mesh(device, dscene, scene, progress);
1052         if(progress.get_cancel()) return;
1053
1054         device_update_attributes(device, dscene, scene, progress);
1055         if(progress.get_cancel()) return;
1056
1057         /* update displacement */
1058         bool displacement_done = false;
1059
1060         foreach(Mesh *mesh, scene->meshes)
1061                 if(mesh->need_update && displace(device, dscene, scene, mesh, progress))
1062                         displacement_done = true;
1063
1064         /* todo: properly handle cancel halfway displacement */
1065         if(progress.get_cancel()) return;
1066
1067         /* device re-update after displacement */
1068         if(displacement_done) {
1069                 device_free(device, dscene);
1070
1071                 device_update_mesh(device, dscene, scene, progress);
1072                 if(progress.get_cancel()) return;
1073
1074                 device_update_attributes(device, dscene, scene, progress);
1075                 if(progress.get_cancel()) return;
1076         }
1077
1078         /* update bvh */
1079         size_t i = 0, num_bvh = 0;
1080
1081         foreach(Mesh *mesh, scene->meshes)
1082                 if(mesh->need_update && !mesh->transform_applied)
1083                         num_bvh++;
1084
1085         TaskPool pool;
1086
1087         foreach(Mesh *mesh, scene->meshes) {
1088                 if(mesh->need_update) {
1089                         pool.push(function_bind(&Mesh::compute_bvh, mesh, &scene->params, &progress, i, num_bvh));
1090                         i++;
1091                 }
1092         }
1093
1094         pool.wait_work();
1095         
1096         foreach(Shader *shader, scene->shaders)
1097                 shader->need_update_attributes = false;
1098
1099 #ifdef __OBJECT_MOTION__
1100         Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
1101         bool motion_blur = need_motion == Scene::MOTION_BLUR;
1102 #else
1103         bool motion_blur = false;
1104 #endif
1105
1106         foreach(Object *object, scene->objects)
1107                 object->compute_bounds(motion_blur);
1108
1109         if(progress.get_cancel()) return;
1110
1111         device_update_bvh(device, dscene, scene, progress);
1112
1113         need_update = false;
1114 }
1115
1116 void MeshManager::device_free(Device *device, DeviceScene *dscene)
1117 {
1118         device->tex_free(dscene->bvh_nodes);
1119         device->tex_free(dscene->object_node);
1120         device->tex_free(dscene->tri_woop);
1121         device->tex_free(dscene->prim_type);
1122         device->tex_free(dscene->prim_visibility);
1123         device->tex_free(dscene->prim_index);
1124         device->tex_free(dscene->prim_object);
1125         device->tex_free(dscene->tri_shader);
1126         device->tex_free(dscene->tri_vnormal);
1127         device->tex_free(dscene->tri_vindex);
1128         device->tex_free(dscene->tri_verts);
1129         device->tex_free(dscene->curves);
1130         device->tex_free(dscene->curve_keys);
1131         device->tex_free(dscene->attributes_map);
1132         device->tex_free(dscene->attributes_float);
1133         device->tex_free(dscene->attributes_float3);
1134         device->tex_free(dscene->attributes_uchar4);
1135
1136         dscene->bvh_nodes.clear();
1137         dscene->object_node.clear();
1138         dscene->tri_woop.clear();
1139         dscene->prim_type.clear();
1140         dscene->prim_visibility.clear();
1141         dscene->prim_index.clear();
1142         dscene->prim_object.clear();
1143         dscene->tri_shader.clear();
1144         dscene->tri_vnormal.clear();
1145         dscene->tri_vindex.clear();
1146         dscene->tri_verts.clear();
1147         dscene->curves.clear();
1148         dscene->curve_keys.clear();
1149         dscene->attributes_map.clear();
1150         dscene->attributes_float.clear();
1151         dscene->attributes_float3.clear();
1152         dscene->attributes_uchar4.clear();
1153
1154 #ifdef WITH_OSL
1155         OSLGlobals *og = (OSLGlobals*)device->osl_memory();
1156
1157         if(og) {
1158                 og->object_name_map.clear();
1159                 og->attribute_map.clear();
1160                 og->object_names.clear();
1161         }
1162 #endif
1163 }
1164
1165 void MeshManager::tag_update(Scene *scene)
1166 {
1167         need_update = true;
1168         scene->object_manager->need_update = true;
1169 }
1170
1171 bool Mesh::need_attribute(Scene *scene, AttributeStandard std)
1172 {
1173         if(std == ATTR_STD_NONE)
1174                 return false;
1175         
1176         if(scene->need_global_attribute(std))
1177                 return true;
1178
1179         foreach(uint shader, used_shaders)
1180                 if(scene->shaders[shader]->attributes.find(std))
1181                         return true;
1182         
1183         return false;
1184 }
1185
1186 bool Mesh::need_attribute(Scene *scene, ustring name)
1187 {
1188         if(name == ustring())
1189                 return false;
1190
1191         foreach(uint shader, used_shaders)
1192                 if(scene->shaders[shader]->attributes.find(name))
1193                         return true;
1194         
1195         return false;
1196 }
1197
1198 CCL_NAMESPACE_END
1199