Cycles microdisplacement: move subdivision options to subsurf modifier
[blender-staging.git] / intern / cycles / blender / blender_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  
18 #include "mesh.h"
19 #include "object.h"
20 #include "scene.h"
21 #include "camera.h"
22
23 #include "blender_sync.h"
24 #include "blender_session.h"
25 #include "blender_util.h"
26
27 #include "subd_patch.h"
28 #include "subd_split.h"
29
30 #include "util_foreach.h"
31 #include "util_logging.h"
32 #include "util_math.h"
33
34 #include "mikktspace.h"
35
36 CCL_NAMESPACE_BEGIN
37
38 /* Per-face bit flags. */
39 enum {
40         /* Face has no special flags. */
41         FACE_FLAG_NONE      = (0 << 0),
42         /* Quad face was split using 1-3 diagonal. */
43         FACE_FLAG_DIVIDE_13 = (1 << 0),
44         /* Quad face was split using 2-4 diagonal. */
45         FACE_FLAG_DIVIDE_24 = (1 << 1),
46 };
47
48 /* Get vertex indices to create triangles from a given face.
49  *
50  * Two triangles has vertex indices in the original Blender-side face.
51  * If face is already a quad tri_b will not be initialized.
52  */
53 inline void face_split_tri_indices(const int num_verts,
54                                    const int face_flag,
55                                    int tri_a[3],
56                                    int tri_b[3])
57 {
58         if(face_flag & FACE_FLAG_DIVIDE_24) {
59                 tri_a[0] = 0;
60                 tri_a[1] = 1;
61                 tri_a[2] = 3;
62                 if(num_verts == 4) {
63                         tri_b[0] = 2;
64                         tri_b[1] = 3;
65                         tri_b[2] = 1;
66                 }
67         }
68         else /*if(face_flag & FACE_FLAG_DIVIDE_13)*/ {
69                 tri_a[0] = 0;
70                 tri_a[1] = 1;
71                 tri_a[2] = 2;
72                 if(num_verts == 4) {
73                         tri_b[0] = 0;
74                         tri_b[1] = 2;
75                         tri_b[2] = 3;
76                 }
77         }
78 }
79
80 /* Tangent Space */
81
82 struct MikkUserData {
83         MikkUserData(const BL::Mesh& mesh_,
84                      BL::MeshTextureFaceLayer *layer_,
85                      int num_faces_)
86         : mesh(mesh_), layer(layer_), num_faces(num_faces_)
87         {
88                 tangent.resize(num_faces*4);
89         }
90
91         BL::Mesh mesh;
92         BL::MeshTextureFaceLayer *layer;
93         int num_faces;
94         vector<float4> tangent;
95 };
96
97 static int mikk_get_num_faces(const SMikkTSpaceContext *context)
98 {
99         MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
100         return userdata->num_faces;
101 }
102
103 static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num)
104 {
105         MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
106         BL::MeshTessFace f = userdata->mesh.tessfaces[face_num];
107         int4 vi = get_int4(f.vertices_raw());
108
109         return (vi[3] == 0)? 3: 4;
110 }
111
112 static void mikk_get_position(const SMikkTSpaceContext *context, float P[3], const int face_num, const int vert_num)
113 {
114         MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
115         BL::MeshTessFace f = userdata->mesh.tessfaces[face_num];
116         int4 vi = get_int4(f.vertices_raw());
117         BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]];
118         float3 vP = get_float3(v.co());
119
120         P[0] = vP.x;
121         P[1] = vP.y;
122         P[2] = vP.z;
123 }
124
125 static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float uv[2], const int face_num, const int vert_num)
126 {
127         MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
128         if(userdata->layer != NULL) {
129                 BL::MeshTextureFace tf = userdata->layer->data[face_num];
130                 float3 tfuv;
131
132                 switch(vert_num) {
133                         case 0:
134                                 tfuv = get_float3(tf.uv1());
135                                 break;
136                         case 1:
137                                 tfuv = get_float3(tf.uv2());
138                                 break;
139                         case 2:
140                                 tfuv = get_float3(tf.uv3());
141                                 break;
142                         default:
143                                 tfuv = get_float3(tf.uv4());
144                                 break;
145                 }
146
147                 uv[0] = tfuv.x;
148                 uv[1] = tfuv.y;
149         }
150         else {
151                 int vert_idx = userdata->mesh.tessfaces[face_num].vertices()[vert_num];
152                 float3 orco =
153                         get_float3(userdata->mesh.vertices[vert_idx].undeformed_co());
154                 float2 tmp = map_to_sphere(make_float3(orco[0], orco[1], orco[2]));
155                 uv[0] = tmp.x;
156                 uv[1] = tmp.y;
157         }
158 }
159
160 static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3], const int face_num, const int vert_num)
161 {
162         MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
163         BL::MeshTessFace f = userdata->mesh.tessfaces[face_num];
164         float3 vN;
165
166         if(f.use_smooth()) {
167                 int4 vi = get_int4(f.vertices_raw());
168                 BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]];
169                 vN = get_float3(v.normal());
170         }
171         else {
172                 vN = get_float3(f.normal());
173         }
174
175         N[0] = vN.x;
176         N[1] = vN.y;
177         N[2] = vN.z;
178 }
179
180 static void mikk_set_tangent_space(const SMikkTSpaceContext *context, const float T[], const float sign, const int face, const int vert)
181 {
182         MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
183
184         userdata->tangent[face*4 + vert] = make_float4(T[0], T[1], T[2], sign);
185 }
186
187 static void mikk_compute_tangents(BL::Mesh& b_mesh,
188                                   BL::MeshTextureFaceLayer *b_layer,
189                                   Mesh *mesh,
190                                   const vector<int>& nverts,
191                                   const vector<int>& face_flags,
192                                   bool need_sign,
193                                   bool active_render)
194 {
195         /* setup userdata */
196         MikkUserData userdata(b_mesh, b_layer, nverts.size());
197
198         /* setup interface */
199         SMikkTSpaceInterface sm_interface;
200         memset(&sm_interface, 0, sizeof(sm_interface));
201         sm_interface.m_getNumFaces = mikk_get_num_faces;
202         sm_interface.m_getNumVerticesOfFace = mikk_get_num_verts_of_face;
203         sm_interface.m_getPosition = mikk_get_position;
204         sm_interface.m_getTexCoord = mikk_get_texture_coordinate;
205         sm_interface.m_getNormal = mikk_get_normal;
206         sm_interface.m_setTSpaceBasic = mikk_set_tangent_space;
207
208         /* setup context */
209         SMikkTSpaceContext context;
210         memset(&context, 0, sizeof(context));
211         context.m_pUserData = &userdata;
212         context.m_pInterface = &sm_interface;
213
214         /* compute tangents */
215         genTangSpaceDefault(&context);
216
217         /* create tangent attributes */
218         Attribute *attr;
219         ustring name;
220         if(b_layer != NULL)
221                 name = ustring((string(b_layer->name().c_str()) + ".tangent").c_str());
222         else
223                 name = ustring("orco.tangent");
224
225         if(active_render)
226                 attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name);
227         else
228                 attr = mesh->attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
229
230         float3 *tangent = attr->data_float3();
231
232         /* create bitangent sign attribute */
233         float *tangent_sign = NULL;
234
235         if(need_sign) {
236                 Attribute *attr_sign;
237                 ustring name_sign;
238                 if(b_layer != NULL)
239                         name_sign = ustring((string(b_layer->name().c_str()) + ".tangent_sign").c_str());
240                 else
241                         name_sign = ustring("orco.tangent_sign");
242
243                 if(active_render)
244                         attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
245                 else
246                         attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
247
248                 tangent_sign = attr_sign->data_float();
249         }
250
251         for(int i = 0; i < nverts.size(); i++) {
252                 int tri_a[3], tri_b[3];
253                 face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b);
254
255                 tangent[0] = float4_to_float3(userdata.tangent[i*4 + tri_a[0]]);
256                 tangent[1] = float4_to_float3(userdata.tangent[i*4 + tri_a[1]]);
257                 tangent[2] = float4_to_float3(userdata.tangent[i*4 + tri_a[2]]);
258                 tangent += 3;
259
260                 if(tangent_sign) {
261                         tangent_sign[0] = userdata.tangent[i*4 + tri_a[0]].w;
262                         tangent_sign[1] = userdata.tangent[i*4 + tri_a[1]].w;
263                         tangent_sign[2] = userdata.tangent[i*4 + tri_a[2]].w;
264                         tangent_sign += 3;
265                 }
266
267                 if(nverts[i] == 4) {
268                         tangent[0] = float4_to_float3(userdata.tangent[i*4 + tri_b[0]]);
269                         tangent[1] = float4_to_float3(userdata.tangent[i*4 + tri_b[1]]);
270                         tangent[2] = float4_to_float3(userdata.tangent[i*4 + tri_b[2]]);
271                         tangent += 3;
272
273                         if(tangent_sign) {
274                                 tangent_sign[0] = userdata.tangent[i*4 + tri_b[0]].w;
275                                 tangent_sign[1] = userdata.tangent[i*4 + tri_b[1]].w;
276                                 tangent_sign[2] = userdata.tangent[i*4 + tri_b[2]].w;
277                                 tangent_sign += 3;
278                         }
279                 }
280         }
281 }
282
283 /* Create Volume Attribute */
284
285 static void create_mesh_volume_attribute(BL::Object& b_ob,
286                                          Mesh *mesh,
287                                          ImageManager *image_manager,
288                                          AttributeStandard std,
289                                          float frame)
290 {
291         BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
292
293         if(!b_domain)
294                 return;
295         
296         Attribute *attr = mesh->attributes.add(std);
297         VoxelAttribute *volume_data = attr->data_voxel();
298         bool is_float, is_linear;
299         bool animated = false;
300
301         volume_data->manager = image_manager;
302         volume_data->slot = image_manager->add_image(
303                 Attribute::standard_name(std),
304                 b_ob.ptr.data,
305                 animated,
306                 frame,
307                 is_float,
308                 is_linear,
309                 INTERPOLATION_LINEAR,
310                 EXTENSION_CLIP,
311                 true);
312 }
313
314 static void create_mesh_volume_attributes(Scene *scene,
315                                           BL::Object& b_ob,
316                                           Mesh *mesh,
317                                           float frame)
318 {
319         /* for smoke volume rendering */
320         if(mesh->need_attribute(scene, ATTR_STD_VOLUME_DENSITY))
321                 create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_DENSITY, frame);
322         if(mesh->need_attribute(scene, ATTR_STD_VOLUME_COLOR))
323                 create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_COLOR, frame);
324         if(mesh->need_attribute(scene, ATTR_STD_VOLUME_FLAME))
325                 create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_FLAME, frame);
326         if(mesh->need_attribute(scene, ATTR_STD_VOLUME_HEAT))
327                 create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_HEAT, frame);
328         if(mesh->need_attribute(scene, ATTR_STD_VOLUME_VELOCITY))
329                 create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_VELOCITY, frame);
330 }
331
332 /* Create vertex color attributes. */
333 static void attr_create_vertex_color(Scene *scene,
334                                      Mesh *mesh,
335                                      BL::Mesh& b_mesh,
336                                      const vector<int>& nverts,
337                                      const vector<int>& face_flags,
338                                      bool subdivision)
339 {
340         if(subdivision) {
341                 BL::Mesh::vertex_colors_iterator l;
342
343                 for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
344                         if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
345                                 continue;
346
347                         Attribute *attr = mesh->subd_attributes.add(ustring(l->name().c_str()),
348                                                                     TypeDesc::TypeColor,
349                                                                     ATTR_ELEMENT_CORNER_BYTE);
350
351                         BL::Mesh::polygons_iterator p;
352                         uchar4 *cdata = attr->data_uchar4();
353
354                         for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
355                                 int n = p->loop_total();
356                                 for(int i = 0; i < n; i++) {
357                                         float3 color = get_float3(l->data[p->loop_start() + i].color());
358                                         *(cdata++) = color_float_to_byte(color_srgb_to_scene_linear(color));
359                                 }
360                         }
361                 }
362         }
363         else {
364                 BL::Mesh::tessface_vertex_colors_iterator l;
365                 for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) {
366                         if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
367                                 continue;
368
369                         Attribute *attr = mesh->attributes.add(ustring(l->name().c_str()),
370                                                                TypeDesc::TypeColor,
371                                                                ATTR_ELEMENT_CORNER_BYTE);
372
373                         BL::MeshColorLayer::data_iterator c;
374                         uchar4 *cdata = attr->data_uchar4();
375                         size_t i = 0;
376
377                         for(l->data.begin(c); c != l->data.end(); ++c, ++i) {
378                                 int tri_a[3], tri_b[3];
379                                 face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b);
380
381                                 uchar4 colors[4];
382                                 colors[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1())));
383                                 colors[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2())));
384                                 colors[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3())));
385                                 if(nverts[i] == 4) {
386                                         colors[3] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4())));
387                                 }
388
389                                 cdata[0] = colors[tri_a[0]];
390                                 cdata[1] = colors[tri_a[1]];
391                                 cdata[2] = colors[tri_a[2]];
392
393                                 if(nverts[i] == 4) {
394                                         cdata[3] = colors[tri_b[0]];
395                                         cdata[4] = colors[tri_b[1]];
396                                         cdata[5] = colors[tri_b[2]];
397                                         cdata += 6;
398                                 }
399                                 else
400                                         cdata += 3;
401                         }
402                 }
403         }
404 }
405
406 /* Create uv map attributes. */
407 static void attr_create_uv_map(Scene *scene,
408                                Mesh *mesh,
409                                BL::Mesh& b_mesh,
410                                const vector<int>& nverts,
411                                const vector<int>& face_flags,
412                                bool subdivision)
413 {
414         if(subdivision) {
415                 BL::Mesh::uv_layers_iterator l;
416                 int i = 0;
417
418                 for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
419                         bool active_render = b_mesh.uv_textures[i].active_render();
420                         AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
421                         ustring name = ustring(l->name().c_str());
422
423                         /* UV map */
424                         if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
425                                 Attribute *attr;
426
427                                 if(active_render)
428                                         attr = mesh->subd_attributes.add(std, name);
429                                 else
430                                         attr = mesh->subd_attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
431
432                                 BL::Mesh::polygons_iterator p;
433                                 float3 *fdata = attr->data_float3();
434
435                                 for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
436                                         int n = p->loop_total();
437                                         for(int j = 0; j < n; j++) {
438                                                 *(fdata++) = get_float3(l->data[p->loop_start() + j].uv());
439                                         }
440                                 }
441                         }
442                 }
443         }
444         else if(b_mesh.tessface_uv_textures.length() != 0) {
445                 BL::Mesh::tessface_uv_textures_iterator l;
446
447                 for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
448                         bool active_render = l->active_render();
449                         AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
450                         ustring name = ustring(l->name().c_str());
451
452                         /* UV map */
453                         if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
454                                 Attribute *attr;
455
456                                 if(active_render)
457                                         attr = mesh->attributes.add(std, name);
458                                 else
459                                         attr = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
460
461                                 BL::MeshTextureFaceLayer::data_iterator t;
462                                 float3 *fdata = attr->data_float3();
463                                 size_t i = 0;
464
465                                 for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
466                                         int tri_a[3], tri_b[3];
467                                         face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b);
468
469                                         float3 uvs[4];
470                                         uvs[0] = get_float3(t->uv1());
471                                         uvs[1] = get_float3(t->uv2());
472                                         uvs[2] = get_float3(t->uv3());
473                                         if(nverts[i] == 4) {
474                                                 uvs[3] = get_float3(t->uv4());
475                                         }
476
477                                         fdata[0] = uvs[tri_a[0]];
478                                         fdata[1] = uvs[tri_a[1]];
479                                         fdata[2] = uvs[tri_a[2]];
480                                         fdata += 3;
481
482                                         if(nverts[i] == 4) {
483                                                 fdata[0] = uvs[tri_b[0]];
484                                                 fdata[1] = uvs[tri_b[1]];
485                                                 fdata[2] = uvs[tri_b[2]];
486                                                 fdata += 3;
487                                         }
488                                 }
489                         }
490
491                         /* UV tangent */
492                         std = (active_render)? ATTR_STD_UV_TANGENT: ATTR_STD_NONE;
493                         name = ustring((string(l->name().c_str()) + ".tangent").c_str());
494
495                         if(mesh->need_attribute(scene, name) || (active_render && mesh->need_attribute(scene, std))) {
496                                 std = (active_render)? ATTR_STD_UV_TANGENT_SIGN: ATTR_STD_NONE;
497                                 name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
498                                 bool need_sign = (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std));
499
500                                 mikk_compute_tangents(b_mesh,
501                                                       &(*l),
502                                                       mesh,
503                                                       nverts,
504                                                       face_flags,
505                                                       need_sign,
506                                                       active_render);
507                         }
508                 }
509         }
510         else if(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
511                 bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
512                 mikk_compute_tangents(b_mesh,
513                                       NULL,
514                                       mesh,
515                                       nverts,
516                                       face_flags,
517                                       need_sign,
518                                       true);
519         }
520 }
521
522 /* Create vertex pointiness attributes. */
523 static void attr_create_pointiness(Scene *scene,
524                                    Mesh *mesh,
525                                    BL::Mesh& b_mesh,
526                                    bool subdivision)
527 {
528         if(mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
529                 const int numverts = b_mesh.vertices.length();
530                 AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
531                 Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
532                 float *data = attr->data_float();
533                 int *counter = new int[numverts];
534                 float *raw_data = new float[numverts];
535                 float3 *edge_accum = new float3[numverts];
536
537                 /* Calculate pointiness using single ring neighborhood. */
538                 memset(counter, 0, sizeof(int) * numverts);
539                 memset(raw_data, 0, sizeof(float) * numverts);
540                 memset(edge_accum, 0, sizeof(float3) * numverts);
541                 BL::Mesh::edges_iterator e;
542                 int i = 0;
543                 for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
544                         int v0 = b_mesh.edges[i].vertices()[0],
545                             v1 = b_mesh.edges[i].vertices()[1];
546                         float3 co0 = get_float3(b_mesh.vertices[v0].co()),
547                                co1 = get_float3(b_mesh.vertices[v1].co());
548                         float3 edge = normalize(co1 - co0);
549                         edge_accum[v0] += edge;
550                         edge_accum[v1] += -edge;
551                         ++counter[v0];
552                         ++counter[v1];
553                 }
554                 i = 0;
555                 BL::Mesh::vertices_iterator v;
556                 for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++i) {
557                         if(counter[i] > 0) {
558                                 float3 normal = get_float3(b_mesh.vertices[i].normal());
559                                 float angle = safe_acosf(dot(normal, edge_accum[i] / counter[i]));
560                                 raw_data[i] = angle * M_1_PI_F;
561                         }
562                         else {
563                                 raw_data[i] = 0.0f;
564                         }
565                 }
566
567                 /* Blur vertices to approximate 2 ring neighborhood. */
568                 memset(counter, 0, sizeof(int) * numverts);
569                 memcpy(data, raw_data, sizeof(float) * numverts);
570                 i = 0;
571                 for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
572                         int v0 = b_mesh.edges[i].vertices()[0],
573                             v1 = b_mesh.edges[i].vertices()[1];
574                         data[v0] += raw_data[v1];
575                         data[v1] += raw_data[v0];
576                         ++counter[v0];
577                         ++counter[v1];
578                 }
579                 for(i = 0; i < numverts; ++i) {
580                         data[i] /= counter[i] + 1;
581                 }
582
583                 delete [] counter;
584                 delete [] raw_data;
585                 delete [] edge_accum;
586         }
587 }
588
589 /* Create Mesh */
590
591 static void create_mesh(Scene *scene,
592                         Mesh *mesh,
593                         BL::Mesh& b_mesh,
594                         const vector<Shader*>& used_shaders,
595                         bool subdivision=false)
596 {
597         /* count vertices and faces */
598         int numverts = b_mesh.vertices.length();
599         int numfaces = (!subdivision) ? b_mesh.tessfaces.length() : b_mesh.polygons.length();
600         int numtris = 0;
601         int numcorners = 0;
602         int numngons = 0;
603         bool use_loop_normals = b_mesh.use_auto_smooth();
604
605         BL::Mesh::vertices_iterator v;
606         BL::Mesh::tessfaces_iterator f;
607         BL::Mesh::polygons_iterator p;
608
609         if(!subdivision) {
610                 for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) {
611                         int4 vi = get_int4(f->vertices_raw());
612                         numtris += (vi[3] == 0)? 1: 2;
613                 }
614         }
615         else {
616                 for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
617                         numngons += (p->loop_total() == 4)? 0: 1;
618                         numcorners += p->loop_total();
619                 }
620         }
621
622         /* allocate memory */
623         mesh->reserve_mesh(numverts, numtris);
624         mesh->reserve_subd_faces(numfaces, numngons, numcorners);
625
626         /* create vertex coordinates and normals */
627         for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
628                 mesh->add_vertex(get_float3(v->co()));
629
630         AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
631         Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL);
632         float3 *N = attr_N->data_float3();
633
634         for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
635                 *N = get_float3(v->normal());
636         N = attr_N->data_float3();
637
638         /* create generated coordinates from undeformed coordinates */
639         if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
640                 Attribute *attr = attributes.add(ATTR_STD_GENERATED);
641
642                 float3 loc, size;
643                 mesh_texture_space(b_mesh, loc, size);
644
645                 float3 *generated = attr->data_float3();
646                 size_t i = 0;
647
648                 for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
649                         generated[i++] = get_float3(v->undeformed_co())*size - loc;
650         }
651
652         /* Create needed vertex attributes. */
653         attr_create_pointiness(scene, mesh, b_mesh, subdivision);
654
655         /* create faces */
656         vector<int> nverts(numfaces);
657         vector<int> face_flags(numfaces, FACE_FLAG_NONE);
658         int fi = 0;
659
660         if(!subdivision) {
661                 for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) {
662                         int4 vi = get_int4(f->vertices_raw());
663                         int n = (vi[3] == 0)? 3: 4;
664                         int shader = clamp(f->material_index(), 0, used_shaders.size()-1);
665                         bool smooth = f->use_smooth() || use_loop_normals;
666
667                         /* split vertices if normal is different
668                          *
669                          * note all vertex attributes must have been set here so we can split
670                          * and copy attributes in split_vertex without remapping later */
671                         if(use_loop_normals) {
672                                 BL::Array<float, 12> loop_normals = f->split_normals();
673
674                                 for(int i = 0; i < n; i++) {
675                                         float3 loop_N = make_float3(loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
676
677                                         if(N[vi[i]] != loop_N) {
678                                                 int new_vi = mesh->split_vertex(vi[i]);
679
680                                                 /* set new normal and vertex index */
681                                                 N = attr_N->data_float3();
682                                                 N[new_vi] = loop_N;
683                                                 vi[i] = new_vi;
684                                         }
685                                 }
686                         }
687
688                         /* create triangles */
689                         if(n == 4) {
690                                 if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) ||
691                                    is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]])))
692                                 {
693                                         mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth);
694                                         mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth);
695                                         face_flags[fi] |= FACE_FLAG_DIVIDE_24;
696                                 }
697                                 else {
698                                         mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
699                                         mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
700                                         face_flags[fi] |= FACE_FLAG_DIVIDE_13;
701                                 }
702                         }
703                         else {
704                                 mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
705                         }
706
707                         nverts[fi] = n;
708                 }
709         }
710         else {
711                 vector<int> vi;
712
713                 for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
714                         int n = p->loop_total();
715                         int shader = clamp(p->material_index(), 0, used_shaders.size()-1);
716                         bool smooth = p->use_smooth() || use_loop_normals;
717
718                         vi.reserve(n);
719                         for(int i = 0; i < n; i++) {
720                                 vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
721
722                                 /* split vertices if normal is different
723                                  *
724                                  * note all vertex attributes must have been set here so we can split
725                                  * and copy attributes in split_vertex without remapping later */
726                                 if(use_loop_normals) {
727                                         float3 loop_N = get_float3(b_mesh.loops[p->loop_start() + i].normal());
728
729                                         if(N[vi[i]] != loop_N) {
730                                                 int new_vi = mesh->split_vertex(vi[i]);
731
732                                                 /* set new normal and vertex index */
733                                                 N = attr_N->data_float3();
734                                                 N[new_vi] = loop_N;
735                                                 vi[i] = new_vi;
736                                         }
737                                 }
738                         }
739
740                         /* create subd faces */
741                         mesh->add_subd_face(&vi[0], n, shader, smooth);
742                 }
743         }
744
745         /* Create all needed attributes.
746          * The calculate functions will check whether they're needed or not.
747          */
748         attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags, subdivision);
749         attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags, subdivision);
750
751         /* for volume objects, create a matrix to transform from object space to
752          * mesh texture space. this does not work with deformations but that can
753          * probably only be done well with a volume grid mapping of coordinates */
754         if(mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
755                 Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
756                 Transform *tfm = attr->data_transform();
757
758                 float3 loc, size;
759                 mesh_texture_space(b_mesh, loc, size);
760
761                 *tfm = transform_translate(-loc)*transform_scale(size);
762         }
763 }
764
765 static void create_subd_mesh(Scene *scene,
766                              Mesh *mesh,
767                              BL::Object& b_ob,
768                              BL::Mesh& b_mesh,
769                              PointerRNA *cmesh,
770                              const vector<Shader*>& used_shaders,
771                              float dicing_rate,
772                              int max_subdivisions)
773 {
774         create_mesh(scene, mesh, b_mesh, used_shaders, true);
775
776         SubdParams sdparams(mesh);
777
778         PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
779
780         sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
781         sdparams.max_level = max_subdivisions;
782
783         scene->camera->update();
784         sdparams.camera = scene->camera;
785         sdparams.objecttoworld = get_transform(b_ob.matrix_world());
786
787         /* tesselate */
788         DiagSplit dsplit(sdparams);
789         mesh->tessellate(&dsplit);
790 }
791
792 /* Sync */
793
794 static void sync_mesh_fluid_motion(BL::Object& b_ob, Scene *scene, Mesh *mesh)
795 {
796         if(scene->need_motion() == Scene::MOTION_NONE)
797                 return;
798
799         BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
800
801         if(!b_fluid_domain)
802                 return;
803
804         /* If the mesh has modifiers following the fluid domain we can't export motion. */
805         if(b_fluid_domain.fluid_mesh_vertices.length() != mesh->verts.size())
806                 return;
807
808         /* Find or add attribute */
809         float3 *P = &mesh->verts[0];
810         Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
811
812         if(!attr_mP) {
813                 attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
814         }
815
816         /* Only export previous and next frame, we don't have any in between data. */
817         float motion_times[2] = {-1.0f, 1.0f};
818         for (int step = 0; step < 2; step++) {
819                 float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
820                 float3 *mP = attr_mP->data_float3() + step*mesh->verts.size();
821
822                 BL::DomainFluidSettings::fluid_mesh_vertices_iterator fvi;
823                 int i = 0;
824
825                 for(b_fluid_domain.fluid_mesh_vertices.begin(fvi); fvi != b_fluid_domain.fluid_mesh_vertices.end(); ++fvi, ++i) {
826                         mP[i] = P[i] + get_float3(fvi->velocity()) * relative_time;
827                 }
828         }
829 }
830
831 Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
832                              bool object_updated,
833                              bool hide_tris)
834 {
835         /* When viewport display is not needed during render we can force some
836          * caches to be releases from blender side in order to reduce peak memory
837          * footprint during synchronization process.
838          */
839         const bool is_interface_locked = b_engine.render() &&
840                                          b_engine.render().use_lock_interface();
841         const bool can_free_caches = BlenderSession::headless || is_interface_locked;
842
843         /* test if we can instance or if the object is modified */
844         BL::ID b_ob_data = b_ob.data();
845         BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob_data;
846         BL::Material material_override = render_layer.material_override;
847
848         /* find shader indices */
849         vector<Shader*> used_shaders;
850
851         BL::Object::material_slots_iterator slot;
852         for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
853                 if(material_override) {
854                         find_shader(material_override, used_shaders, scene->default_surface);
855                 }
856                 else {
857                         BL::ID b_material(slot->material());
858                         find_shader(b_material, used_shaders, scene->default_surface);
859                 }
860         }
861
862         if(used_shaders.size() == 0) {
863                 if(material_override)
864                         find_shader(material_override, used_shaders, scene->default_surface);
865                 else
866                         used_shaders.push_back(scene->default_surface);
867         }
868         
869         /* test if we need to sync */
870         int requested_geometry_flags = Mesh::GEOMETRY_NONE;
871         if(render_layer.use_surfaces) {
872                 requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES;
873         }
874         if(render_layer.use_hair) {
875                 requested_geometry_flags |= Mesh::GEOMETRY_CURVES;
876         }
877         Mesh *mesh;
878
879         if(!mesh_map.sync(&mesh, key)) {
880                 /* if transform was applied to mesh, need full update */
881                 if(object_updated && mesh->transform_applied);
882                 /* test if shaders changed, these can be object level so mesh
883                  * does not get tagged for recalc */
884                 else if(mesh->used_shaders != used_shaders);
885                 else if(requested_geometry_flags != mesh->geometry_flags);
886                 else {
887                         /* even if not tagged for recalc, we may need to sync anyway
888                          * because the shader needs different mesh attributes */
889                         bool attribute_recalc = false;
890
891                         foreach(Shader *shader, mesh->used_shaders)
892                                 if(shader->need_update_attributes)
893                                         attribute_recalc = true;
894
895                         if(!attribute_recalc)
896                                 return mesh;
897                 }
898         }
899
900         /* ensure we only sync instanced meshes once */
901         if(mesh_synced.find(mesh) != mesh_synced.end())
902                 return mesh;
903         
904         mesh_synced.insert(mesh);
905
906         /* create derived mesh */
907         PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles");
908
909         array<int> oldtriangle = mesh->triangles;
910         
911         /* compares curve_keys rather than strands in order to handle quick hair
912          * adjustments in dynamic BVH - other methods could probably do this better*/
913         array<float3> oldcurve_keys = mesh->curve_keys;
914         array<float> oldcurve_radius = mesh->curve_radius;
915
916         mesh->clear();
917         mesh->used_shaders = used_shaders;
918         mesh->name = ustring(b_ob_data.name().c_str());
919
920         if(requested_geometry_flags != Mesh::GEOMETRY_NONE) {
921                 /* mesh objects does have special handle in the dependency graph,
922                  * they're ensured to have properly updated.
923                  *
924                  * updating meshes here will end up having derived mesh referencing
925                  * freed data from the blender side.
926                  */
927                 if(preview && b_ob.type() != BL::Object::type_MESH)
928                         b_ob.update_from_editmode();
929
930                 bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
931
932                 mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
933
934                 PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
935
936                 if(cobj.data && b_ob.modifiers.length() > 0 && experimental) {
937                         BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length()-1];
938                         bool enabled = preview ? mod.show_viewport() : mod.show_render();
939
940                         if(enabled && mod.type() == BL::Modifier::type_SUBSURF && RNA_int_get(&cobj, "use_adaptive_subdivision")) {
941                                 BL::SubsurfModifier subsurf(mod);
942
943                                 if(subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
944                                         mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK;
945                                 }
946                                 else {
947                                         mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR;
948                                 }
949                         }
950                 }
951
952                 BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed, mesh->subdivision_type);
953
954                 if(b_mesh) {
955                         if(render_layer.use_surfaces && !hide_tris) {
956                                 if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
957                                         create_subd_mesh(scene, mesh, b_ob, b_mesh, &cmesh, used_shaders,
958                                                          dicing_rate, max_subdivisions);
959                                 else
960                                         create_mesh(scene, mesh, b_mesh, used_shaders, false);
961
962                                 create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
963                         }
964
965                         if(render_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
966                                 sync_curves(mesh, b_mesh, b_ob, false);
967
968                         if(can_free_caches) {
969                                 b_ob.cache_release();
970                         }
971
972                         /* free derived mesh */
973                         b_data.meshes.remove(b_mesh, false);
974                 }
975         }
976         mesh->geometry_flags = requested_geometry_flags;
977
978         /* displacement method */
979         if(cmesh.data) {
980                 const int method = get_enum(cmesh,
981                                             "displacement_method",
982                                             Mesh::DISPLACE_NUM_METHODS,
983                                             Mesh::DISPLACE_BUMP);
984
985                 if(method == 0 || !experimental)
986                         mesh->displacement_method = Mesh::DISPLACE_BUMP;
987                 else if(method == 1)
988                         mesh->displacement_method = Mesh::DISPLACE_TRUE;
989                 else
990                         mesh->displacement_method = Mesh::DISPLACE_BOTH;
991         }
992
993         /* fluid motion */
994         sync_mesh_fluid_motion(b_ob, scene, mesh);
995
996         /* tag update */
997         bool rebuild = false;
998
999         if(oldtriangle.size() != mesh->triangles.size())
1000                 rebuild = true;
1001         else if(oldtriangle.size()) {
1002                 if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(int)*oldtriangle.size()) != 0)
1003                         rebuild = true;
1004         }
1005
1006         if(oldcurve_keys.size() != mesh->curve_keys.size())
1007                 rebuild = true;
1008         else if(oldcurve_keys.size()) {
1009                 if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(float3)*oldcurve_keys.size()) != 0)
1010                         rebuild = true;
1011         }
1012
1013         if(oldcurve_radius.size() != mesh->curve_radius.size())
1014                 rebuild = true;
1015         else if(oldcurve_radius.size()) {
1016                 if(memcmp(&oldcurve_radius[0], &mesh->curve_radius[0], sizeof(float)*oldcurve_radius.size()) != 0)
1017                         rebuild = true;
1018         }
1019         
1020         mesh->tag_update(scene, rebuild);
1021
1022         return mesh;
1023 }
1024
1025 void BlenderSync::sync_mesh_motion(BL::Object& b_ob,
1026                                    Object *object,
1027                                    float motion_time)
1028 {
1029         /* ensure we only sync instanced meshes once */
1030         Mesh *mesh = object->mesh;
1031
1032         if(mesh_motion_synced.find(mesh) != mesh_motion_synced.end())
1033                 return;
1034
1035         mesh_motion_synced.insert(mesh);
1036
1037         /* ensure we only motion sync meshes that also had mesh synced, to avoid
1038          * unnecessary work and to ensure that its attributes were clear */
1039         if(mesh_synced.find(mesh) == mesh_synced.end())
1040                 return;
1041
1042         /* for motion pass always compute, for motion blur it can be disabled */
1043         int time_index = 0;
1044
1045         if(scene->need_motion() == Scene::MOTION_BLUR) {
1046                 if(!mesh->use_motion_blur)
1047                         return;
1048                 
1049                 /* see if this mesh needs motion data at this time */
1050                 vector<float> object_times = object->motion_times();
1051                 bool found = false;
1052
1053                 foreach(float object_time, object_times) {
1054                         if(motion_time == object_time) {
1055                                 found = true;
1056                                 break;
1057                         }
1058                         else
1059                                 time_index++;
1060                 }
1061
1062                 if(!found)
1063                         return;
1064         }
1065         else {
1066                 if(motion_time == -1.0f)
1067                         time_index = 0;
1068                 else if(motion_time == 1.0f)
1069                         time_index = 1;
1070                 else
1071                         return;
1072         }
1073
1074         /* skip empty meshes */
1075         size_t numverts = mesh->verts.size();
1076         size_t numkeys = mesh->curve_keys.size();
1077
1078         if(!numverts && !numkeys)
1079                 return;
1080         
1081         /* skip objects without deforming modifiers. this is not totally reliable,
1082          * would need a more extensive check to see which objects are animated */
1083         BL::Mesh b_mesh(PointerRNA_NULL);
1084
1085         /* fluid motion is exported immediate with mesh, skip here */
1086         BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
1087         if (b_fluid_domain)
1088                 return;
1089
1090         if(ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
1091                 /* get derived mesh */
1092                 b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false, false);
1093         }
1094
1095         if(!b_mesh) {
1096                 /* if we have no motion blur on this frame, but on other frames, copy */
1097                 if(numverts) {
1098                         /* triangles */
1099                         Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1100
1101                         if(attr_mP) {
1102                                 Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
1103                                 Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
1104                                 float3 *P = &mesh->verts[0];
1105                                 float3 *N = (attr_N)? attr_N->data_float3(): NULL;
1106
1107                                 memcpy(attr_mP->data_float3() + time_index*numverts, P, sizeof(float3)*numverts);
1108                                 if(attr_mN)
1109                                         memcpy(attr_mN->data_float3() + time_index*numverts, N, sizeof(float3)*numverts);
1110                         }
1111                 }
1112
1113                 if(numkeys) {
1114                         /* curves */
1115                         Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1116
1117                         if(attr_mP) {
1118                                 float3 *keys = &mesh->curve_keys[0];
1119                                 memcpy(attr_mP->data_float3() + time_index*numkeys, keys, sizeof(float3)*numkeys);
1120                         }
1121                 }
1122
1123                 return;
1124         }
1125
1126         /* TODO(sergey): Perform preliminary check for number of verticies. */
1127         if(numverts) {
1128                 /* find attributes */
1129                 Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1130                 Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
1131                 Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
1132                 bool new_attribute = false;
1133
1134                 /* add new attributes if they don't exist already */
1135                 if(!attr_mP) {
1136                         attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
1137                         if(attr_N)
1138                                 attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
1139
1140                         new_attribute = true;
1141                 }
1142
1143                 /* load vertex data from mesh */
1144                 float3 *mP = attr_mP->data_float3() + time_index*numverts;
1145                 float3 *mN = (attr_mN)? attr_mN->data_float3() + time_index*numverts: NULL;
1146
1147                 BL::Mesh::vertices_iterator v;
1148                 int i = 0;
1149
1150                 for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
1151                         mP[i] = get_float3(v->co());
1152                         if(mN)
1153                                 mN[i] = get_float3(v->normal());
1154                 }
1155
1156                 /* in case of new attribute, we verify if there really was any motion */
1157                 if(new_attribute) {
1158                         if(b_mesh.vertices.length() != numverts ||
1159                            memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0)
1160                         {
1161                                 /* no motion, remove attributes again */
1162                                 if(b_mesh.vertices.length() != numverts) {
1163                                         VLOG(1) << "Topology differs, disabling motion blur.";
1164                                 }
1165                                 else {
1166                                         VLOG(1) << "No actual deformation motion for object " << b_ob.name();
1167                                 }
1168                                 mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
1169                                 if(attr_mN)
1170                                         mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
1171                         }
1172                         else if(time_index > 0) {
1173                                 VLOG(1) << "Filling deformation motion for object " << b_ob.name();
1174                                 /* motion, fill up previous steps that we might have skipped because
1175                                  * they had no motion, but we need them anyway now */
1176                                 float3 *P = &mesh->verts[0];
1177                                 float3 *N = (attr_N)? attr_N->data_float3(): NULL;
1178
1179                                 for(int step = 0; step < time_index; step++) {
1180                                         memcpy(attr_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts);
1181                                         if(attr_mN)
1182                                                 memcpy(attr_mN->data_float3() + step*numverts, N, sizeof(float3)*numverts);
1183                                 }
1184                         }
1185                 }
1186         }
1187
1188         /* hair motion */
1189         if(numkeys)
1190                 sync_curves(mesh, b_mesh, b_ob, true, time_index);
1191
1192         /* free derived mesh */
1193         b_data.meshes.remove(b_mesh, false);
1194 }
1195
1196 CCL_NAMESPACE_END
1197