1 /*
2 * Copyright 2011-2013 Blender Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "render/camera.h"
18 #include "render/colorspace.h"
19 #include "render/mesh.h"
20 #include "render/object.h"
21 #include "render/scene.h"
22
23 #include "blender/blender_session.h"
24 #include "blender/blender_sync.h"
25 #include "blender/blender_util.h"
26
27 #include "subd/subd_patch.h"
28 #include "subd/subd_split.h"
29
30 #include "util/util_algorithm.h"
31 #include "util/util_disjoint_set.h"
32 #include "util/util_foreach.h"
33 #include "util/util_hash.h"
34 #include "util/util_logging.h"
35 #include "util/util_math.h"
36
37 #include "mikktspace.h"
38
39 CCL_NAMESPACE_BEGIN
40
41 /* Tangent Space */
42
43 struct MikkUserData {
MikkUserDataMikkUserData44 MikkUserData(const BL::Mesh &b_mesh,
45 const char *layer_name,
46 const Mesh *mesh,
47 float3 *tangent,
48 float *tangent_sign)
49 : mesh(mesh), texface(NULL), orco(NULL), tangent(tangent), tangent_sign(tangent_sign)
50 {
51 const AttributeSet &attributes = (mesh->subd_faces.size()) ? mesh->subd_attributes :
52 mesh->attributes;
53
54 Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
55 vertex_normal = attr_vN->data_float3();
56
57 if (layer_name == NULL) {
58 Attribute *attr_orco = attributes.find(ATTR_STD_GENERATED);
59
60 if (attr_orco) {
61 orco = attr_orco->data_float3();
62 mesh_texture_space(*(BL::Mesh *)&b_mesh, orco_loc, orco_size);
63 }
64 }
65 else {
66 Attribute *attr_uv = attributes.find(ustring(layer_name));
67 if (attr_uv != NULL) {
68 texface = attr_uv->data_float2();
69 }
70 }
71 }
72
73 const Mesh *mesh;
74 int num_faces;
75
76 float3 *vertex_normal;
77 float2 *texface;
78 float3 *orco;
79 float3 orco_loc, orco_size;
80
81 float3 *tangent;
82 float *tangent_sign;
83 };
84
mikk_get_num_faces(const SMikkTSpaceContext * context)85 static int mikk_get_num_faces(const SMikkTSpaceContext *context)
86 {
87 const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
88 if (userdata->mesh->subd_faces.size()) {
89 return userdata->mesh->subd_faces.size();
90 }
91 else {
92 return userdata->mesh->num_triangles();
93 }
94 }
95
mikk_get_num_verts_of_face(const SMikkTSpaceContext * context,const int face_num)96 static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num)
97 {
98 const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
99 if (userdata->mesh->subd_faces.size()) {
100 const Mesh *mesh = userdata->mesh;
101 return mesh->subd_faces[face_num].num_corners;
102 }
103 else {
104 return 3;
105 }
106 }
107
mikk_vertex_index(const Mesh * mesh,const int face_num,const int vert_num)108 static int mikk_vertex_index(const Mesh *mesh, const int face_num, const int vert_num)
109 {
110 if (mesh->subd_faces.size()) {
111 const Mesh::SubdFace &face = mesh->subd_faces[face_num];
112 return mesh->subd_face_corners[face.start_corner + vert_num];
113 }
114 else {
115 return mesh->triangles[face_num * 3 + vert_num];
116 }
117 }
118
mikk_corner_index(const Mesh * mesh,const int face_num,const int vert_num)119 static int mikk_corner_index(const Mesh *mesh, const int face_num, const int vert_num)
120 {
121 if (mesh->subd_faces.size()) {
122 const Mesh::SubdFace &face = mesh->subd_faces[face_num];
123 return face.start_corner + vert_num;
124 }
125 else {
126 return face_num * 3 + vert_num;
127 }
128 }
129
mikk_get_position(const SMikkTSpaceContext * context,float P[3],const int face_num,const int vert_num)130 static void mikk_get_position(const SMikkTSpaceContext *context,
131 float P[3],
132 const int face_num,
133 const int vert_num)
134 {
135 const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
136 const Mesh *mesh = userdata->mesh;
137 const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
138 const float3 vP = mesh->verts[vertex_index];
139 P[0] = vP.x;
140 P[1] = vP.y;
141 P[2] = vP.z;
142 }
143
mikk_get_texture_coordinate(const SMikkTSpaceContext * context,float uv[2],const int face_num,const int vert_num)144 static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context,
145 float uv[2],
146 const int face_num,
147 const int vert_num)
148 {
149 const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
150 const Mesh *mesh = userdata->mesh;
151 if (userdata->texface != NULL) {
152 const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
153 float2 tfuv = userdata->texface[corner_index];
154 uv[0] = tfuv.x;
155 uv[1] = tfuv.y;
156 }
157 else if (userdata->orco != NULL) {
158 const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
159 const float3 orco_loc = userdata->orco_loc;
160 const float3 orco_size = userdata->orco_size;
161 const float3 orco = (userdata->orco[vertex_index] + orco_loc) / orco_size;
162
163 const float2 tmp = map_to_sphere(orco);
164 uv[0] = tmp.x;
165 uv[1] = tmp.y;
166 }
167 else {
168 uv[0] = 0.0f;
169 uv[1] = 0.0f;
170 }
171 }
172
mikk_get_normal(const SMikkTSpaceContext * context,float N[3],const int face_num,const int vert_num)173 static void mikk_get_normal(const SMikkTSpaceContext *context,
174 float N[3],
175 const int face_num,
176 const int vert_num)
177 {
178 const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
179 const Mesh *mesh = userdata->mesh;
180 float3 vN;
181 if (mesh->subd_faces.size()) {
182 const Mesh::SubdFace &face = mesh->subd_faces[face_num];
183 if (face.smooth) {
184 const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
185 vN = userdata->vertex_normal[vertex_index];
186 }
187 else {
188 vN = face.normal(mesh);
189 }
190 }
191 else {
192 if (mesh->smooth[face_num]) {
193 const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
194 vN = userdata->vertex_normal[vertex_index];
195 }
196 else {
197 const Mesh::Triangle tri = mesh->get_triangle(face_num);
198 vN = tri.compute_normal(&mesh->verts[0]);
199 }
200 }
201 N[0] = vN.x;
202 N[1] = vN.y;
203 N[2] = vN.z;
204 }
205
mikk_set_tangent_space(const SMikkTSpaceContext * context,const float T[],const float sign,const int face_num,const int vert_num)206 static void mikk_set_tangent_space(const SMikkTSpaceContext *context,
207 const float T[],
208 const float sign,
209 const int face_num,
210 const int vert_num)
211 {
212 MikkUserData *userdata = (MikkUserData *)context->m_pUserData;
213 const Mesh *mesh = userdata->mesh;
214 const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
215 userdata->tangent[corner_index] = make_float3(T[0], T[1], T[2]);
216 if (userdata->tangent_sign != NULL) {
217 userdata->tangent_sign[corner_index] = sign;
218 }
219 }
220
mikk_compute_tangents(const BL::Mesh & b_mesh,const char * layer_name,Mesh * mesh,bool need_sign,bool active_render)221 static void mikk_compute_tangents(
222 const BL::Mesh &b_mesh, const char *layer_name, Mesh *mesh, bool need_sign, bool active_render)
223 {
224 /* Create tangent attributes. */
225 AttributeSet &attributes = (mesh->subd_faces.size()) ? mesh->subd_attributes : mesh->attributes;
226 Attribute *attr;
227 ustring name;
228 if (layer_name != NULL) {
229 name = ustring((string(layer_name) + ".tangent").c_str());
230 }
231 else {
232 name = ustring("orco.tangent");
233 }
234 if (active_render) {
235 attr = attributes.add(ATTR_STD_UV_TANGENT, name);
236 }
237 else {
238 attr = attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
239 }
240 float3 *tangent = attr->data_float3();
241 /* Create bitangent sign attribute. */
242 float *tangent_sign = NULL;
243 if (need_sign) {
244 Attribute *attr_sign;
245 ustring name_sign;
246 if (layer_name != NULL) {
247 name_sign = ustring((string(layer_name) + ".tangent_sign").c_str());
248 }
249 else {
250 name_sign = ustring("orco.tangent_sign");
251 }
252
253 if (active_render) {
254 attr_sign = attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
255 }
256 else {
257 attr_sign = attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
258 }
259 tangent_sign = attr_sign->data_float();
260 }
261 /* Setup userdata. */
262 MikkUserData userdata(b_mesh, layer_name, mesh, tangent, tangent_sign);
263 /* Setup interface. */
264 SMikkTSpaceInterface sm_interface;
265 memset(&sm_interface, 0, sizeof(sm_interface));
266 sm_interface.m_getNumFaces = mikk_get_num_faces;
267 sm_interface.m_getNumVerticesOfFace = mikk_get_num_verts_of_face;
268 sm_interface.m_getPosition = mikk_get_position;
269 sm_interface.m_getTexCoord = mikk_get_texture_coordinate;
270 sm_interface.m_getNormal = mikk_get_normal;
271 sm_interface.m_setTSpaceBasic = mikk_set_tangent_space;
272 /* Setup context. */
273 SMikkTSpaceContext context;
274 memset(&context, 0, sizeof(context));
275 context.m_pUserData = &userdata;
276 context.m_pInterface = &sm_interface;
277 /* Compute tangents. */
278 genTangSpaceDefault(&context);
279 }
280
281 /* Create sculpt vertex color attributes. */
attr_create_sculpt_vertex_color(Scene * scene,Mesh * mesh,BL::Mesh & b_mesh,bool subdivision)282 static void attr_create_sculpt_vertex_color(Scene *scene,
283 Mesh *mesh,
284 BL::Mesh &b_mesh,
285 bool subdivision)
286 {
287 BL::Mesh::sculpt_vertex_colors_iterator l;
288
289 for (b_mesh.sculpt_vertex_colors.begin(l); l != b_mesh.sculpt_vertex_colors.end(); ++l) {
290 const bool active_render = l->active_render();
291 AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
292 ustring vcol_name = ustring(l->name().c_str());
293
294 const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
295 mesh->need_attribute(scene, vcol_std);
296
297 if (!need_vcol) {
298 continue;
299 }
300
301 AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
302 Attribute *vcol_attr = attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_VERTEX);
303 vcol_attr->std = vcol_std;
304
305 float4 *cdata = vcol_attr->data_float4();
306 int numverts = b_mesh.vertices.length();
307
308 for (int i = 0; i < numverts; i++) {
309 *(cdata++) = get_float4(l->data[i].color());
310 }
311 }
312 }
313
314 /* Create vertex color attributes. */
attr_create_vertex_color(Scene * scene,Mesh * mesh,BL::Mesh & b_mesh,bool subdivision)315 static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
316 {
317 BL::Mesh::vertex_colors_iterator l;
318
319 for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
320 const bool active_render = l->active_render();
321 AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
322 ustring vcol_name = ustring(l->name().c_str());
323
324 const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
325 mesh->need_attribute(scene, vcol_std);
326
327 if (!need_vcol) {
328 continue;
329 }
330
331 Attribute *vcol_attr = NULL;
332
333 if (subdivision) {
334 if (active_render) {
335 vcol_attr = mesh->subd_attributes.add(vcol_std, vcol_name);
336 }
337 else {
338 vcol_attr = mesh->subd_attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
339 }
340
341 BL::Mesh::polygons_iterator p;
342 uchar4 *cdata = vcol_attr->data_uchar4();
343
344 for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
345 int n = p->loop_total();
346 for (int i = 0; i < n; i++) {
347 float4 color = get_float4(l->data[p->loop_start() + i].color());
348 /* Compress/encode vertex color using the sRGB curve. */
349 *(cdata++) = color_float4_to_uchar4(color);
350 }
351 }
352 }
353 else {
354 if (active_render) {
355 vcol_attr = mesh->attributes.add(vcol_std, vcol_name);
356 }
357 else {
358 vcol_attr = mesh->attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
359 }
360
361 BL::Mesh::loop_triangles_iterator t;
362 uchar4 *cdata = vcol_attr->data_uchar4();
363
364 for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
365 int3 li = get_int3(t->loops());
366 float4 c1 = get_float4(l->data[li[0]].color());
367 float4 c2 = get_float4(l->data[li[1]].color());
368 float4 c3 = get_float4(l->data[li[2]].color());
369
370 /* Compress/encode vertex color using the sRGB curve. */
371 cdata[0] = color_float4_to_uchar4(c1);
372 cdata[1] = color_float4_to_uchar4(c2);
373 cdata[2] = color_float4_to_uchar4(c3);
374
375 cdata += 3;
376 }
377 }
378 }
379 }
380
381 /* Create uv map attributes. */
attr_create_uv_map(Scene * scene,Mesh * mesh,BL::Mesh & b_mesh)382 static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
383 {
384 if (b_mesh.uv_layers.length() != 0) {
385 BL::Mesh::uv_layers_iterator l;
386
387 for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) {
388 const bool active_render = l->active_render();
389 AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
390 ustring uv_name = ustring(l->name().c_str());
391 AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
392 ustring tangent_name = ustring((string(l->name().c_str()) + ".tangent").c_str());
393
394 /* Denotes whether UV map was requested directly. */
395 const bool need_uv = mesh->need_attribute(scene, uv_name) ||
396 mesh->need_attribute(scene, uv_std);
397 /* Denotes whether tangent was requested directly. */
398 const bool need_tangent = mesh->need_attribute(scene, tangent_name) ||
399 (active_render && mesh->need_attribute(scene, tangent_std));
400
401 /* UV map */
402 /* NOTE: We create temporary UV layer if its needed for tangent but
403 * wasn't requested by other nodes in shaders.
404 */
405 Attribute *uv_attr = NULL;
406 if (need_uv || need_tangent) {
407 if (active_render) {
408 uv_attr = mesh->attributes.add(uv_std, uv_name);
409 }
410 else {
411 uv_attr = mesh->attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
412 }
413
414 BL::Mesh::loop_triangles_iterator t;
415 float2 *fdata = uv_attr->data_float2();
416
417 for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
418 int3 li = get_int3(t->loops());
419 fdata[0] = get_float2(l->data[li[0]].uv());
420 fdata[1] = get_float2(l->data[li[1]].uv());
421 fdata[2] = get_float2(l->data[li[2]].uv());
422 fdata += 3;
423 }
424 }
425
426 /* UV tangent */
427 if (need_tangent) {
428 AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
429 ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
430 bool need_sign = (mesh->need_attribute(scene, sign_name) ||
431 mesh->need_attribute(scene, sign_std));
432 mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render);
433 }
434 /* Remove temporarily created UV attribute. */
435 if (!need_uv && uv_attr != NULL) {
436 mesh->attributes.remove(uv_attr);
437 }
438 }
439 }
440 else if (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
441 bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
442 mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true);
443 if (!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
444 mesh->attributes.remove(ATTR_STD_GENERATED);
445 }
446 }
447 }
448
attr_create_subd_uv_map(Scene * scene,Mesh * mesh,BL::Mesh & b_mesh,bool subdivide_uvs)449 static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs)
450 {
451 if (b_mesh.uv_layers.length() != 0) {
452 BL::Mesh::uv_layers_iterator l;
453 int i = 0;
454
455 for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
456 bool active_render = l->active_render();
457 AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
458 ustring uv_name = ustring(l->name().c_str());
459 AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
460 ustring tangent_name = ustring((string(l->name().c_str()) + ".tangent").c_str());
461
462 /* Denotes whether UV map was requested directly. */
463 const bool need_uv = mesh->need_attribute(scene, uv_name) ||
464 mesh->need_attribute(scene, uv_std);
465 /* Denotes whether tangent was requested directly. */
466 const bool need_tangent = mesh->need_attribute(scene, tangent_name) ||
467 (active_render && mesh->need_attribute(scene, tangent_std));
468
469 Attribute *uv_attr = NULL;
470
471 /* UV map */
472 if (need_uv || need_tangent) {
473 if (active_render)
474 uv_attr = mesh->subd_attributes.add(uv_std, uv_name);
475 else
476 uv_attr = mesh->subd_attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
477
478 if (subdivide_uvs) {
479 uv_attr->flags |= ATTR_SUBDIVIDED;
480 }
481
482 BL::Mesh::polygons_iterator p;
483 float2 *fdata = uv_attr->data_float2();
484
485 for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
486 int n = p->loop_total();
487 for (int j = 0; j < n; j++) {
488 *(fdata++) = get_float2(l->data[p->loop_start() + j].uv());
489 }
490 }
491 }
492
493 /* UV tangent */
494 if (need_tangent) {
495 AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
496 ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
497 bool need_sign = (mesh->need_attribute(scene, sign_name) ||
498 mesh->need_attribute(scene, sign_std));
499 mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render);
500 }
501 /* Remove temporarily created UV attribute. */
502 if (!need_uv && uv_attr != NULL) {
503 mesh->subd_attributes.remove(uv_attr);
504 }
505 }
506 }
507 else if (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
508 bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
509 mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true);
510 if (!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
511 mesh->subd_attributes.remove(ATTR_STD_GENERATED);
512 }
513 }
514 }
515
516 /* Create vertex pointiness attributes. */
517
518 /* Compare vertices by sum of their coordinates. */
519 class VertexAverageComparator {
520 public:
VertexAverageComparator(const array<float3> & verts)521 VertexAverageComparator(const array<float3> &verts) : verts_(verts)
522 {
523 }
524
operator ()(const int & vert_idx_a,const int & vert_idx_b)525 bool operator()(const int &vert_idx_a, const int &vert_idx_b)
526 {
527 const float3 &vert_a = verts_[vert_idx_a];
528 const float3 &vert_b = verts_[vert_idx_b];
529 if (vert_a == vert_b) {
530 /* Special case for doubles, so we ensure ordering. */
531 return vert_idx_a > vert_idx_b;
532 }
533 const float x1 = vert_a.x + vert_a.y + vert_a.z;
534 const float x2 = vert_b.x + vert_b.y + vert_b.z;
535 return x1 < x2;
536 }
537
538 protected:
539 const array<float3> &verts_;
540 };
541
attr_create_pointiness(Scene * scene,Mesh * mesh,BL::Mesh & b_mesh,bool subdivision)542 static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
543 {
544 if (!mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
545 return;
546 }
547 const int num_verts = b_mesh.vertices.length();
548 if (num_verts == 0) {
549 return;
550 }
551 /* STEP 1: Find out duplicated vertices and point duplicates to a single
552 * original vertex.
553 */
554 vector<int> sorted_vert_indeices(num_verts);
555 for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
556 sorted_vert_indeices[vert_index] = vert_index;
557 }
558 VertexAverageComparator compare(mesh->verts);
559 sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare);
560 /* This array stores index of the original vertex for the given vertex
561 * index.
562 */
563 vector<int> vert_orig_index(num_verts);
564 for (int sorted_vert_index = 0; sorted_vert_index < num_verts; ++sorted_vert_index) {
565 const int vert_index = sorted_vert_indeices[sorted_vert_index];
566 const float3 &vert_co = mesh->verts[vert_index];
567 bool found = false;
568 for (int other_sorted_vert_index = sorted_vert_index + 1; other_sorted_vert_index < num_verts;
569 ++other_sorted_vert_index) {
570 const int other_vert_index = sorted_vert_indeices[other_sorted_vert_index];
571 const float3 &other_vert_co = mesh->verts[other_vert_index];
572 /* We are too far away now, we wouldn't have duplicate. */
573 if ((other_vert_co.x + other_vert_co.y + other_vert_co.z) -
574 (vert_co.x + vert_co.y + vert_co.z) >
575 3 * FLT_EPSILON) {
576 break;
577 }
578 /* Found duplicate. */
579 if (len_squared(other_vert_co - vert_co) < FLT_EPSILON) {
580 found = true;
581 vert_orig_index[vert_index] = other_vert_index;
582 break;
583 }
584 }
585 if (!found) {
586 vert_orig_index[vert_index] = vert_index;
587 }
588 }
589 /* Make sure we always points to the very first orig vertex. */
590 for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
591 int orig_index = vert_orig_index[vert_index];
592 while (orig_index != vert_orig_index[orig_index]) {
593 orig_index = vert_orig_index[orig_index];
594 }
595 vert_orig_index[vert_index] = orig_index;
596 }
597 sorted_vert_indeices.free_memory();
598 /* STEP 2: Calculate vertex normals taking into account their possible
599 * duplicates which gets "welded" together.
600 */
601 vector<float3> vert_normal(num_verts, make_float3(0.0f, 0.0f, 0.0f));
602 /* First we accumulate all vertex normals in the original index. */
603 for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
604 const float3 normal = get_float3(b_mesh.vertices[vert_index].normal());
605 const int orig_index = vert_orig_index[vert_index];
606 vert_normal[orig_index] += normal;
607 }
608 /* Then we normalize the accumulated result and flush it to all duplicates
609 * as well.
610 */
611 for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
612 const int orig_index = vert_orig_index[vert_index];
613 vert_normal[vert_index] = normalize(vert_normal[orig_index]);
614 }
615 /* STEP 3: Calculate pointiness using single ring neighborhood. */
616 vector<int> counter(num_verts, 0);
617 vector<float> raw_data(num_verts, 0.0f);
618 vector<float3> edge_accum(num_verts, make_float3(0.0f, 0.0f, 0.0f));
619 BL::Mesh::edges_iterator e;
620 EdgeMap visited_edges;
621 int edge_index = 0;
622 memset(&counter[0], 0, sizeof(int) * counter.size());
623 for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
624 const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
625 v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
626 if (visited_edges.exists(v0, v1)) {
627 continue;
628 }
629 visited_edges.insert(v0, v1);
630 float3 co0 = get_float3(b_mesh.vertices[v0].co()), co1 = get_float3(b_mesh.vertices[v1].co());
631 float3 edge = normalize(co1 - co0);
632 edge_accum[v0] += edge;
633 edge_accum[v1] += -edge;
634 ++counter[v0];
635 ++counter[v1];
636 }
637 for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
638 const int orig_index = vert_orig_index[vert_index];
639 if (orig_index != vert_index) {
640 /* Skip duplicates, they'll be overwritten later on. */
641 continue;
642 }
643 if (counter[vert_index] > 0) {
644 const float3 normal = vert_normal[vert_index];
645 const float angle = safe_acosf(dot(normal, edge_accum[vert_index] / counter[vert_index]));
646 raw_data[vert_index] = angle * M_1_PI_F;
647 }
648 else {
649 raw_data[vert_index] = 0.0f;
650 }
651 }
652 /* STEP 3: Blur vertices to approximate 2 ring neighborhood. */
653 AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
654 Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
655 float *data = attr->data_float();
656 memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
657 memset(&counter[0], 0, sizeof(int) * counter.size());
658 edge_index = 0;
659 visited_edges.clear();
660 for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
661 const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
662 v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
663 if (visited_edges.exists(v0, v1)) {
664 continue;
665 }
666 visited_edges.insert(v0, v1);
667 data[v0] += raw_data[v1];
668 data[v1] += raw_data[v0];
669 ++counter[v0];
670 ++counter[v1];
671 }
672 for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
673 data[vert_index] /= counter[vert_index] + 1;
674 }
675 /* STEP 4: Copy attribute to the duplicated vertices. */
676 for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
677 const int orig_index = vert_orig_index[vert_index];
678 data[vert_index] = data[orig_index];
679 }
680 }
681
682 /* The Random Per Island attribute is a random float associated with each
683 * connected component (island) of the mesh. The attribute is computed by
684 * first classifying the vertices into different sets using a Disjoint Set
685 * data structure. Then the index of the root of each vertex (Which is the
686 * representative of the set the vertex belongs to) is hashed and stored.
687 *
688 * We are using a face attribute to avoid interpolation during rendering,
689 * allowing the user to safely hash the output further. Had we used vertex
690 * attribute, the interpolation will introduce very slight variations,
691 * making the output unsafe to hash. */
attr_create_random_per_island(Scene * scene,Mesh * mesh,BL::Mesh & b_mesh,bool subdivision)692 static void attr_create_random_per_island(Scene *scene,
693 Mesh *mesh,
694 BL::Mesh &b_mesh,
695 bool subdivision)
696 {
697 if (!mesh->need_attribute(scene, ATTR_STD_RANDOM_PER_ISLAND)) {
698 return;
699 }
700
701 int number_of_vertices = b_mesh.vertices.length();
702 if (number_of_vertices == 0) {
703 return;
704 }
705
706 DisjointSet vertices_sets(number_of_vertices);
707
708 BL::Mesh::edges_iterator e;
709 for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
710 vertices_sets.join(e->vertices()[0], e->vertices()[1]);
711 }
712
713 AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
714 Attribute *attribute = attributes.add(ATTR_STD_RANDOM_PER_ISLAND);
715 float *data = attribute->data_float();
716
717 if (!subdivision) {
718 BL::Mesh::loop_triangles_iterator t;
719 for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
720 data[t->index()] = hash_uint_to_float(vertices_sets.find(t->vertices()[0]));
721 }
722 }
723 else {
724 BL::Mesh::polygons_iterator p;
725 for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
726 data[p->index()] = hash_uint_to_float(vertices_sets.find(p->vertices()[0]));
727 }
728 }
729 }
730
731 /* Create Mesh */
732
create_mesh(Scene * scene,Mesh * mesh,BL::Mesh & b_mesh,const vector<Shader * > & used_shaders,bool subdivision=false,bool subdivide_uvs=true)733 static void create_mesh(Scene *scene,
734 Mesh *mesh,
735 BL::Mesh &b_mesh,
736 const vector<Shader *> &used_shaders,
737 bool subdivision = false,
738 bool subdivide_uvs = true)
739 {
740 /* count vertices and faces */
741 int numverts = b_mesh.vertices.length();
742 int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
743 int numtris = 0;
744 int numcorners = 0;
745 int numngons = 0;
746 bool use_loop_normals = b_mesh.use_auto_smooth() &&
747 (mesh->subdivision_type != Mesh::SUBDIVISION_CATMULL_CLARK);
748
749 /* If no faces, create empty mesh. */
750 if (numfaces == 0) {
751 return;
752 }
753
754 if (!subdivision) {
755 numtris = numfaces;
756 }
757 else {
758 BL::Mesh::polygons_iterator p;
759 for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
760 numngons += (p->loop_total() == 4) ? 0 : 1;
761 numcorners += p->loop_total();
762 }
763 }
764
765 /* allocate memory */
766 mesh->reserve_mesh(numverts, numtris);
767 mesh->reserve_subd_faces(numfaces, numngons, numcorners);
768
769 /* create vertex coordinates and normals */
770 BL::Mesh::vertices_iterator v;
771 for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
772 mesh->add_vertex(get_float3(v->co()));
773
774 AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
775 Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL);
776 float3 *N = attr_N->data_float3();
777
778 for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
779 *N = get_float3(v->normal());
780 N = attr_N->data_float3();
781
782 /* create generated coordinates from undeformed coordinates */
783 const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.length() == 0) &&
784 (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT));
785 if (mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_default_tangent) {
786 Attribute *attr = attributes.add(ATTR_STD_GENERATED);
787 attr->flags |= ATTR_SUBDIVIDED;
788
789 float3 loc, size;
790 mesh_texture_space(b_mesh, loc, size);
791
792 float3 *generated = attr->data_float3();
793 size_t i = 0;
794
795 for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) {
796 generated[i++] = get_float3(v->undeformed_co()) * size - loc;
797 }
798 }
799
800 /* create faces */
801 if (!subdivision) {
802 BL::Mesh::loop_triangles_iterator t;
803
804 for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
805 BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()];
806 int3 vi = get_int3(t->vertices());
807
808 int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
809 bool smooth = p.use_smooth() || use_loop_normals;
810
811 if (use_loop_normals) {
812 BL::Array<float, 9> loop_normals = t->split_normals();
813 for (int i = 0; i < 3; i++) {
814 N[vi[i]] = make_float3(
815 loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
816 }
817 }
818
819 /* Create triangles.
820 *
821 * NOTE: Autosmooth is already taken care about.
822 */
823 mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
824 }
825 }
826 else {
827 BL::Mesh::polygons_iterator p;
828 vector<int> vi;
829
830 for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
831 int n = p->loop_total();
832 int shader = clamp(p->material_index(), 0, used_shaders.size() - 1);
833 bool smooth = p->use_smooth() || use_loop_normals;
834
835 vi.resize(n);
836 for (int i = 0; i < n; i++) {
837 /* NOTE: Autosmooth is already taken care about. */
838 vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
839 }
840
841 /* create subd faces */
842 mesh->add_subd_face(&vi[0], n, shader, smooth);
843 }
844 }
845
846 /* Create all needed attributes.
847 * The calculate functions will check whether they're needed or not.
848 */
849 attr_create_pointiness(scene, mesh, b_mesh, subdivision);
850 attr_create_vertex_color(scene, mesh, b_mesh, subdivision);
851 attr_create_sculpt_vertex_color(scene, mesh, b_mesh, subdivision);
852 attr_create_random_per_island(scene, mesh, b_mesh, subdivision);
853
854 if (subdivision) {
855 attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs);
856 }
857 else {
858 attr_create_uv_map(scene, mesh, b_mesh);
859 }
860
861 /* For volume objects, create a matrix to transform from object space to
862 * mesh texture space. this does not work with deformations but that can
863 * probably only be done well with a volume grid mapping of coordinates. */
864 if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
865 Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
866 Transform *tfm = attr->data_transform();
867
868 float3 loc, size;
869 mesh_texture_space(b_mesh, loc, size);
870
871 *tfm = transform_translate(-loc) * transform_scale(size);
872 }
873 }
874
create_subd_mesh(Scene * scene,Mesh * mesh,BL::Object & b_ob,BL::Mesh & b_mesh,const vector<Shader * > & used_shaders,float dicing_rate,int max_subdivisions)875 static void create_subd_mesh(Scene *scene,
876 Mesh *mesh,
877 BL::Object &b_ob,
878 BL::Mesh &b_mesh,
879 const vector<Shader *> &used_shaders,
880 float dicing_rate,
881 int max_subdivisions)
882 {
883 BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length() - 1]);
884 bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE;
885
886 create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
887
888 /* export creases */
889 size_t num_creases = 0;
890 BL::Mesh::edges_iterator e;
891
892 for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
893 if (e->crease() != 0.0f) {
894 num_creases++;
895 }
896 }
897
898 mesh->subd_creases.resize(num_creases);
899
900 Mesh::SubdEdgeCrease *crease = mesh->subd_creases.data();
901 for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
902 if (e->crease() != 0.0f) {
903 crease->v[0] = e->vertices()[0];
904 crease->v[1] = e->vertices()[1];
905 crease->crease = e->crease();
906
907 crease++;
908 }
909 }
910
911 /* set subd params */
912 if (!mesh->subd_params) {
913 mesh->subd_params = new SubdParams(mesh);
914 }
915 SubdParams &sdparams = *mesh->subd_params;
916
917 PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
918
919 sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
920 sdparams.max_level = max_subdivisions;
921
922 sdparams.objecttoworld = get_transform(b_ob.matrix_world());
923 }
924
925 /* Sync */
926
object_mesh_cache_find(BL::Object & b_ob)927 static BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b_ob)
928 {
929 if (b_ob.modifiers.length() > 0) {
930 BL::Modifier b_mod = b_ob.modifiers[b_ob.modifiers.length() - 1];
931
932 if (b_mod.type() == BL::Modifier::type_MESH_SEQUENCE_CACHE) {
933 BL::MeshSequenceCacheModifier mesh_cache = BL::MeshSequenceCacheModifier(b_mod);
934
935 if (MeshSequenceCacheModifier_has_velocity_get(&mesh_cache.ptr)) {
936 return mesh_cache;
937 }
938 }
939 }
940
941 return BL::MeshSequenceCacheModifier(PointerRNA_NULL);
942 }
943
sync_mesh_cached_velocities(BL::Object & b_ob,Scene * scene,Mesh * mesh)944 static void sync_mesh_cached_velocities(BL::Object &b_ob, Scene *scene, Mesh *mesh)
945 {
946 if (scene->need_motion() == Scene::MOTION_NONE)
947 return;
948
949 BL::MeshSequenceCacheModifier b_mesh_cache = object_mesh_cache_find(b_ob);
950
951 if (!b_mesh_cache) {
952 return;
953 }
954
955 if (!MeshSequenceCacheModifier_read_velocity_get(&b_mesh_cache.ptr)) {
956 return;
957 }
958
959 const size_t numverts = mesh->verts.size();
960
961 if (b_mesh_cache.vertex_velocities.length() != numverts) {
962 return;
963 }
964
965 /* Find or add attribute */
966 float3 *P = &mesh->verts[0];
967 Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
968
969 if (!attr_mP) {
970 attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
971 }
972
973 /* Only export previous and next frame, we don't have any in between data. */
974 float motion_times[2] = {-1.0f, 1.0f};
975 for (int step = 0; step < 2; step++) {
976 const float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
977 float3 *mP = attr_mP->data_float3() + step * numverts;
978
979 BL::MeshSequenceCacheModifier::vertex_velocities_iterator vvi;
980 int i = 0;
981
982 for (b_mesh_cache.vertex_velocities.begin(vvi); vvi != b_mesh_cache.vertex_velocities.end();
983 ++vvi, ++i) {
984 mP[i] = P[i] + get_float3(vvi->velocity()) * relative_time;
985 }
986 }
987 }
988
sync_mesh_fluid_motion(BL::Object & b_ob,Scene * scene,Mesh * mesh)989 static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh)
990 {
991 if (scene->need_motion() == Scene::MOTION_NONE)
992 return;
993
994 BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob);
995
996 if (!b_fluid_domain)
997 return;
998
999 /* If the mesh has modifiers following the fluid domain we can't export motion. */
1000 if (b_fluid_domain.mesh_vertices.length() != mesh->verts.size())
1001 return;
1002
1003 /* Find or add attribute */
1004 float3 *P = &mesh->verts[0];
1005 Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1006
1007 if (!attr_mP) {
1008 attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
1009 }
1010
1011 /* Only export previous and next frame, we don't have any in between data. */
1012 float motion_times[2] = {-1.0f, 1.0f};
1013 for (int step = 0; step < 2; step++) {
1014 float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
1015 float3 *mP = attr_mP->data_float3() + step * mesh->verts.size();
1016
1017 BL::FluidDomainSettings::mesh_vertices_iterator svi;
1018 int i = 0;
1019
1020 for (b_fluid_domain.mesh_vertices.begin(svi); svi != b_fluid_domain.mesh_vertices.end();
1021 ++svi, ++i) {
1022 mP[i] = P[i] + get_float3(svi->velocity()) * relative_time;
1023 }
1024 }
1025 }
1026
sync_mesh(BL::Depsgraph b_depsgraph,BL::Object b_ob,Mesh * mesh,const vector<Shader * > & used_shaders)1027 void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph,
1028 BL::Object b_ob,
1029 Mesh *mesh,
1030 const vector<Shader *> &used_shaders)
1031 {
1032 array<int> oldtriangles;
1033 array<Mesh::SubdFace> oldsubd_faces;
1034 array<int> oldsubd_face_corners;
1035 oldtriangles.steal_data(mesh->triangles);
1036 oldsubd_faces.steal_data(mesh->subd_faces);
1037 oldsubd_face_corners.steal_data(mesh->subd_face_corners);
1038
1039 mesh->clear();
1040 mesh->used_shaders = used_shaders;
1041
1042 mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
1043
1044 if (view_layer.use_surfaces) {
1045 /* Adaptive subdivision setup. Not for baking since that requires
1046 * exact mapping to the Blender mesh. */
1047 if (!scene->bake_manager->get_baking()) {
1048 mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental);
1049 }
1050
1051 /* For some reason, meshes do not need this... */
1052 bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
1053 BL::Mesh b_mesh = object_to_mesh(
1054 b_data, b_ob, b_depsgraph, need_undeformed, mesh->subdivision_type);
1055
1056 if (b_mesh) {
1057 /* Sync mesh itself. */
1058 if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
1059 create_subd_mesh(
1060 scene, mesh, b_ob, b_mesh, mesh->used_shaders, dicing_rate, max_subdivisions);
1061 else
1062 create_mesh(scene, mesh, b_mesh, mesh->used_shaders, false);
1063
1064 free_object_to_mesh(b_data, b_ob, b_mesh);
1065 }
1066 }
1067
1068 /* cached velocities (e.g. from alembic archive) */
1069 sync_mesh_cached_velocities(b_ob, scene, mesh);
1070
1071 /* mesh fluid motion mantaflow */
1072 sync_mesh_fluid_motion(b_ob, scene, mesh);
1073
1074 /* tag update */
1075 bool rebuild = (oldtriangles != mesh->triangles) || (oldsubd_faces != mesh->subd_faces) ||
1076 (oldsubd_face_corners != mesh->subd_face_corners);
1077
1078 mesh->tag_update(scene, rebuild);
1079 }
1080
sync_mesh_motion(BL::Depsgraph b_depsgraph,BL::Object b_ob,Mesh * mesh,int motion_step)1081 void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
1082 BL::Object b_ob,
1083 Mesh *mesh,
1084 int motion_step)
1085 {
1086 /* Fluid motion blur already exported. */
1087 BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob);
1088 if (b_fluid_domain) {
1089 return;
1090 }
1091
1092 /* Cached motion blur already exported. */
1093 BL::MeshSequenceCacheModifier mesh_cache = object_mesh_cache_find(b_ob);
1094 if (mesh_cache) {
1095 return;
1096 }
1097
1098 /* Skip if no vertices were exported. */
1099 size_t numverts = mesh->verts.size();
1100 if (numverts == 0) {
1101 return;
1102 }
1103
1104 /* Skip objects without deforming modifiers. this is not totally reliable,
1105 * would need a more extensive check to see which objects are animated. */
1106 BL::Mesh b_mesh(PointerRNA_NULL);
1107 if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
1108 /* get derived mesh */
1109 b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
1110 }
1111
1112 /* TODO(sergey): Perform preliminary check for number of vertices. */
1113 if (b_mesh) {
1114 /* Export deformed coordinates. */
1115 /* Find attributes. */
1116 Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
1117 Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
1118 Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
1119 bool new_attribute = false;
1120 /* Add new attributes if they don't exist already. */
1121 if (!attr_mP) {
1122 attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
1123 if (attr_N)
1124 attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
1125
1126 new_attribute = true;
1127 }
1128 /* Load vertex data from mesh. */
1129 float3 *mP = attr_mP->data_float3() + motion_step * numverts;
1130 float3 *mN = (attr_mN) ? attr_mN->data_float3() + motion_step * numverts : NULL;
1131 /* NOTE: We don't copy more that existing amount of vertices to prevent
1132 * possible memory corruption.
1133 */
1134 BL::Mesh::vertices_iterator v;
1135 int i = 0;
1136 for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
1137 mP[i] = get_float3(v->co());
1138 if (mN)
1139 mN[i] = get_float3(v->normal());
1140 }
1141 if (new_attribute) {
1142 /* In case of new attribute, we verify if there really was any motion. */
1143 if (b_mesh.vertices.length() != numverts ||
1144 memcmp(mP, &mesh->verts[0], sizeof(float3) * numverts) == 0) {
1145 /* no motion, remove attributes again */
1146 if (b_mesh.vertices.length() != numverts) {
1147 VLOG(1) << "Topology differs, disabling motion blur for object " << b_ob.name();
1148 }
1149 else {
1150 VLOG(1) << "No actual deformation motion for object " << b_ob.name();
1151 }
1152 mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
1153 if (attr_mN)
1154 mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
1155 }
1156 else if (motion_step > 0) {
1157 VLOG(1) << "Filling deformation motion for object " << b_ob.name();
1158 /* motion, fill up previous steps that we might have skipped because
1159 * they had no motion, but we need them anyway now */
1160 float3 *P = &mesh->verts[0];
1161 float3 *N = (attr_N) ? attr_N->data_float3() : NULL;
1162 for (int step = 0; step < motion_step; step++) {
1163 memcpy(attr_mP->data_float3() + step * numverts, P, sizeof(float3) * numverts);
1164 if (attr_mN)
1165 memcpy(attr_mN->data_float3() + step * numverts, N, sizeof(float3) * numverts);
1166 }
1167 }
1168 }
1169 else {
1170 if (b_mesh.vertices.length() != numverts) {
1171 VLOG(1) << "Topology differs, discarding motion blur for object " << b_ob.name()
1172 << " at time " << motion_step;
1173 memcpy(mP, &mesh->verts[0], sizeof(float3) * numverts);
1174 if (mN != NULL) {
1175 memcpy(mN, attr_N->data_float3(), sizeof(float3) * numverts);
1176 }
1177 }
1178 }
1179
1180 free_object_to_mesh(b_data, b_ob, b_mesh);
1181 return;
1182 }
1183
1184 /* No deformation on this frame, copy coordinates if other frames did have it. */
1185 mesh->copy_center_to_motion_step(motion_step);
1186 }
1187
1188 CCL_NAMESPACE_END
1189