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