Blender  V2.93
blender_mesh.cpp
Go to the documentation of this file.
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 
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 
40 
41 /* Tangent Space */
42 
43 struct MikkUserData {
44  MikkUserData(const BL::Mesh &b_mesh,
45  const char *layer_name,
46  const Mesh *mesh,
47  float3 *tangent,
48  float *tangent_sign)
50  {
51  const AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->subd_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();
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 
80 
82  float *tangent_sign;
83 };
84 
86 {
87  const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
88  if (userdata->mesh->get_num_subd_faces()) {
89  return userdata->mesh->get_num_subd_faces();
90  }
91  else {
92  return userdata->mesh->num_triangles();
93  }
94 }
95 
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->get_num_subd_faces()) {
100  const Mesh *mesh = userdata->mesh;
101  return mesh->get_subd_num_corners()[face_num];
102  }
103  else {
104  return 3;
105  }
106 }
107 
108 static int mikk_vertex_index(const Mesh *mesh, const int face_num, const int vert_num)
109 {
110  if (mesh->get_num_subd_faces()) {
111  const Mesh::SubdFace &face = mesh->get_subd_face(face_num);
112  return mesh->get_subd_face_corners()[face.start_corner + vert_num];
113  }
114  else {
115  return mesh->get_triangles()[face_num * 3 + vert_num];
116  }
117 }
118 
119 static int mikk_corner_index(const Mesh *mesh, const int face_num, const int vert_num)
120 {
121  if (mesh->get_num_subd_faces()) {
122  const Mesh::SubdFace &face = mesh->get_subd_face(face_num);
123  return face.start_corner + vert_num;
124  }
125  else {
126  return face_num * 3 + vert_num;
127  }
128 }
129 
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->get_verts()[vertex_index];
139  P[0] = vP.x;
140  P[1] = vP.y;
141  P[2] = vP.z;
142 }
143 
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 
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->get_num_subd_faces()) {
182  const Mesh::SubdFace &face = mesh->get_subd_face(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->get_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->get_verts()[0]);
199  }
200  }
201  N[0] = vN.x;
202  N[1] = vN.y;
203  N[2] = vN.z;
204 }
205 
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 
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->get_num_subd_faces()) ? mesh->subd_attributes :
226  mesh->attributes;
227  Attribute *attr;
228  ustring name;
229  if (layer_name != NULL) {
230  name = ustring((string(layer_name) + ".tangent").c_str());
231  }
232  else {
233  name = ustring("orco.tangent");
234  }
235  if (active_render) {
236  attr = attributes.add(ATTR_STD_UV_TANGENT, name);
237  }
238  else {
239  attr = attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
240  }
241  float3 *tangent = attr->data_float3();
242  /* Create bitangent sign attribute. */
243  float *tangent_sign = NULL;
244  if (need_sign) {
245  Attribute *attr_sign;
246  ustring name_sign;
247  if (layer_name != NULL) {
248  name_sign = ustring((string(layer_name) + ".tangent_sign").c_str());
249  }
250  else {
251  name_sign = ustring("orco.tangent_sign");
252  }
253 
254  if (active_render) {
255  attr_sign = attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
256  }
257  else {
258  attr_sign = attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
259  }
260  tangent_sign = attr_sign->data_float();
261  }
262  /* Setup userdata. */
263  MikkUserData userdata(b_mesh, layer_name, mesh, tangent, tangent_sign);
264  /* Setup interface. */
265  SMikkTSpaceInterface sm_interface;
266  memset(&sm_interface, 0, sizeof(sm_interface));
267  sm_interface.m_getNumFaces = mikk_get_num_faces;
269  sm_interface.m_getPosition = mikk_get_position;
271  sm_interface.m_getNormal = mikk_get_normal;
273  /* Setup context. */
275  memset(&context, 0, sizeof(context));
276  context.m_pUserData = &userdata;
277  context.m_pInterface = &sm_interface;
278  /* Compute tangents. */
280 }
281 
282 /* Create sculpt vertex color attributes. */
284  Mesh *mesh,
285  BL::Mesh &b_mesh,
286  bool subdivision)
287 {
288  for (BL::MeshVertColorLayer &l : b_mesh.sculpt_vertex_colors) {
289  const bool active_render = l.active_render();
290  AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
291  ustring vcol_name = ustring(l.name().c_str());
292 
293  const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
294  mesh->need_attribute(scene, vcol_std);
295 
296  if (!need_vcol) {
297  continue;
298  }
299 
300  AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
301  Attribute *vcol_attr = attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_VERTEX);
302  vcol_attr->std = vcol_std;
303 
304  float4 *cdata = vcol_attr->data_float4();
305  int numverts = b_mesh.vertices.length();
306 
307  for (int i = 0; i < numverts; i++) {
308  *(cdata++) = get_float4(l.data[i].color());
309  }
310  }
311 }
312 
313 template<typename TypeInCycles, typename GetValueAtIndex>
314 static void fill_generic_attribute(BL::Mesh &b_mesh,
315  TypeInCycles *data,
317  const GetValueAtIndex &get_value_at_index)
318 {
319  switch (element) {
320  case ATTR_ELEMENT_CORNER: {
321  for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
322  const int index = t.index() * 3;
323  BL::Array<int, 3> loops = t.loops();
324  data[index] = get_value_at_index(loops[0]);
325  data[index + 1] = get_value_at_index(loops[1]);
326  data[index + 2] = get_value_at_index(loops[2]);
327  }
328  break;
329  }
330  case ATTR_ELEMENT_VERTEX: {
331  const int num_verts = b_mesh.vertices.length();
332  for (int i = 0; i < num_verts; i++) {
333  data[i] = get_value_at_index(i);
334  }
335  break;
336  }
337  case ATTR_ELEMENT_FACE: {
338  for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
339  data[t.index()] = get_value_at_index(t.polygon_index());
340  }
341  break;
342  }
343  default: {
344  assert(false);
345  break;
346  }
347  }
348 }
349 
350 static void attr_create_generic(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
351 {
352  if (subdivision) {
353  /* TODO: Handle subdivision correctly. */
354  return;
355  }
356  AttributeSet &attributes = mesh->attributes;
357 
358  for (BL::Attribute &b_attribute : b_mesh.attributes) {
359  const ustring name{b_attribute.name().c_str()};
360  if (!mesh->need_attribute(scene, name)) {
361  continue;
362  }
363  if (attributes.find(name)) {
364  continue;
365  }
366 
367  const BL::Attribute::domain_enum b_domain = b_attribute.domain();
368  const BL::Attribute::data_type_enum b_data_type = b_attribute.data_type();
369 
371  switch (b_domain) {
372  case BL::Attribute::domain_CORNER:
374  break;
375  case BL::Attribute::domain_POINT:
377  break;
378  case BL::Attribute::domain_FACE:
380  break;
381  default:
382  break;
383  }
384  if (element == ATTR_ELEMENT_NONE) {
385  /* Not supported. */
386  continue;
387  }
388  switch (b_data_type) {
389  case BL::Attribute::data_type_FLOAT: {
390  BL::FloatAttribute b_float_attribute{b_attribute};
391  Attribute *attr = attributes.add(name, TypeFloat, element);
392  float *data = attr->data_float();
394  b_mesh, data, element, [&](int i) { return b_float_attribute.data[i].value(); });
395  break;
396  }
397  case BL::Attribute::data_type_BOOLEAN: {
398  BL::BoolAttribute b_bool_attribute{b_attribute};
399  Attribute *attr = attributes.add(name, TypeFloat, element);
400  float *data = attr->data_float();
402  b_mesh, data, element, [&](int i) { return (float)b_bool_attribute.data[i].value(); });
403  break;
404  }
405  case BL::Attribute::data_type_INT: {
406  BL::IntAttribute b_int_attribute{b_attribute};
407  Attribute *attr = attributes.add(name, TypeFloat, element);
408  float *data = attr->data_float();
410  b_mesh, data, element, [&](int i) { return (float)b_int_attribute.data[i].value(); });
411  break;
412  }
413  case BL::Attribute::data_type_FLOAT_VECTOR: {
414  BL::FloatVectorAttribute b_vector_attribute{b_attribute};
415  Attribute *attr = attributes.add(name, TypeVector, element);
416  float3 *data = attr->data_float3();
417  fill_generic_attribute(b_mesh, data, element, [&](int i) {
418  BL::Array<float, 3> v = b_vector_attribute.data[i].vector();
419  return make_float3(v[0], v[1], v[2]);
420  });
421  break;
422  }
423  case BL::Attribute::data_type_FLOAT_COLOR: {
424  BL::FloatColorAttribute b_color_attribute{b_attribute};
425  Attribute *attr = attributes.add(name, TypeRGBA, element);
426  float4 *data = attr->data_float4();
427  fill_generic_attribute(b_mesh, data, element, [&](int i) {
428  BL::Array<float, 4> v = b_color_attribute.data[i].color();
429  return make_float4(v[0], v[1], v[2], v[3]);
430  });
431  break;
432  }
433  case BL::Attribute::data_type_FLOAT2: {
434  BL::Float2Attribute b_float2_attribute{b_attribute};
435  Attribute *attr = attributes.add(name, TypeFloat2, element);
436  float2 *data = attr->data_float2();
437  fill_generic_attribute(b_mesh, data, element, [&](int i) {
438  BL::Array<float, 2> v = b_float2_attribute.data[i].vector();
439  return make_float2(v[0], v[1]);
440  });
441  break;
442  }
443  default:
444  /* Not supported. */
445  break;
446  }
447  }
448 }
449 
450 /* Create vertex color attributes. */
451 static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
452 {
453  for (BL::MeshLoopColorLayer &l : b_mesh.vertex_colors) {
454  const bool active_render = l.active_render();
455  AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
456  ustring vcol_name = ustring(l.name().c_str());
457 
458  const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
459  mesh->need_attribute(scene, vcol_std);
460 
461  if (!need_vcol) {
462  continue;
463  }
464 
465  Attribute *vcol_attr = NULL;
466 
467  if (subdivision) {
468  if (active_render) {
469  vcol_attr = mesh->subd_attributes.add(vcol_std, vcol_name);
470  }
471  else {
472  vcol_attr = mesh->subd_attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
473  }
474 
475  uchar4 *cdata = vcol_attr->data_uchar4();
476 
477  for (BL::MeshPolygon &p : b_mesh.polygons) {
478  int n = p.loop_total();
479  for (int i = 0; i < n; i++) {
480  float4 color = get_float4(l.data[p.loop_start() + i].color());
481  /* Compress/encode vertex color using the sRGB curve. */
482  *(cdata++) = color_float4_to_uchar4(color);
483  }
484  }
485  }
486  else {
487  if (active_render) {
488  vcol_attr = mesh->attributes.add(vcol_std, vcol_name);
489  }
490  else {
491  vcol_attr = mesh->attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
492  }
493 
494  uchar4 *cdata = vcol_attr->data_uchar4();
495 
496  for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
497  int3 li = get_int3(t.loops());
498  float4 c1 = get_float4(l.data[li[0]].color());
499  float4 c2 = get_float4(l.data[li[1]].color());
500  float4 c3 = get_float4(l.data[li[2]].color());
501 
502  /* Compress/encode vertex color using the sRGB curve. */
503  cdata[0] = color_float4_to_uchar4(c1);
504  cdata[1] = color_float4_to_uchar4(c2);
505  cdata[2] = color_float4_to_uchar4(c3);
506 
507  cdata += 3;
508  }
509  }
510  }
511 }
512 
513 /* Create uv map attributes. */
514 static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
515 {
516  if (b_mesh.uv_layers.length() != 0) {
517  for (BL::MeshUVLoopLayer &l : b_mesh.uv_layers) {
518  const bool active_render = l.active_render();
519  AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
520  ustring uv_name = ustring(l.name().c_str());
521  AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
522  ustring tangent_name = ustring((string(l.name().c_str()) + ".tangent").c_str());
523 
524  /* Denotes whether UV map was requested directly. */
525  const bool need_uv = mesh->need_attribute(scene, uv_name) ||
526  mesh->need_attribute(scene, uv_std);
527  /* Denotes whether tangent was requested directly. */
528  const bool need_tangent = mesh->need_attribute(scene, tangent_name) ||
529  (active_render && mesh->need_attribute(scene, tangent_std));
530 
531  /* UV map */
532  /* NOTE: We create temporary UV layer if its needed for tangent but
533  * wasn't requested by other nodes in shaders.
534  */
535  Attribute *uv_attr = NULL;
536  if (need_uv || need_tangent) {
537  if (active_render) {
538  uv_attr = mesh->attributes.add(uv_std, uv_name);
539  }
540  else {
541  uv_attr = mesh->attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
542  }
543 
544  float2 *fdata = uv_attr->data_float2();
545 
546  for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
547  int3 li = get_int3(t.loops());
548  fdata[0] = get_float2(l.data[li[0]].uv());
549  fdata[1] = get_float2(l.data[li[1]].uv());
550  fdata[2] = get_float2(l.data[li[2]].uv());
551  fdata += 3;
552  }
553  }
554 
555  /* UV tangent */
556  if (need_tangent) {
557  AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
558  ustring sign_name = ustring((string(l.name().c_str()) + ".tangent_sign").c_str());
559  bool need_sign = (mesh->need_attribute(scene, sign_name) ||
560  mesh->need_attribute(scene, sign_std));
561  mikk_compute_tangents(b_mesh, l.name().c_str(), mesh, need_sign, active_render);
562  }
563  /* Remove temporarily created UV attribute. */
564  if (!need_uv && uv_attr != NULL) {
565  mesh->attributes.remove(uv_attr);
566  }
567  }
568  }
571  mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true);
574  }
575  }
576 }
577 
578 static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs)
579 {
580  if (b_mesh.uv_layers.length() != 0) {
581  BL::Mesh::uv_layers_iterator l;
582  int i = 0;
583 
584  for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
585  bool active_render = l->active_render();
586  AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
587  ustring uv_name = ustring(l->name().c_str());
588  AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
589  ustring tangent_name = ustring((string(l->name().c_str()) + ".tangent").c_str());
590 
591  /* Denotes whether UV map was requested directly. */
592  const bool need_uv = mesh->need_attribute(scene, uv_name) ||
593  mesh->need_attribute(scene, uv_std);
594  /* Denotes whether tangent was requested directly. */
595  const bool need_tangent = mesh->need_attribute(scene, tangent_name) ||
596  (active_render && mesh->need_attribute(scene, tangent_std));
597 
598  Attribute *uv_attr = NULL;
599 
600  /* UV map */
601  if (need_uv || need_tangent) {
602  if (active_render)
603  uv_attr = mesh->subd_attributes.add(uv_std, uv_name);
604  else
605  uv_attr = mesh->subd_attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
606 
607  if (subdivide_uvs) {
608  uv_attr->flags |= ATTR_SUBDIVIDED;
609  }
610 
611  float2 *fdata = uv_attr->data_float2();
612 
613  for (BL::MeshPolygon &p : b_mesh.polygons) {
614  int n = p.loop_total();
615  for (int j = 0; j < n; j++) {
616  *(fdata++) = get_float2(l->data[p.loop_start() + j].uv());
617  }
618  }
619  }
620 
621  /* UV tangent */
622  if (need_tangent) {
623  AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
624  ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
625  bool need_sign = (mesh->need_attribute(scene, sign_name) ||
626  mesh->need_attribute(scene, sign_std));
627  mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render);
628  }
629  /* Remove temporarily created UV attribute. */
630  if (!need_uv && uv_attr != NULL) {
631  mesh->subd_attributes.remove(uv_attr);
632  }
633  }
634  }
637  mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true);
639  mesh->subd_attributes.remove(ATTR_STD_GENERATED);
640  }
641  }
642 }
643 
644 /* Create vertex pointiness attributes. */
645 
646 /* Compare vertices by sum of their coordinates. */
648  public:
650  {
651  }
652 
653  bool operator()(const int &vert_idx_a, const int &vert_idx_b)
654  {
655  const float3 &vert_a = verts_[vert_idx_a];
656  const float3 &vert_b = verts_[vert_idx_b];
657  if (vert_a == vert_b) {
658  /* Special case for doubles, so we ensure ordering. */
659  return vert_idx_a > vert_idx_b;
660  }
661  const float x1 = vert_a.x + vert_a.y + vert_a.z;
662  const float x2 = vert_b.x + vert_b.y + vert_b.z;
663  return x1 < x2;
664  }
665 
666  protected:
668 };
669 
670 static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
671 {
673  return;
674  }
675  const int num_verts = b_mesh.vertices.length();
676  if (num_verts == 0) {
677  return;
678  }
679  /* STEP 1: Find out duplicated vertices and point duplicates to a single
680  * original vertex.
681  */
682  vector<int> sorted_vert_indeices(num_verts);
683  for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
684  sorted_vert_indeices[vert_index] = vert_index;
685  }
686  VertexAverageComparator compare(mesh->get_verts());
687  sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare);
688  /* This array stores index of the original vertex for the given vertex
689  * index.
690  */
691  vector<int> vert_orig_index(num_verts);
692  for (int sorted_vert_index = 0; sorted_vert_index < num_verts; ++sorted_vert_index) {
693  const int vert_index = sorted_vert_indeices[sorted_vert_index];
694  const float3 &vert_co = mesh->get_verts()[vert_index];
695  bool found = false;
696  for (int other_sorted_vert_index = sorted_vert_index + 1; other_sorted_vert_index < num_verts;
697  ++other_sorted_vert_index) {
698  const int other_vert_index = sorted_vert_indeices[other_sorted_vert_index];
699  const float3 &other_vert_co = mesh->get_verts()[other_vert_index];
700  /* We are too far away now, we wouldn't have duplicate. */
701  if ((other_vert_co.x + other_vert_co.y + other_vert_co.z) -
702  (vert_co.x + vert_co.y + vert_co.z) >
703  3 * FLT_EPSILON) {
704  break;
705  }
706  /* Found duplicate. */
707  if (len_squared(other_vert_co - vert_co) < FLT_EPSILON) {
708  found = true;
709  vert_orig_index[vert_index] = other_vert_index;
710  break;
711  }
712  }
713  if (!found) {
714  vert_orig_index[vert_index] = vert_index;
715  }
716  }
717  /* Make sure we always points to the very first orig vertex. */
718  for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
719  int orig_index = vert_orig_index[vert_index];
720  while (orig_index != vert_orig_index[orig_index]) {
721  orig_index = vert_orig_index[orig_index];
722  }
723  vert_orig_index[vert_index] = orig_index;
724  }
725  sorted_vert_indeices.free_memory();
726  /* STEP 2: Calculate vertex normals taking into account their possible
727  * duplicates which gets "welded" together.
728  */
729  vector<float3> vert_normal(num_verts, zero_float3());
730  /* First we accumulate all vertex normals in the original index. */
731  for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
732  const float3 normal = get_float3(b_mesh.vertices[vert_index].normal());
733  const int orig_index = vert_orig_index[vert_index];
734  vert_normal[orig_index] += normal;
735  }
736  /* Then we normalize the accumulated result and flush it to all duplicates
737  * as well.
738  */
739  for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
740  const int orig_index = vert_orig_index[vert_index];
741  vert_normal[vert_index] = normalize(vert_normal[orig_index]);
742  }
743  /* STEP 3: Calculate pointiness using single ring neighborhood. */
744  vector<int> counter(num_verts, 0);
745  vector<float> raw_data(num_verts, 0.0f);
746  vector<float3> edge_accum(num_verts, zero_float3());
747  BL::Mesh::edges_iterator e;
748  EdgeMap visited_edges;
749  int edge_index = 0;
750  memset(&counter[0], 0, sizeof(int) * counter.size());
751  for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
752  const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
753  v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
754  if (visited_edges.exists(v0, v1)) {
755  continue;
756  }
757  visited_edges.insert(v0, v1);
758  float3 co0 = get_float3(b_mesh.vertices[v0].co()), co1 = get_float3(b_mesh.vertices[v1].co());
759  float3 edge = normalize(co1 - co0);
760  edge_accum[v0] += edge;
761  edge_accum[v1] += -edge;
762  ++counter[v0];
763  ++counter[v1];
764  }
765  for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
766  const int orig_index = vert_orig_index[vert_index];
767  if (orig_index != vert_index) {
768  /* Skip duplicates, they'll be overwritten later on. */
769  continue;
770  }
771  if (counter[vert_index] > 0) {
772  const float3 normal = vert_normal[vert_index];
773  const float angle = safe_acosf(dot(normal, edge_accum[vert_index] / counter[vert_index]));
774  raw_data[vert_index] = angle * M_1_PI_F;
775  }
776  else {
777  raw_data[vert_index] = 0.0f;
778  }
779  }
780  /* STEP 3: Blur vertices to approximate 2 ring neighborhood. */
781  AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
782  Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
783  float *data = attr->data_float();
784  memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
785  memset(&counter[0], 0, sizeof(int) * counter.size());
786  edge_index = 0;
787  visited_edges.clear();
788  for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
789  const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
790  v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
791  if (visited_edges.exists(v0, v1)) {
792  continue;
793  }
794  visited_edges.insert(v0, v1);
795  data[v0] += raw_data[v1];
796  data[v1] += raw_data[v0];
797  ++counter[v0];
798  ++counter[v1];
799  }
800  for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
801  data[vert_index] /= counter[vert_index] + 1;
802  }
803  /* STEP 4: Copy attribute to the duplicated vertices. */
804  for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
805  const int orig_index = vert_orig_index[vert_index];
806  data[vert_index] = data[orig_index];
807  }
808 }
809 
810 /* The Random Per Island attribute is a random float associated with each
811  * connected component (island) of the mesh. The attribute is computed by
812  * first classifying the vertices into different sets using a Disjoint Set
813  * data structure. Then the index of the root of each vertex (Which is the
814  * representative of the set the vertex belongs to) is hashed and stored.
815  *
816  * We are using a face attribute to avoid interpolation during rendering,
817  * allowing the user to safely hash the output further. Had we used vertex
818  * attribute, the interpolation will introduce very slight variations,
819  * making the output unsafe to hash. */
821  Mesh *mesh,
822  BL::Mesh &b_mesh,
823  bool subdivision)
824 {
826  return;
827  }
828 
829  int number_of_vertices = b_mesh.vertices.length();
830  if (number_of_vertices == 0) {
831  return;
832  }
833 
834  DisjointSet vertices_sets(number_of_vertices);
835 
836  for (BL::MeshEdge &e : b_mesh.edges) {
837  vertices_sets.join(e.vertices()[0], e.vertices()[1]);
838  }
839 
840  AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
841  Attribute *attribute = attributes.add(ATTR_STD_RANDOM_PER_ISLAND);
842  float *data = attribute->data_float();
843 
844  if (!subdivision) {
845  for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
846  data[t.index()] = hash_uint_to_float(vertices_sets.find(t.vertices()[0]));
847  }
848  }
849  else {
850  for (BL::MeshPolygon &p : b_mesh.polygons) {
851  data[p.index()] = hash_uint_to_float(vertices_sets.find(p.vertices()[0]));
852  }
853  }
854 }
855 
856 /* Create Mesh */
857 
858 static void create_mesh(Scene *scene,
859  Mesh *mesh,
860  BL::Mesh &b_mesh,
861  const array<Node *> &used_shaders,
862  bool subdivision = false,
863  bool subdivide_uvs = true)
864 {
865  /* count vertices and faces */
866  int numverts = b_mesh.vertices.length();
867  int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
868  int numtris = 0;
869  int numcorners = 0;
870  int numngons = 0;
871  bool use_loop_normals = b_mesh.use_auto_smooth() &&
872  (mesh->get_subdivision_type() != Mesh::SUBDIVISION_CATMULL_CLARK);
873 
874  /* If no faces, create empty mesh. */
875  if (numfaces == 0) {
876  return;
877  }
878 
879  if (!subdivision) {
880  numtris = numfaces;
881  }
882  else {
883  for (BL::MeshPolygon &p : b_mesh.polygons) {
884  numngons += (p.loop_total() == 4) ? 0 : 1;
885  numcorners += p.loop_total();
886  }
887  }
888 
889  /* allocate memory */
890  if (subdivision) {
891  mesh->reserve_subd_faces(numfaces, numngons, numcorners);
892  }
893 
894  mesh->reserve_mesh(numverts, numtris);
895 
896  /* create vertex coordinates and normals */
897  BL::Mesh::vertices_iterator v;
898  for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
899  mesh->add_vertex(get_float3(v->co()));
900 
901  AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
902  Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL);
903  float3 *N = attr_N->data_float3();
904 
905  for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
906  *N = get_float3(v->normal());
907  N = attr_N->data_float3();
908 
909  /* create generated coordinates from undeformed coordinates */
910  const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.length() == 0) &&
912  if (mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_default_tangent) {
913  Attribute *attr = attributes.add(ATTR_STD_GENERATED);
914  attr->flags |= ATTR_SUBDIVIDED;
915 
916  float3 loc, size;
917  mesh_texture_space(b_mesh, loc, size);
918 
919  float3 *generated = attr->data_float3();
920  size_t i = 0;
921 
922  for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) {
923  generated[i++] = get_float3(v->undeformed_co()) * size - loc;
924  }
925  }
926 
927  /* create faces */
928  if (!subdivision) {
929  for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
930  BL::MeshPolygon p = b_mesh.polygons[t.polygon_index()];
931  int3 vi = get_int3(t.vertices());
932 
933  int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
934  bool smooth = p.use_smooth() || use_loop_normals;
935 
936  if (use_loop_normals) {
937  BL::Array<float, 9> loop_normals = t.split_normals();
938  for (int i = 0; i < 3; i++) {
939  N[vi[i]] = make_float3(
940  loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
941  }
942  }
943 
944  /* Create triangles.
945  *
946  * NOTE: Autosmooth is already taken care about.
947  */
948  mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
949  }
950  }
951  else {
952  vector<int> vi;
953 
954  for (BL::MeshPolygon &p : b_mesh.polygons) {
955  int n = p.loop_total();
956  int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
957  bool smooth = p.use_smooth() || use_loop_normals;
958 
959  vi.resize(n);
960  for (int i = 0; i < n; i++) {
961  /* NOTE: Autosmooth is already taken care about. */
962  vi[i] = b_mesh.loops[p.loop_start() + i].vertex_index();
963  }
964 
965  /* create subd faces */
966  mesh->add_subd_face(&vi[0], n, shader, smooth);
967  }
968  }
969 
970  /* Create all needed attributes.
971  * The calculate functions will check whether they're needed or not.
972  */
973  attr_create_pointiness(scene, mesh, b_mesh, subdivision);
974  attr_create_vertex_color(scene, mesh, b_mesh, subdivision);
975  attr_create_sculpt_vertex_color(scene, mesh, b_mesh, subdivision);
976  attr_create_random_per_island(scene, mesh, b_mesh, subdivision);
977  attr_create_generic(scene, mesh, b_mesh, subdivision);
978 
979  if (subdivision) {
980  attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs);
981  }
982  else {
983  attr_create_uv_map(scene, mesh, b_mesh);
984  }
985 
986  /* For volume objects, create a matrix to transform from object space to
987  * mesh texture space. this does not work with deformations but that can
988  * probably only be done well with a volume grid mapping of coordinates. */
991  Transform *tfm = attr->data_transform();
992 
993  float3 loc, size;
994  mesh_texture_space(b_mesh, loc, size);
995 
996  *tfm = transform_translate(-loc) * transform_scale(size);
997  }
998 }
999 
1001  Mesh *mesh,
1002  BL::Object &b_ob,
1003  BL::Mesh &b_mesh,
1004  const array<Node *> &used_shaders,
1005  float dicing_rate,
1006  int max_subdivisions)
1007 {
1008  BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length() - 1]);
1009  bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE;
1010 
1011  create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
1012 
1013  /* export creases */
1014  size_t num_creases = 0;
1015 
1016  for (BL::MeshEdge &e : b_mesh.edges) {
1017  if (e.crease() != 0.0f) {
1018  num_creases++;
1019  }
1020  }
1021 
1022  mesh->reserve_subd_creases(num_creases);
1023 
1024  for (BL::MeshEdge &e : b_mesh.edges) {
1025  if (e.crease() != 0.0f) {
1026  mesh->add_crease(e.vertices()[0], e.vertices()[1], e.crease());
1027  }
1028  }
1029 
1030  /* set subd params */
1031  PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
1032  float subd_dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
1033 
1034  mesh->set_subd_dicing_rate(subd_dicing_rate);
1035  mesh->set_subd_max_level(max_subdivisions);
1036  mesh->set_subd_objecttoworld(get_transform(b_ob.matrix_world()));
1037 }
1038 
1039 /* Sync */
1040 
1041 static BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b_ob)
1042 {
1043  if (b_ob.modifiers.length() > 0) {
1044  BL::Modifier b_mod = b_ob.modifiers[b_ob.modifiers.length() - 1];
1045 
1046  if (b_mod.type() == BL::Modifier::type_MESH_SEQUENCE_CACHE) {
1047  BL::MeshSequenceCacheModifier mesh_cache = BL::MeshSequenceCacheModifier(b_mod);
1048 
1049  if (MeshSequenceCacheModifier_has_velocity_get(&mesh_cache.ptr)) {
1050  return mesh_cache;
1051  }
1052  }
1053  }
1054 
1055  return BL::MeshSequenceCacheModifier(PointerRNA_NULL);
1056 }
1057 
1059 {
1061  return;
1062 
1063  BL::MeshSequenceCacheModifier b_mesh_cache = object_mesh_cache_find(b_ob);
1064 
1065  if (!b_mesh_cache) {
1066  return;
1067  }
1068 
1069  if (!MeshSequenceCacheModifier_read_velocity_get(&b_mesh_cache.ptr)) {
1070  return;
1071  }
1072 
1073  const size_t numverts = mesh->get_verts().size();
1074 
1075  if (b_mesh_cache.vertex_velocities.length() != numverts) {
1076  return;
1077  }
1078 
1079  /* Find or add attribute */
1080  float3 *P = &mesh->get_verts()[0];
1082 
1083  if (!attr_mP) {
1085  }
1086 
1087  /* Only export previous and next frame, we don't have any in between data. */
1088  float motion_times[2] = {-1.0f, 1.0f};
1089  for (int step = 0; step < 2; step++) {
1090  const float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
1091  float3 *mP = attr_mP->data_float3() + step * numverts;
1092 
1093  BL::MeshSequenceCacheModifier::vertex_velocities_iterator vvi;
1094  int i = 0;
1095 
1096  for (b_mesh_cache.vertex_velocities.begin(vvi); vvi != b_mesh_cache.vertex_velocities.end();
1097  ++vvi, ++i) {
1098  mP[i] = P[i] + get_float3(vvi->velocity()) * relative_time;
1099  }
1100  }
1101 }
1102 
1104 {
1106  return;
1107 
1109 
1110  if (!b_fluid_domain)
1111  return;
1112 
1113  /* If the mesh has modifiers following the fluid domain we can't export motion. */
1114  if (b_fluid_domain.mesh_vertices.length() != mesh->get_verts().size())
1115  return;
1116 
1117  /* Find or add attribute */
1118  float3 *P = &mesh->get_verts()[0];
1120 
1121  if (!attr_mP) {
1123  }
1124 
1125  /* Only export previous and next frame, we don't have any in between data. */
1126  float motion_times[2] = {-1.0f, 1.0f};
1127  for (int step = 0; step < 2; step++) {
1128  float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f;
1129  float3 *mP = attr_mP->data_float3() + step * mesh->get_verts().size();
1130 
1131  BL::FluidDomainSettings::mesh_vertices_iterator svi;
1132  int i = 0;
1133 
1134  for (b_fluid_domain.mesh_vertices.begin(svi); svi != b_fluid_domain.mesh_vertices.end();
1135  ++svi, ++i) {
1136  mP[i] = P[i] + get_float3(svi->velocity()) * relative_time;
1137  }
1138  }
1139 }
1140 
1141 void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh)
1142 {
1143  /* make a copy of the shaders as the caller in the main thread still need them for syncing the
1144  * attributes */
1145  array<Node *> used_shaders = mesh->get_used_shaders();
1146 
1147  Mesh new_mesh;
1148  new_mesh.set_used_shaders(used_shaders);
1149 
1150  if (view_layer.use_surfaces) {
1151  /* Adaptive subdivision setup. Not for baking since that requires
1152  * exact mapping to the Blender mesh. */
1153  if (!scene->bake_manager->get_baking()) {
1154  new_mesh.set_subdivision_type(object_subdivision_type(b_ob, preview, experimental));
1155  }
1156 
1157  /* For some reason, meshes do not need this... */
1158  bool need_undeformed = new_mesh.need_attribute(scene, ATTR_STD_GENERATED);
1159  BL::Mesh b_mesh = object_to_mesh(
1160  b_data, b_ob, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type());
1161 
1162  if (b_mesh) {
1163  /* Sync mesh itself. */
1164  if (new_mesh.get_subdivision_type() != Mesh::SUBDIVISION_NONE)
1165  create_subd_mesh(scene,
1166  &new_mesh,
1167  b_ob,
1168  b_mesh,
1169  new_mesh.get_used_shaders(),
1170  dicing_rate,
1171  max_subdivisions);
1172  else
1173  create_mesh(scene, &new_mesh, b_mesh, new_mesh.get_used_shaders(), false);
1174 
1175  free_object_to_mesh(b_data, b_ob, b_mesh);
1176  }
1177  }
1178 
1179  /* cached velocities (e.g. from alembic archive) */
1180  sync_mesh_cached_velocities(b_ob, scene, &new_mesh);
1181 
1182  /* mesh fluid motion mantaflow */
1183  sync_mesh_fluid_motion(b_ob, scene, &new_mesh);
1184 
1185  /* update original sockets */
1186 
1188 
1189  for (const SocketType &socket : new_mesh.type->inputs) {
1190  /* Those sockets are updated in sync_object, so do not modify them. */
1191  if (socket.name == "use_motion_blur" || socket.name == "motion_steps" ||
1192  socket.name == "used_shaders") {
1193  continue;
1194  }
1195  mesh->set_value(socket, new_mesh, socket);
1196  }
1197 
1198  mesh->attributes.update(std::move(new_mesh.attributes));
1199  mesh->subd_attributes.update(std::move(new_mesh.subd_attributes));
1200 
1202 
1203  /* tag update */
1204  bool rebuild = (mesh->triangles_is_modified()) || (mesh->subd_num_corners_is_modified()) ||
1205  (mesh->subd_shader_is_modified()) || (mesh->subd_smooth_is_modified()) ||
1206  (mesh->subd_ptex_offset_is_modified()) ||
1207  (mesh->subd_start_corner_is_modified()) ||
1208  (mesh->subd_face_corners_is_modified());
1209 
1210  mesh->tag_update(scene, rebuild);
1211 }
1212 
1213 void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
1214  BL::Object b_ob,
1215  Mesh *mesh,
1216  int motion_step)
1217 {
1218  /* Fluid motion blur already exported. */
1220  if (b_fluid_domain) {
1221  return;
1222  }
1223 
1224  /* Cached motion blur already exported. */
1225  BL::MeshSequenceCacheModifier mesh_cache = object_mesh_cache_find(b_ob);
1226  if (mesh_cache) {
1227  return;
1228  }
1229 
1230  /* Skip if no vertices were exported. */
1231  size_t numverts = mesh->get_verts().size();
1232  if (numverts == 0) {
1233  return;
1234  }
1235 
1236  /* Skip objects without deforming modifiers. this is not totally reliable,
1237  * would need a more extensive check to see which objects are animated. */
1238  BL::Mesh b_mesh(PointerRNA_NULL);
1239  if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
1240  /* get derived mesh */
1241  b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
1242  }
1243 
1244  /* TODO(sergey): Perform preliminary check for number of vertices. */
1245  if (b_mesh) {
1246  /* Export deformed coordinates. */
1247  /* Find attributes. */
1251  bool new_attribute = false;
1252  /* Add new attributes if they don't exist already. */
1253  if (!attr_mP) {
1255  if (attr_N)
1257 
1258  new_attribute = true;
1259  }
1260  /* Load vertex data from mesh. */
1261  float3 *mP = attr_mP->data_float3() + motion_step * numverts;
1262  float3 *mN = (attr_mN) ? attr_mN->data_float3() + motion_step * numverts : NULL;
1263  /* NOTE: We don't copy more that existing amount of vertices to prevent
1264  * possible memory corruption.
1265  */
1266  BL::Mesh::vertices_iterator v;
1267  int i = 0;
1268  for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
1269  mP[i] = get_float3(v->co());
1270  if (mN)
1271  mN[i] = get_float3(v->normal());
1272  }
1273  if (new_attribute) {
1274  /* In case of new attribute, we verify if there really was any motion. */
1275  if (b_mesh.vertices.length() != numverts ||
1276  memcmp(mP, &mesh->get_verts()[0], sizeof(float3) * numverts) == 0) {
1277  /* no motion, remove attributes again */
1278  if (b_mesh.vertices.length() != numverts) {
1279  VLOG(1) << "Topology differs, disabling motion blur for object " << b_ob.name();
1280  }
1281  else {
1282  VLOG(1) << "No actual deformation motion for object " << b_ob.name();
1283  }
1285  if (attr_mN)
1287  }
1288  else if (motion_step > 0) {
1289  VLOG(1) << "Filling deformation motion for object " << b_ob.name();
1290  /* motion, fill up previous steps that we might have skipped because
1291  * they had no motion, but we need them anyway now */
1292  float3 *P = &mesh->get_verts()[0];
1293  float3 *N = (attr_N) ? attr_N->data_float3() : NULL;
1294  for (int step = 0; step < motion_step; step++) {
1295  memcpy(attr_mP->data_float3() + step * numverts, P, sizeof(float3) * numverts);
1296  if (attr_mN)
1297  memcpy(attr_mN->data_float3() + step * numverts, N, sizeof(float3) * numverts);
1298  }
1299  }
1300  }
1301  else {
1302  if (b_mesh.vertices.length() != numverts) {
1303  VLOG(1) << "Topology differs, discarding motion blur for object " << b_ob.name()
1304  << " at time " << motion_step;
1305  memcpy(mP, &mesh->get_verts()[0], sizeof(float3) * numverts);
1306  if (mN != NULL) {
1307  memcpy(mN, attr_N->data_float3(), sizeof(float3) * numverts);
1308  }
1309  }
1310  }
1311 
1312  free_object_to_mesh(b_data, b_ob, b_mesh);
1313  return;
1314  }
1315 
1316  /* No deformation on this frame, copy coordinates if other frames did have it. */
1317  mesh->copy_center_to_motion_step(motion_step);
1318 }
1319 
int BKE_object_is_deform_modified(struct Scene *scene, struct Object *ob)
Definition: object.c:5018
MINLINE float safe_acosf(float a)
void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z)
Definition: math_geom.c:5236
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
struct FluidDomainSettings FluidDomainSettings
struct Mesh Mesh
struct Object Object
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
static int mikk_corner_index(const Mesh *mesh, const int face_num, const int vert_num)
static void mikk_get_position(const SMikkTSpaceContext *context, float P[3], const int face_num, const int vert_num)
static BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b_ob)
static void attr_create_random_per_island(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Object &b_ob, BL::Mesh &b_mesh, const array< Node * > &used_shaders, float dicing_rate, int max_subdivisions)
static void attr_create_sculpt_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh)
static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num)
static void fill_generic_attribute(BL::Mesh &b_mesh, TypeInCycles *data, const AttributeElement element, const GetValueAtIndex &get_value_at_index)
static int mikk_vertex_index(const Mesh *mesh, const int face_num, const int vert_num)
static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, const array< Node * > &used_shaders, bool subdivision=false, bool subdivide_uvs=true)
static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float uv[2], const int face_num, const int vert_num)
static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs)
static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
static void mikk_set_tangent_space(const SMikkTSpaceContext *context, const float T[], const float sign, const int face_num, const int vert_num)
static void sync_mesh_cached_velocities(BL::Object &b_ob, Scene *scene, Mesh *mesh)
static void mikk_compute_tangents(const BL::Mesh &b_mesh, const char *layer_name, Mesh *mesh, bool need_sign, bool active_render)
static int mikk_get_num_faces(const SMikkTSpaceContext *context)
static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
static void attr_create_generic(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3], const int face_num, const int vert_num)
static float4 get_float4(const BL::Array< float, 4 > &array)
Definition: blender_util.h:310
static BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object &b_ob)
Definition: blender_util.h:539
static float3 get_float3(const BL::Array< float, 2 > &array)
Definition: blender_util.h:295
static int3 get_int3(const BL::Array< int, 3 > &array)
Definition: blender_util.h:315
static float2 get_float2(const BL::Array< float, 2 > &array)
Definition: blender_util.h:290
static Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob, bool preview, bool experimental)
Definition: blender_util.h:571
static BL::Mesh object_to_mesh(BL::BlendData &, BL::Object &object, BL::Depsgraph &, bool, Mesh::SubdivisionType subdivision_type)
Definition: blender_util.h:49
static void free_object_to_mesh(BL::BlendData &, BL::Object &object, BL::Mesh &mesh)
Definition: blender_util.h:110
static Transform get_transform(const BL::Array< float, 16 > &array)
Definition: blender_util.h:277
static void mesh_texture_space(BL::Mesh &b_mesh, float3 &loc, float3 &size)
Definition: blender_util.h:473
ATTR_WARN_UNUSED_RESULT const void * element
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void sort(btMatrix3x3 &U, btVector3 &sigma, btMatrix3x3 &V, int t)
Helper function of 3X3 SVD for sorting singular values.
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
Attribute * add(ustring name, TypeDesc type, AttributeElement element)
Definition: attribute.cpp:428
void update(AttributeSet &&new_attributes)
Definition: attribute.cpp:663
Attribute * find(ustring name) const
Definition: attribute.cpp:447
void remove(ustring name)
Definition: attribute.cpp:456
float * data_float()
Definition: attribute.h:96
uchar4 * data_uchar4()
Definition: attribute.h:101
Transform * data_transform()
Definition: attribute.h:106
float4 * data_float4()
Definition: attribute.h:91
uint flags
Definition: attribute.h:55
AttributeStandard std
Definition: attribute.h:50
float3 * data_float3()
Definition: attribute.h:86
float2 * data_float2()
Definition: attribute.h:81
bool get_baking()
Definition: bake.cpp:88
void join(size_t x, size_t y)
size_t find(size_t x)
void clear()
Definition: blender_util.h:618
void insert(int v0, int v1)
Definition: blender_util.h:623
bool exists(int v0, int v1)
Definition: blender_util.h:629
bool need_attribute(Scene *scene, AttributeStandard std)
Definition: geometry.cpp:102
void tag_update(Scene *scene, bool rebuild)
Definition: geometry.cpp:271
AttributeSet attributes
Definition: geometry.h:81
VertexAverageComparator(const array< float3 > &verts)
bool operator()(const int &vert_idx_a, const int &vert_idx_b)
const array< float3 > & verts_
size_t size() const
Definition: util_array.h:203
void free_memory()
Definition: util_vector.h:44
Scene scene
static float verts[][3]
IconTextureDrawCall normal
#define CCL_NAMESPACE_END
#define make_float2(x, y)
#define make_float4(x, y, z, w)
#define make_float3(x, y, z)
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
AttributeStandard
Definition: kernel_types.h:744
@ ATTR_STD_GENERATED_TRANSFORM
Definition: kernel_types.h:753
@ ATTR_STD_UV
Definition: kernel_types.h:748
@ ATTR_STD_MOTION_VERTEX_NORMAL
Definition: kernel_types.h:757
@ ATTR_STD_VERTEX_NORMAL
Definition: kernel_types.h:746
@ ATTR_STD_UV_TANGENT
Definition: kernel_types.h:749
@ ATTR_STD_NONE
Definition: kernel_types.h:745
@ ATTR_STD_VERTEX_COLOR
Definition: kernel_types.h:751
@ ATTR_STD_MOTION_VERTEX_POSITION
Definition: kernel_types.h:756
@ ATTR_STD_UV_TANGENT_SIGN
Definition: kernel_types.h:750
@ ATTR_STD_POINTINESS
Definition: kernel_types.h:769
@ ATTR_STD_GENERATED
Definition: kernel_types.h:752
@ ATTR_STD_RANDOM_PER_ISLAND
Definition: kernel_types.h:770
@ ATTR_SUBDIVIDED
Definition: kernel_types.h:778
AttributeElement
Definition: kernel_types.h:729
@ ATTR_ELEMENT_NONE
Definition: kernel_types.h:730
@ ATTR_ELEMENT_CORNER_BYTE
Definition: kernel_types.h:737
@ ATTR_ELEMENT_CORNER
Definition: kernel_types.h:736
@ ATTR_ELEMENT_VERTEX
Definition: kernel_types.h:734
@ ATTR_ELEMENT_FACE
Definition: kernel_types.h:733
static float P(float k)
Definition: math_interp.c:41
#define T
tbool genTangSpaceDefault(const SMikkTSpaceContext *pContext)
Definition: mikktspace.c:269
double sign(double arg)
Definition: utility.h:250
params N
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6562
const PointerRNA PointerRNA_NULL
Definition: rna_access.c:71
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
struct SELECTID_Context context
Definition: select_engine.c:47
float co[3]
Definition: bmesh_class.h:99
int start_corner
Definition: mesh.h:99
bool smooth
Definition: mesh.h:102
float3 normal(const Mesh *mesh) const
Definition: mesh.cpp:115
float3 compute_normal(const float3 *verts) const
Definition: mesh.cpp:95
void reserve_subd_faces(int numfaces, int num_ngons, int numcorners)
Definition: mesh.cpp:260
size_t get_num_subd_faces() const
Definition: mesh.h:246
void reserve_subd_creases(size_t num_creases)
Definition: mesh.cpp:274
float size[3]
Triangle get_triangle(size_t i) const
Definition: mesh.h:86
void copy_center_to_motion_step(const int motion_step)
Definition: mesh.cpp:422
void reserve_mesh(int numverts, int numfaces)
Definition: mesh.cpp:230
@ SUBDIVISION_NONE
Definition: mesh.h:133
@ SUBDIVISION_CATMULL_CLARK
Definition: mesh.h:135
size_t num_triangles() const
Definition: mesh.h:92
void clear_non_sockets()
Definition: mesh.cpp:280
void set_num_subd_faces(size_t num_subd_faces_)
Definition: mesh.h:251
void add_crease(int v0, int v1, float weight)
Definition: mesh.cpp:411
void add_vertex(float3 P)
Definition: mesh.cpp:330
void add_triangle(int v0, int v1, int v2, int shader, bool smooth)
Definition: mesh.cpp:352
void add_subd_face(int *corners, int num_corners, int shader_, bool smooth_)
Definition: mesh.cpp:370
SubdFace get_subd_face(size_t index) const
Definition: mesh.cpp:400
float * tangent_sign
float2 * texface
const Mesh * mesh
float3 * vertex_normal
MikkUserData(const BL::Mesh &b_mesh, const char *layer_name, const Mesh *mesh, float3 *tangent, float *tangent_sign)
float3 * orco
float3 * tangent
float3 orco_size
vector< SocketType, std::allocator< SocketType > > inputs
Definition: node_type.h:131
const NodeType * type
Definition: node.h:175
void set_value(const SocketType &input, const Node &other, const SocketType &other_input)
Definition: node.cpp:385
void(* m_getNormal)(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert)
Definition: mikktspace.h:77
void(* m_getPosition)(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert)
Definition: mikktspace.h:73
void(* m_getTexCoord)(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert)
Definition: mikktspace.h:81
void(* m_setTSpaceBasic)(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert)
Definition: mikktspace.h:98
int(* m_getNumFaces)(const SMikkTSpaceContext *pContext)
Definition: mikktspace.h:65
int(* m_getNumVerticesOfFace)(const SMikkTSpaceContext *pContext, const int iFace)
Definition: mikktspace.h:69
BakeManager * bake_manager
Definition: scene.h:249
MotionType need_motion()
Definition: scene.cpp:358
@ MOTION_NONE
Definition: scene.h:280
float motion_shutter_time()
Definition: scene.cpp:368
ustring name
Definition: node_type.h:85
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
float max
ccl_device uchar4 color_float4_to_uchar4(float4 c)
Definition: util_color.h:46
ccl_device_inline float hash_uint_to_float(uint kx)
Definition: util_hash.h:130
#define VLOG(severity)
Definition: util_logging.h:50
#define M_1_PI_F
Definition: util_math.h:52
ccl_device_inline int clamp(int a, int mn, int mx)
Definition: util_math.h:283
ccl_device_inline float2 normalize(const float2 &a)
ccl_device_inline float dot(const float2 &a, const float2 &b)
ccl_device_inline float3 zero_float3()
ccl_device_inline float len_squared(const float3 a)
static constexpr TypeDesc TypeRGBA(TypeDesc::FLOAT, TypeDesc::VEC4, TypeDesc::COLOR)
CCL_NAMESPACE_BEGIN static constexpr OIIO_NAMESPACE_USING TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2)
ccl_device_inline Transform transform_translate(float3 t)
ccl_device_inline Transform transform_scale(float3 s)