6dc26c2981b493c866a89efa493d8ace6e6898a0
[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         SubdParams sdparams(mesh);
810
811         PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
812
813         sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
814         sdparams.max_level = max_subdivisions;
815
816         scene->camera->update();
817         sdparams.camera = scene->camera;
818         sdparams.objecttoworld = get_transform(b_ob.matrix_world());
819
820         /* tesselate */
821         DiagSplit dsplit(sdparams);
822         mesh->tessellate(&dsplit);
823 }
824
825 /* Sync */
826
827 static void sync_mesh_fluid_motion(BL::Object& b_ob, Scene *scene, Mesh *mesh)
828 {
829         if(scene->need_motion() == Scene::MOTION_NONE)
830                 return;
831
832         BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
833
834         if(!b_fluid_domain)
835                 return;
836
837         /* If the mesh has modifiers following the fluid domain we can't export motion. */
838         if(b_fluid_domain.fluid_mesh_vertices.length() != mesh->verts.size())
839                 return;
840
841         /* Find or add attribute */
842         float3 *P = &mesh->verts[0];
843         Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
844
845         if(!attr_mP) {
846                 attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
847         }
848
849         /* Only export previous and next frame, we don't have any in between data. */
850         float motion_times[2] = {-1.0f, 1.0f};
851         for (int step = 0; step < 2; step++) {
852                 float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
853                 float3 *mP = attr_mP->data_float3() + step*mesh->verts.size();
854
855                 BL::DomainFluidSettings::fluid_mesh_vertices_iterator fvi;
856                 int i = 0;
857
858                 for(b_fluid_domain.fluid_mesh_vertices.begin(fvi); fvi != b_fluid_domain.fluid_mesh_vertices.end(); ++fvi, ++i) {
859                         mP[i] = P[i] + get_float3(fvi->velocity()) * relative_time;
860                 }
861         }
862 }
863
864 Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
865                              bool object_updated,
866                              bool hide_tris)
867 {
868         /* When viewport display is not needed during render we can force some
869          * caches to be releases from blender side in order to reduce peak memory
870          * footprint during synchronization process.
871          */
872         const bool is_interface_locked = b_engine.render() &&
873                                          b_engine.render().use_lock_interface();
874         const bool can_free_caches = BlenderSession::headless || is_interface_locked;
875
876         /* test if we can instance or if the object is modified */
877         BL::ID b_ob_data = b_ob.data();
878         BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob_data;
879         BL::Material material_override = render_layer.material_override;
880
881         /* find shader indices */
882         vector<Shader*> used_shaders;
883
884         BL::Object::material_slots_iterator slot;
885         for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
886                 if(material_override) {
887                         find_shader(material_override, used_shaders, scene->default_surface);
888                 }
889                 else {
890                         BL::ID b_material(slot->material());
891                         find_shader(b_material, used_shaders, scene->default_surface);
892                 }
893         }
894
895         if(used_shaders.size() == 0) {
896                 if(material_override)
897                         find_shader(material_override, used_shaders, scene->default_surface);
898                 else
899                         used_shaders.push_back(scene->default_surface);
900         }
901         
902         /* test if we need to sync */
903         int requested_geometry_flags = Mesh::GEOMETRY_NONE;
904         if(render_layer.use_surfaces) {
905                 requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES;
906         }
907         if(render_layer.use_hair) {
908                 requested_geometry_flags |= Mesh::GEOMETRY_CURVES;
909         }
910         Mesh *mesh;
911
912         if(!mesh_map.sync(&mesh, key)) {
913                 /* if transform was applied to mesh, need full update */
914                 if(object_updated && mesh->transform_applied);
915                 /* test if shaders changed, these can be object level so mesh
916                  * does not get tagged for recalc */
917                 else if(mesh->used_shaders != used_shaders);
918                 else if(requested_geometry_flags != mesh->geometry_flags);
919                 else {
920                         /* even if not tagged for recalc, we may need to sync anyway
921                          * because the shader needs different mesh attributes */
922                         bool attribute_recalc = false;
923
924                         foreach(Shader *shader, mesh->used_shaders)
925                                 if(shader->need_update_attributes)
926                                         attribute_recalc = true;
927
928                         if(!attribute_recalc)
929                                 return mesh;
930                 }
931         }
932
933         /* ensure we only sync instanced meshes once */
934         if(mesh_synced.find(mesh) != mesh_synced.end())
935                 return mesh;
936         
937         mesh_synced.insert(mesh);
938
939         /* create derived mesh */
940         array<int> oldtriangle = mesh->triangles;
941         
942         /* compares curve_keys rather than strands in order to handle quick hair
943          * adjustments in dynamic BVH - other methods could probably do this better*/
944         array<float3> oldcurve_keys = mesh->curve_keys;
945         array<float> oldcurve_radius = mesh->curve_radius;
946
947         mesh->clear();
948         mesh->used_shaders = used_shaders;
949         mesh->name = ustring(b_ob_data.name().c_str());
950
951         if(requested_geometry_flags != Mesh::GEOMETRY_NONE) {
952                 /* mesh objects does have special handle in the dependency graph,
953                  * they're ensured to have properly updated.
954                  *
955                  * updating meshes here will end up having derived mesh referencing
956                  * freed data from the blender side.
957                  */
958                 if(preview && b_ob.type() != BL::Object::type_MESH)
959                         b_ob.update_from_editmode();
960
961                 bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
962
963                 mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
964
965                 PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
966
967                 if(cobj.data && b_ob.modifiers.length() > 0 && experimental) {
968                         BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length()-1];
969                         bool enabled = preview ? mod.show_viewport() : mod.show_render();
970
971                         if(enabled && mod.type() == BL::Modifier::type_SUBSURF && RNA_boolean_get(&cobj, "use_adaptive_subdivision")) {
972                                 BL::SubsurfModifier subsurf(mod);
973
974                                 if(subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
975                                         mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK;
976                                 }
977                                 else {
978                                         mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR;
979                                 }
980                         }
981                 }
982
983                 BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed, mesh->subdivision_type);
984
985                 if(b_mesh) {
986                         if(render_layer.use_surfaces && !hide_tris) {
987                                 if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
988                                         create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders,
989                                                          dicing_rate, max_subdivisions);
990                                 else
991                                         create_mesh(scene, mesh, b_mesh, used_shaders, false);
992
993                                 create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
994                         }
995
996                         if(render_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
997                                 sync_curves(mesh, b_mesh, b_ob, false);
998
999                         if(can_free_caches) {
1000                                 b_ob.cache_release();
1001                         }
1002
1003                         /* free derived mesh */
1004                         b_data.meshes.remove(b_mesh, false);
1005                 }
1006         }
1007         mesh->geometry_flags = requested_geometry_flags;
1008
1009         /* fluid motion */
1010         sync_mesh_fluid_motion(b_ob, scene, mesh);
1011
1012         /* tag update */
1013         bool rebuild = false;
1014
1015         if(oldtriangle.size() != mesh->triangles.size())
1016                 rebuild = true;
1017         else if(oldtriangle.size()) {
1018                 if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(int)*oldtriangle.size()) != 0)
1019                         rebuild = true;
1020         }
1021
1022         if(oldcurve_keys.size() != mesh->curve_keys.size())
1023                 rebuild = true;
1024         else if(oldcurve_keys.size()) {
1025                 if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(float3)*oldcurve_keys.size()) != 0)
1026                         rebuild = true;
1027         }
1028
1029         if(oldcurve_radius.size() != mesh->curve_radius.size())
1030                 rebuild = true;
1031         else if(oldcurve_radius.size()) {
1032                 if(memcmp(&oldcurve_radius[0], &mesh->curve_radius[0], sizeof(float)*oldcurve_radius.size()) != 0)
1033                         rebuild = true;
1034         }
1035         
1036         mesh->tag_update(scene, rebuild);
1037
1038         return mesh;
1039 }
1040
1041 void BlenderSync::sync_mesh_motion(BL::Object& b_ob,
1042                                    Object *object,
1043                                    float motion_time)
1044 {
1045         /* ensure we only sync instanced meshes once */
1046         Mesh *mesh = object->mesh;
1047
1048         if(mesh_motion_synced.find(mesh) != mesh_motion_synced.end())
1049                 return;
1050
1051         mesh_motion_synced.insert(mesh);
1052
1053         /* ensure we only motion sync meshes that also had mesh synced, to avoid
1054          * unnecessary work and to ensure that its attributes were clear */
1055         if(mesh_synced.find(mesh) == mesh_synced.end())
1056                 return;
1057
1058         /* for motion pass always compute, for motion blur it can be disabled */
1059         int time_index = 0;
1060
1061         if(scene->need_motion() == Scene::MOTION_BLUR) {
1062                 if(!mesh->use_motion_blur)
1063                         return;
1064                 
1065                 /* see if this mesh needs motion data at this time */
1066                 vector<float> object_times = object->motion_times();
1067                 bool found = false;
1068
1069                 foreach(float object_time, object_times) {
1070                         if(motion_time == object_time) {
1071                                 found = true;
1072                                 break;
1073                         }
1074                         else
1075                                 time_index++;
1076                 }
1077
1078                 if(!found)
1079                         return;
1080         }
1081         else {
1082                 if(motion_time == -1.0f)
1083                         time_index = 0;
1084                 else if(motion_time == 1.0f)
1085                         time_index = 1;
1086                 else
1087                         return;
1088         }
1089
1090         /* skip empty meshes */
1091         size_t numverts = mesh->verts.size();
1092         size_t numkeys = mesh->curve_keys.size();
1093
1094         if(!numverts && !numkeys)
1095                 return;
1096         
1097         /* skip objects without deforming modifiers. this is not totally reliable,
1098          * would need a more extensive check to see which objects are animated */
1099         BL::Mesh b_mesh(PointerRNA_NULL);
1100
1101         /* fluid motion is exported immediate with mesh, skip here */
1102         BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob);
1103         if (b_fluid_domain)
1104                 return;
1105
1106         if(ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
1107                 /* get derived mesh */
1108                 b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false, false);
1109         }
1110
1111         if(!b_mesh) {
1112                 /* if we have no motion blur on this frame, but on other frames, copy */
1113                 if(numverts) {
1114                         /* triangles */
1115                         Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1116
1117                         if(attr_mP) {
1118                                 Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
1119                                 Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
1120                                 float3 *P = &mesh->verts[0];
1121                                 float3 *N = (attr_N)? attr_N->data_float3(): NULL;
1122
1123                                 memcpy(attr_mP->data_float3() + time_index*numverts, P, sizeof(float3)*numverts);
1124                                 if(attr_mN)
1125                                         memcpy(attr_mN->data_float3() + time_index*numverts, N, sizeof(float3)*numverts);
1126                         }
1127                 }
1128
1129                 if(numkeys) {
1130                         /* curves */
1131                         Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1132
1133                         if(attr_mP) {
1134                                 float3 *keys = &mesh->curve_keys[0];
1135                                 memcpy(attr_mP->data_float3() + time_index*numkeys, keys, sizeof(float3)*numkeys);
1136                         }
1137                 }
1138
1139                 return;
1140         }
1141
1142         /* TODO(sergey): Perform preliminary check for number of verticies. */
1143         if(numverts) {
1144                 /* find attributes */
1145                 Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1146                 Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
1147                 Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
1148                 bool new_attribute = false;
1149
1150                 /* add new attributes if they don't exist already */
1151                 if(!attr_mP) {
1152                         attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
1153                         if(attr_N)
1154                                 attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
1155
1156                         new_attribute = true;
1157                 }
1158
1159                 /* load vertex data from mesh */
1160                 float3 *mP = attr_mP->data_float3() + time_index*numverts;
1161                 float3 *mN = (attr_mN)? attr_mN->data_float3() + time_index*numverts: NULL;
1162
1163                 BL::Mesh::vertices_iterator v;
1164                 int i = 0;
1165
1166                 for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
1167                         mP[i] = get_float3(v->co());
1168                         if(mN)
1169                                 mN[i] = get_float3(v->normal());
1170                 }
1171
1172                 /* in case of new attribute, we verify if there really was any motion */
1173                 if(new_attribute) {
1174                         if(b_mesh.vertices.length() != numverts ||
1175                            memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0)
1176                         {
1177                                 /* no motion, remove attributes again */
1178                                 if(b_mesh.vertices.length() != numverts) {
1179                                         VLOG(1) << "Topology differs, disabling motion blur.";
1180                                 }
1181                                 else {
1182                                         VLOG(1) << "No actual deformation motion for object " << b_ob.name();
1183                                 }
1184                                 mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
1185                                 if(attr_mN)
1186                                         mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
1187                         }
1188                         else if(time_index > 0) {
1189                                 VLOG(1) << "Filling deformation motion for object " << b_ob.name();
1190                                 /* motion, fill up previous steps that we might have skipped because
1191                                  * they had no motion, but we need them anyway now */
1192                                 float3 *P = &mesh->verts[0];
1193                                 float3 *N = (attr_N)? attr_N->data_float3(): NULL;
1194
1195                                 for(int step = 0; step < time_index; step++) {
1196                                         memcpy(attr_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts);
1197                                         if(attr_mN)
1198                                                 memcpy(attr_mN->data_float3() + step*numverts, N, sizeof(float3)*numverts);
1199                                 }
1200                         }
1201                 }
1202         }
1203
1204         /* hair motion */
1205         if(numkeys)
1206                 sync_curves(mesh, b_mesh, b_ob, true, time_index);
1207
1208         /* free derived mesh */
1209         b_data.meshes.remove(b_mesh, false);
1210 }
1211
1212 CCL_NAMESPACE_END
1213