Cycles microdisplacement: Move call to tessellate() from addon to Cycles
[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                                bool subdivide_uvs)
414 {
415         if(subdivision) {
416                 BL::Mesh::uv_layers_iterator l;
417                 int i = 0;
418
419                 for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
420                         bool active_render = b_mesh.uv_textures[i].active_render();
421                         AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
422                         ustring name = ustring(l->name().c_str());
423
424                         /* UV map */
425                         if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
426                                 Attribute *attr;
427
428                                 if(active_render)
429                                         attr = mesh->subd_attributes.add(std, name);
430                                 else
431                                         attr = mesh->subd_attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
432
433                                 if(subdivide_uvs) {
434                                         attr->flags |= ATTR_SUBDIVIDED;
435                                 }
436
437                                 BL::Mesh::polygons_iterator p;
438                                 float3 *fdata = attr->data_float3();
439
440                                 for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
441                                         int n = p->loop_total();
442                                         for(int j = 0; j < n; j++) {
443                                                 *(fdata++) = get_float3(l->data[p->loop_start() + j].uv());
444                                         }
445                                 }
446                         }
447                 }
448         }
449         else if(b_mesh.tessface_uv_textures.length() != 0) {
450                 BL::Mesh::tessface_uv_textures_iterator l;
451
452                 for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
453                         bool active_render = l->active_render();
454                         AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
455                         ustring name = ustring(l->name().c_str());
456
457                         /* UV map */
458                         if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
459                                 Attribute *attr;
460
461                                 if(active_render)
462                                         attr = mesh->attributes.add(std, name);
463                                 else
464                                         attr = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
465
466                                 BL::MeshTextureFaceLayer::data_iterator t;
467                                 float3 *fdata = attr->data_float3();
468                                 size_t i = 0;
469
470                                 for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
471                                         int tri_a[3], tri_b[3];
472                                         face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b);
473
474                                         float3 uvs[4];
475                                         uvs[0] = get_float3(t->uv1());
476                                         uvs[1] = get_float3(t->uv2());
477                                         uvs[2] = get_float3(t->uv3());
478                                         if(nverts[i] == 4) {
479                                                 uvs[3] = get_float3(t->uv4());
480                                         }
481
482                                         fdata[0] = uvs[tri_a[0]];
483                                         fdata[1] = uvs[tri_a[1]];
484                                         fdata[2] = uvs[tri_a[2]];
485                                         fdata += 3;
486
487                                         if(nverts[i] == 4) {
488                                                 fdata[0] = uvs[tri_b[0]];
489                                                 fdata[1] = uvs[tri_b[1]];
490                                                 fdata[2] = uvs[tri_b[2]];
491                                                 fdata += 3;
492                                         }
493                                 }
494                         }
495
496                         /* UV tangent */
497                         std = (active_render)? ATTR_STD_UV_TANGENT: ATTR_STD_NONE;
498                         name = ustring((string(l->name().c_str()) + ".tangent").c_str());
499
500                         if(mesh->need_attribute(scene, name) || (active_render && mesh->need_attribute(scene, std))) {
501                                 std = (active_render)? ATTR_STD_UV_TANGENT_SIGN: ATTR_STD_NONE;
502                                 name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
503                                 bool need_sign = (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std));
504
505                                 mikk_compute_tangents(b_mesh,
506                                                       &(*l),
507                                                       mesh,
508                                                       nverts,
509                                                       face_flags,
510                                                       need_sign,
511                                                       active_render);
512                         }
513                 }
514         }
515         else if(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
516                 bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
517                 mikk_compute_tangents(b_mesh,
518                                       NULL,
519                                       mesh,
520                                       nverts,
521                                       face_flags,
522                                       need_sign,
523                                       true);
524         }
525 }
526
527 /* Create vertex pointiness attributes. */
528 static void attr_create_pointiness(Scene *scene,
529                                    Mesh *mesh,
530                                    BL::Mesh& b_mesh,
531                                    bool subdivision)
532 {
533         if(mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
534                 const int numverts = b_mesh.vertices.length();
535                 AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
536                 Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
537                 float *data = attr->data_float();
538                 int *counter = new int[numverts];
539                 float *raw_data = new float[numverts];
540                 float3 *edge_accum = new float3[numverts];
541
542                 /* Calculate pointiness using single ring neighborhood. */
543                 memset(counter, 0, sizeof(int) * numverts);
544                 memset(raw_data, 0, sizeof(float) * numverts);
545                 memset(edge_accum, 0, sizeof(float3) * numverts);
546                 BL::Mesh::edges_iterator e;
547                 int i = 0;
548                 for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
549                         int v0 = b_mesh.edges[i].vertices()[0],
550                             v1 = b_mesh.edges[i].vertices()[1];
551                         float3 co0 = get_float3(b_mesh.vertices[v0].co()),
552                                co1 = get_float3(b_mesh.vertices[v1].co());
553                         float3 edge = normalize(co1 - co0);
554                         edge_accum[v0] += edge;
555                         edge_accum[v1] += -edge;
556                         ++counter[v0];
557                         ++counter[v1];
558                 }
559                 i = 0;
560                 BL::Mesh::vertices_iterator v;
561                 for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++i) {
562                         if(counter[i] > 0) {
563                                 float3 normal = get_float3(b_mesh.vertices[i].normal());
564                                 float angle = safe_acosf(dot(normal, edge_accum[i] / counter[i]));
565                                 raw_data[i] = angle * M_1_PI_F;
566                         }
567                         else {
568                                 raw_data[i] = 0.0f;
569                         }
570                 }
571
572                 /* Blur vertices to approximate 2 ring neighborhood. */
573                 memset(counter, 0, sizeof(int) * numverts);
574                 memcpy(data, raw_data, sizeof(float) * numverts);
575                 i = 0;
576                 for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
577                         int v0 = b_mesh.edges[i].vertices()[0],
578                             v1 = b_mesh.edges[i].vertices()[1];
579                         data[v0] += raw_data[v1];
580                         data[v1] += raw_data[v0];
581                         ++counter[v0];
582                         ++counter[v1];
583                 }
584                 for(i = 0; i < numverts; ++i) {
585                         data[i] /= counter[i] + 1;
586                 }
587
588                 delete [] counter;
589                 delete [] raw_data;
590                 delete [] edge_accum;
591         }
592 }
593
594 /* Create Mesh */
595
596 static void create_mesh(Scene *scene,
597                         Mesh *mesh,
598                         BL::Mesh& b_mesh,
599                         const vector<Shader*>& used_shaders,
600                         bool subdivision=false,
601                         bool subdivide_uvs=true)
602 {
603         /* count vertices and faces */
604         int numverts = b_mesh.vertices.length();
605         int numfaces = (!subdivision) ? b_mesh.tessfaces.length() : b_mesh.polygons.length();
606         int numtris = 0;
607         int numcorners = 0;
608         int numngons = 0;
609         bool use_loop_normals = b_mesh.use_auto_smooth();
610
611         BL::Mesh::vertices_iterator v;
612         BL::Mesh::tessfaces_iterator f;
613         BL::Mesh::polygons_iterator p;
614
615         if(!subdivision) {
616                 for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) {
617                         int4 vi = get_int4(f->vertices_raw());
618                         numtris += (vi[3] == 0)? 1: 2;
619                 }
620         }
621         else {
622                 for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
623                         numngons += (p->loop_total() == 4)? 0: 1;
624                         numcorners += p->loop_total();
625                 }
626         }
627
628         /* allocate memory */
629         mesh->reserve_mesh(numverts, numtris);
630         mesh->reserve_subd_faces(numfaces, numngons, numcorners);
631
632         /* create vertex coordinates and normals */
633         for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
634                 mesh->add_vertex(get_float3(v->co()));
635
636         AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
637         Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL);
638         float3 *N = attr_N->data_float3();
639
640         for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
641                 *N = get_float3(v->normal());
642         N = attr_N->data_float3();
643
644         /* create generated coordinates from undeformed coordinates */
645         if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
646                 Attribute *attr = attributes.add(ATTR_STD_GENERATED);
647                 attr->flags |= ATTR_SUBDIVIDED;
648
649                 float3 loc, size;
650                 mesh_texture_space(b_mesh, loc, size);
651
652                 float3 *generated = attr->data_float3();
653                 size_t i = 0;
654
655                 for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
656                         generated[i++] = get_float3(v->undeformed_co())*size - loc;
657         }
658
659         /* Create needed vertex attributes. */
660         attr_create_pointiness(scene, mesh, b_mesh, subdivision);
661
662         /* create faces */
663         vector<int> nverts(numfaces);
664         vector<int> face_flags(numfaces, FACE_FLAG_NONE);
665         int fi = 0;
666
667         if(!subdivision) {
668                 for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) {
669                         int4 vi = get_int4(f->vertices_raw());
670                         int n = (vi[3] == 0)? 3: 4;
671                         int shader = clamp(f->material_index(), 0, used_shaders.size()-1);
672                         bool smooth = f->use_smooth() || use_loop_normals;
673
674                         /* split vertices if normal is different
675                          *
676                          * note all vertex attributes must have been set here so we can split
677                          * and copy attributes in split_vertex without remapping later */
678                         if(use_loop_normals) {
679                                 BL::Array<float, 12> loop_normals = f->split_normals();
680
681                                 for(int i = 0; i < n; i++) {
682                                         float3 loop_N = make_float3(loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
683
684                                         if(N[vi[i]] != loop_N) {
685                                                 int new_vi = mesh->split_vertex(vi[i]);
686
687                                                 /* set new normal and vertex index */
688                                                 N = attr_N->data_float3();
689                                                 N[new_vi] = loop_N;
690                                                 vi[i] = new_vi;
691                                         }
692                                 }
693                         }
694
695                         /* create triangles */
696                         if(n == 4) {
697                                 if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) ||
698                                    is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]])))
699                                 {
700                                         mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth);
701                                         mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth);
702                                         face_flags[fi] |= FACE_FLAG_DIVIDE_24;
703                                 }
704                                 else {
705                                         mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
706                                         mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
707                                         face_flags[fi] |= FACE_FLAG_DIVIDE_13;
708                                 }
709                         }
710                         else {
711                                 mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
712                         }
713
714                         nverts[fi] = n;
715                 }
716         }
717         else {
718                 vector<int> vi;
719
720                 for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
721                         int n = p->loop_total();
722                         int shader = clamp(p->material_index(), 0, used_shaders.size()-1);
723                         bool smooth = p->use_smooth() || use_loop_normals;
724
725                         vi.reserve(n);
726                         for(int i = 0; i < n; i++) {
727                                 vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
728
729                                 /* split vertices if normal is different
730                                  *
731                                  * note all vertex attributes must have been set here so we can split
732                                  * and copy attributes in split_vertex without remapping later */
733                                 if(use_loop_normals) {
734                                         float3 loop_N = get_float3(b_mesh.loops[p->loop_start() + i].normal());
735
736                                         if(N[vi[i]] != loop_N) {
737                                                 int new_vi = mesh->split_vertex(vi[i]);
738
739                                                 /* set new normal and vertex index */
740                                                 N = attr_N->data_float3();
741                                                 N[new_vi] = loop_N;
742                                                 vi[i] = new_vi;
743                                         }
744                                 }
745                         }
746
747                         /* create subd faces */
748                         mesh->add_subd_face(&vi[0], n, shader, smooth);
749                 }
750         }
751
752         /* Create all needed attributes.
753          * The calculate functions will check whether they're needed or not.
754          */
755         attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags, subdivision);
756         attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags, subdivision, subdivide_uvs);
757
758         /* for volume objects, create a matrix to transform from object space to
759          * mesh texture space. this does not work with deformations but that can
760          * probably only be done well with a volume grid mapping of coordinates */
761         if(mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
762                 Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
763                 Transform *tfm = attr->data_transform();
764
765                 float3 loc, size;
766                 mesh_texture_space(b_mesh, loc, size);
767
768                 *tfm = transform_translate(-loc)*transform_scale(size);
769         }
770 }
771
772 static void create_subd_mesh(Scene *scene,
773                              Mesh *mesh,
774                              BL::Object& b_ob,
775                              BL::Mesh& b_mesh,
776                              const vector<Shader*>& used_shaders,
777                              float dicing_rate,
778                              int max_subdivisions)
779 {
780         BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length()-1]);
781         bool subdivide_uvs = subsurf_mod.use_subsurf_uv();
782
783         create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
784
785         /* export creases */
786         size_t num_creases = 0;
787         BL::Mesh::edges_iterator e;
788
789         for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
790                 if(e->crease() != 0.0f) {
791                         num_creases++;
792                 }
793         }
794
795         mesh->subd_creases.resize(num_creases);
796
797         Mesh::SubdEdgeCrease* crease = mesh->subd_creases.data();
798         for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
799                 if(e->crease() != 0.0f) {
800                         crease->v[0] = e->vertices()[0];
801                         crease->v[1] = e->vertices()[1];
802                         crease->crease = e->crease();
803
804                         crease++;
805                 }
806         }
807
808         /* set subd params */
809         if(!mesh->subd_params) {
810                 mesh->subd_params = new SubdParams(mesh);
811         }
812         SubdParams& sdparams = *mesh->subd_params;
813
814         PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
815
816         sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
817         sdparams.max_level = max_subdivisions;
818
819         scene->camera->update();
820         sdparams.camera = scene->camera;
821         sdparams.objecttoworld = get_transform(b_ob.matrix_world());
822 }
823
824 /* Sync */
825
826 static void sync_mesh_fluid_motion(BL::Object& b_ob, Scene *scene, Mesh *mesh)
827 {
828         if(scene->need_motion() == Scene::MOTION_NONE)
829                 return;
830
831         BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
832
833         if(!b_fluid_domain)
834                 return;
835
836         /* If the mesh has modifiers following the fluid domain we can't export motion. */
837         if(b_fluid_domain.fluid_mesh_vertices.length() != mesh->verts.size())
838                 return;
839
840         /* Find or add attribute */
841         float3 *P = &mesh->verts[0];
842         Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
843
844         if(!attr_mP) {
845                 attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
846         }
847
848         /* Only export previous and next frame, we don't have any in between data. */
849         float motion_times[2] = {-1.0f, 1.0f};
850         for (int step = 0; step < 2; step++) {
851                 float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
852                 float3 *mP = attr_mP->data_float3() + step*mesh->verts.size();
853
854                 BL::DomainFluidSettings::fluid_mesh_vertices_iterator fvi;
855                 int i = 0;
856
857                 for(b_fluid_domain.fluid_mesh_vertices.begin(fvi); fvi != b_fluid_domain.fluid_mesh_vertices.end(); ++fvi, ++i) {
858                         mP[i] = P[i] + get_float3(fvi->velocity()) * relative_time;
859                 }
860         }
861 }
862
863 Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
864                              bool object_updated,
865                              bool hide_tris)
866 {
867         /* When viewport display is not needed during render we can force some
868          * caches to be releases from blender side in order to reduce peak memory
869          * footprint during synchronization process.
870          */
871         const bool is_interface_locked = b_engine.render() &&
872                                          b_engine.render().use_lock_interface();
873         const bool can_free_caches = BlenderSession::headless || is_interface_locked;
874
875         /* test if we can instance or if the object is modified */
876         BL::ID b_ob_data = b_ob.data();
877         BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob_data;
878         BL::Material material_override = render_layer.material_override;
879
880         /* find shader indices */
881         vector<Shader*> used_shaders;
882
883         BL::Object::material_slots_iterator slot;
884         for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
885                 if(material_override) {
886                         find_shader(material_override, used_shaders, scene->default_surface);
887                 }
888                 else {
889                         BL::ID b_material(slot->material());
890                         find_shader(b_material, used_shaders, scene->default_surface);
891                 }
892         }
893
894         if(used_shaders.size() == 0) {
895                 if(material_override)
896                         find_shader(material_override, used_shaders, scene->default_surface);
897                 else
898                         used_shaders.push_back(scene->default_surface);
899         }
900         
901         /* test if we need to sync */
902         int requested_geometry_flags = Mesh::GEOMETRY_NONE;
903         if(render_layer.use_surfaces) {
904                 requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES;
905         }
906         if(render_layer.use_hair) {
907                 requested_geometry_flags |= Mesh::GEOMETRY_CURVES;
908         }
909         Mesh *mesh;
910
911         if(!mesh_map.sync(&mesh, key)) {
912                 /* if transform was applied to mesh, need full update */
913                 if(object_updated && mesh->transform_applied);
914                 /* test if shaders changed, these can be object level so mesh
915                  * does not get tagged for recalc */
916                 else if(mesh->used_shaders != used_shaders);
917                 else if(requested_geometry_flags != mesh->geometry_flags);
918                 else {
919                         /* even if not tagged for recalc, we may need to sync anyway
920                          * because the shader needs different mesh attributes */
921                         bool attribute_recalc = false;
922
923                         foreach(Shader *shader, mesh->used_shaders)
924                                 if(shader->need_update_attributes)
925                                         attribute_recalc = true;
926
927                         if(!attribute_recalc)
928                                 return mesh;
929                 }
930         }
931
932         /* ensure we only sync instanced meshes once */
933         if(mesh_synced.find(mesh) != mesh_synced.end())
934                 return mesh;
935         
936         mesh_synced.insert(mesh);
937
938         /* create derived mesh */
939         array<int> oldtriangle = mesh->triangles;
940         
941         /* compares curve_keys rather than strands in order to handle quick hair
942          * adjustments in dynamic BVH - other methods could probably do this better*/
943         array<float3> oldcurve_keys = mesh->curve_keys;
944         array<float> oldcurve_radius = mesh->curve_radius;
945
946         mesh->clear();
947         mesh->used_shaders = used_shaders;
948         mesh->name = ustring(b_ob_data.name().c_str());
949
950         if(requested_geometry_flags != Mesh::GEOMETRY_NONE) {
951                 /* mesh objects does have special handle in the dependency graph,
952                  * they're ensured to have properly updated.
953                  *
954                  * updating meshes here will end up having derived mesh referencing
955                  * freed data from the blender side.
956                  */
957                 if(preview && b_ob.type() != BL::Object::type_MESH)
958                         b_ob.update_from_editmode();
959
960                 bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
961
962                 mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
963
964                 PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
965
966                 if(cobj.data && b_ob.modifiers.length() > 0 && experimental) {
967                         BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length()-1];
968                         bool enabled = preview ? mod.show_viewport() : mod.show_render();
969
970                         if(enabled && mod.type() == BL::Modifier::type_SUBSURF && RNA_boolean_get(&cobj, "use_adaptive_subdivision")) {
971                                 BL::SubsurfModifier subsurf(mod);
972
973                                 if(subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
974                                         mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK;
975                                 }
976                                 else {
977                                         mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR;
978                                 }
979                         }
980                 }
981
982                 BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed, mesh->subdivision_type);
983
984                 if(b_mesh) {
985                         if(render_layer.use_surfaces && !hide_tris) {
986                                 if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
987                                         create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders,
988                                                          dicing_rate, max_subdivisions);
989                                 else
990                                         create_mesh(scene, mesh, b_mesh, used_shaders, false);
991
992                                 create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
993                         }
994
995                         if(render_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
996                                 sync_curves(mesh, b_mesh, b_ob, false);
997
998                         if(can_free_caches) {
999                                 b_ob.cache_release();
1000                         }
1001
1002                         /* free derived mesh */
1003                         b_data.meshes.remove(b_mesh, false);
1004                 }
1005         }
1006         mesh->geometry_flags = requested_geometry_flags;
1007
1008         /* fluid motion */
1009         sync_mesh_fluid_motion(b_ob, scene, mesh);
1010
1011         /* tag update */
1012         bool rebuild = false;
1013
1014         if(oldtriangle.size() != mesh->triangles.size())
1015                 rebuild = true;
1016         else if(oldtriangle.size()) {
1017                 if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(int)*oldtriangle.size()) != 0)
1018                         rebuild = true;
1019         }
1020
1021         if(oldcurve_keys.size() != mesh->curve_keys.size())
1022                 rebuild = true;
1023         else if(oldcurve_keys.size()) {
1024                 if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(float3)*oldcurve_keys.size()) != 0)
1025                         rebuild = true;
1026         }
1027
1028         if(oldcurve_radius.size() != mesh->curve_radius.size())
1029                 rebuild = true;
1030         else if(oldcurve_radius.size()) {
1031                 if(memcmp(&oldcurve_radius[0], &mesh->curve_radius[0], sizeof(float)*oldcurve_radius.size()) != 0)
1032                         rebuild = true;
1033         }
1034         
1035         mesh->tag_update(scene, rebuild);
1036
1037         return mesh;
1038 }
1039
1040 void BlenderSync::sync_mesh_motion(BL::Object& b_ob,
1041                                    Object *object,
1042                                    float motion_time)
1043 {
1044         /* ensure we only sync instanced meshes once */
1045         Mesh *mesh = object->mesh;
1046
1047         if(mesh_motion_synced.find(mesh) != mesh_motion_synced.end())
1048                 return;
1049
1050         mesh_motion_synced.insert(mesh);
1051
1052         /* ensure we only motion sync meshes that also had mesh synced, to avoid
1053          * unnecessary work and to ensure that its attributes were clear */
1054         if(mesh_synced.find(mesh) == mesh_synced.end())
1055                 return;
1056
1057         /* for motion pass always compute, for motion blur it can be disabled */
1058         int time_index = 0;
1059
1060         if(scene->need_motion() == Scene::MOTION_BLUR) {
1061                 if(!mesh->use_motion_blur)
1062                         return;
1063                 
1064                 /* see if this mesh needs motion data at this time */
1065                 vector<float> object_times = object->motion_times();
1066                 bool found = false;
1067
1068                 foreach(float object_time, object_times) {
1069                         if(motion_time == object_time) {
1070                                 found = true;
1071                                 break;
1072                         }
1073                         else
1074                                 time_index++;
1075                 }
1076
1077                 if(!found)
1078                         return;
1079         }
1080         else {
1081                 if(motion_time == -1.0f)
1082                         time_index = 0;
1083                 else if(motion_time == 1.0f)
1084                         time_index = 1;
1085                 else
1086                         return;
1087         }
1088
1089         /* skip empty meshes */
1090         size_t numverts = mesh->verts.size();
1091         size_t numkeys = mesh->curve_keys.size();
1092
1093         if(!numverts && !numkeys)
1094                 return;
1095         
1096         /* skip objects without deforming modifiers. this is not totally reliable,
1097          * would need a more extensive check to see which objects are animated */
1098         BL::Mesh b_mesh(PointerRNA_NULL);
1099
1100         /* fluid motion is exported immediate with mesh, skip here */
1101         BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
1102         if (b_fluid_domain)
1103                 return;
1104
1105         if(ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
1106                 /* get derived mesh */
1107                 b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false, false);
1108         }
1109
1110         if(!b_mesh) {
1111                 /* if we have no motion blur on this frame, but on other frames, copy */
1112                 if(numverts) {
1113                         /* triangles */
1114                         Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1115
1116                         if(attr_mP) {
1117                                 Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
1118                                 Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
1119                                 float3 *P = &mesh->verts[0];
1120                                 float3 *N = (attr_N)? attr_N->data_float3(): NULL;
1121
1122                                 memcpy(attr_mP->data_float3() + time_index*numverts, P, sizeof(float3)*numverts);
1123                                 if(attr_mN)
1124                                         memcpy(attr_mN->data_float3() + time_index*numverts, N, sizeof(float3)*numverts);
1125                         }
1126                 }
1127
1128                 if(numkeys) {
1129                         /* curves */
1130                         Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1131
1132                         if(attr_mP) {
1133                                 float3 *keys = &mesh->curve_keys[0];
1134                                 memcpy(attr_mP->data_float3() + time_index*numkeys, keys, sizeof(float3)*numkeys);
1135                         }
1136                 }
1137
1138                 return;
1139         }
1140
1141         /* TODO(sergey): Perform preliminary check for number of verticies. */
1142         if(numverts) {
1143                 /* find attributes */
1144                 Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1145                 Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
1146                 Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
1147                 bool new_attribute = false;
1148
1149                 /* add new attributes if they don't exist already */
1150                 if(!attr_mP) {
1151                         attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
1152                         if(attr_N)
1153                                 attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
1154
1155                         new_attribute = true;
1156                 }
1157
1158                 /* load vertex data from mesh */
1159                 float3 *mP = attr_mP->data_float3() + time_index*numverts;
1160                 float3 *mN = (attr_mN)? attr_mN->data_float3() + time_index*numverts: NULL;
1161
1162                 BL::Mesh::vertices_iterator v;
1163                 int i = 0;
1164
1165                 for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
1166                         mP[i] = get_float3(v->co());
1167                         if(mN)
1168                                 mN[i] = get_float3(v->normal());
1169                 }
1170
1171                 /* in case of new attribute, we verify if there really was any motion */
1172                 if(new_attribute) {
1173                         if(b_mesh.vertices.length() != numverts ||
1174                            memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0)
1175                         {
1176                                 /* no motion, remove attributes again */
1177                                 if(b_mesh.vertices.length() != numverts) {
1178                                         VLOG(1) << "Topology differs, disabling motion blur.";
1179                                 }
1180                                 else {
1181                                         VLOG(1) << "No actual deformation motion for object " << b_ob.name();
1182                                 }
1183                                 mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
1184                                 if(attr_mN)
1185                                         mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
1186                         }
1187                         else if(time_index > 0) {
1188                                 VLOG(1) << "Filling deformation motion for object " << b_ob.name();
1189                                 /* motion, fill up previous steps that we might have skipped because
1190                                  * they had no motion, but we need them anyway now */
1191                                 float3 *P = &mesh->verts[0];
1192                                 float3 *N = (attr_N)? attr_N->data_float3(): NULL;
1193
1194                                 for(int step = 0; step < time_index; step++) {
1195                                         memcpy(attr_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts);
1196                                         if(attr_mN)
1197                                                 memcpy(attr_mN->data_float3() + step*numverts, N, sizeof(float3)*numverts);
1198                                 }
1199                         }
1200                 }
1201         }
1202
1203         /* hair motion */
1204         if(numkeys)
1205                 sync_curves(mesh, b_mesh, b_ob, true, time_index);
1206
1207         /* free derived mesh */
1208         b_data.meshes.remove(b_mesh, false);
1209 }
1210
1211 CCL_NAMESPACE_END
1212