Blender  V2.93
geometry.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2020 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 "bvh/bvh.h"
18 #include "bvh/bvh2.h"
19 
20 #include "device/device.h"
21 
22 #include "render/attribute.h"
23 #include "render/camera.h"
24 #include "render/geometry.h"
25 #include "render/hair.h"
26 #include "render/light.h"
27 #include "render/mesh.h"
28 #include "render/nodes.h"
29 #include "render/object.h"
30 #include "render/scene.h"
31 #include "render/shader.h"
32 #include "render/stats.h"
33 #include "render/volume.h"
34 
35 #include "subd/subd_patch_table.h"
36 #include "subd/subd_split.h"
37 
38 #include "kernel/osl/osl_globals.h"
39 
40 #include "util/util_foreach.h"
41 #include "util/util_logging.h"
42 #include "util/util_progress.h"
43 #include "util/util_task.h"
44 
46 
47 /* Geometry */
48 
50 {
51  pack_flags = (PackFlags)((uint32_t)pack_flags | value);
52  return pack_flags;
53 }
54 
56 {
57  NodeType *type = NodeType::add("geometry_base", NULL);
58 
59  SOCKET_UINT(motion_steps, "Motion Steps", 3);
60  SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false);
61  SOCKET_NODE_ARRAY(used_shaders, "Shaders", Shader::get_node_type());
62 
63  return type;
64 }
65 
66 Geometry::Geometry(const NodeType *node_type, const Type type)
67  : Node(node_type), geometry_type(type), attributes(this, ATTR_PRIM_GEOMETRY)
68 {
69  need_update_rebuild = false;
71 
72  transform_applied = false;
76 
77  has_volume = false;
78  has_surface_bssrdf = false;
79 
80  bvh = NULL;
81  attr_map_offset = 0;
83  prim_offset = 0;
84 }
85 
87 {
88  delete bvh;
89 }
90 
91 void Geometry::clear(bool preserve_shaders)
92 {
93  if (!preserve_shaders)
94  used_shaders.clear();
95 
96  transform_applied = false;
99  tag_modified();
100 }
101 
103 {
104  if (std == ATTR_STD_NONE)
105  return false;
106 
108  return true;
109 
110  foreach (Node *node, used_shaders) {
111  Shader *shader = static_cast<Shader *>(node);
112  if (shader->attributes.find(std))
113  return true;
114  }
115 
116  return false;
117 }
118 
119 bool Geometry::need_attribute(Scene * /*scene*/, ustring name)
120 {
121  if (name == ustring())
122  return false;
123 
124  foreach (Node *node, used_shaders) {
125  Shader *shader = static_cast<Shader *>(node);
126  if (shader->attributes.find(name))
127  return true;
128  }
129 
130  return false;
131 }
132 
134 {
136 
137  foreach (Node *node, used_shaders) {
138  Shader *shader = static_cast<Shader *>(node);
139  result.add(shader->attributes);
140  }
141 
142  return result;
143 }
144 
145 float Geometry::motion_time(int step) const
146 {
147  return (motion_steps > 1) ? 2.0f * step / (motion_steps - 1) - 1.0f : 0.0f;
148 }
149 
150 int Geometry::motion_step(float time) const
151 {
152  if (motion_steps > 1) {
153  int attr_step = 0;
154 
155  for (int step = 0; step < motion_steps; step++) {
156  float step_time = motion_time(step);
157  if (step_time == time) {
158  return attr_step;
159  }
160 
161  /* Center step is stored in a separate attribute. */
162  if (step != motion_steps / 2) {
163  attr_step++;
164  }
165  }
166  }
167 
168  return -1;
169 }
170 
172 {
173  return is_instanced() || layout == BVH_LAYOUT_OPTIX || layout == BVH_LAYOUT_MULTI_OPTIX ||
175 }
176 
178 {
179  /* Currently we treat subsurface objects as instanced.
180  *
181  * While it might be not very optimal for ray traversal, it avoids having
182  * duplicated BVH in the memory, saving quite some space.
183  */
185 }
186 
188 {
189  foreach (Node *node, used_shaders) {
190  Shader *shader = static_cast<Shader *>(node);
191  if (shader->has_displacement && shader->get_displacement_method() != DISPLACE_BUMP) {
192  return true;
193  }
194  }
195 
196  return false;
197 }
198 
200  Device *device, DeviceScene *dscene, SceneParams *params, Progress *progress, int n, int total)
201 {
202  if (progress->get_cancel())
203  return;
204 
205  compute_bounds();
206 
207  const BVHLayout bvh_layout = BVHParams::best_bvh_layout(params->bvh_layout,
208  device->get_bvh_layout_mask());
209  if (need_build_bvh(bvh_layout)) {
210  string msg = "Updating Geometry BVH ";
211  if (name.empty())
212  msg += string_printf("%u/%u", (uint)(n + 1), (uint)total);
213  else
214  msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total);
215 
216  Object object;
217  object.set_geometry(this);
218 
219  vector<Geometry *> geometry;
220  geometry.push_back(this);
221  vector<Object *> objects;
222  objects.push_back(&object);
223 
224  if (bvh && !need_update_rebuild) {
225  progress->set_status(msg, "Refitting BVH");
226 
227  bvh->geometry = geometry;
228  bvh->objects = objects;
229 
230  device->build_bvh(bvh, *progress, true);
231  }
232  else {
233  progress->set_status(msg, "Building BVH");
234 
235  BVHParams bparams;
236  bparams.use_spatial_split = params->use_bvh_spatial_split;
237  bparams.bvh_layout = bvh_layout;
238  bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
239  params->use_bvh_unaligned_nodes;
240  bparams.num_motion_triangle_steps = params->num_bvh_time_steps;
241  bparams.num_motion_curve_steps = params->num_bvh_time_steps;
242  bparams.bvh_type = params->bvh_type;
243  bparams.curve_subdivisions = params->curve_subdivisions();
244 
245  delete bvh;
246  bvh = BVH::create(bparams, geometry, objects, device);
247  MEM_GUARDED_CALL(progress, device->build_bvh, bvh, *progress, false);
248  }
249  }
250 
251  need_update_rebuild = false;
253 }
254 
256 {
257  return (use_motion_blur && attributes.find(ATTR_STD_MOTION_VERTEX_POSITION));
258 }
259 
261 {
262  foreach (const Attribute &attr, attributes.attributes) {
263  if (attr.element == ATTR_ELEMENT_VOXEL) {
264  return true;
265  }
266  }
267 
268  return false;
269 }
270 
271 void Geometry::tag_update(Scene *scene, bool rebuild)
272 {
273  if (rebuild) {
274  need_update_rebuild = true;
276  }
277  else {
278  foreach (Node *node, used_shaders) {
279  Shader *shader = static_cast<Shader *>(node);
280  if (shader->has_surface_emission) {
282  break;
283  }
284  }
285  }
286 
288 }
289 
290 void Geometry::tag_bvh_update(bool rebuild)
291 {
292  tag_modified();
293 
294  if (rebuild) {
295  need_update_rebuild = true;
296  }
297 }
298 
299 /* Geometry Manager */
300 
302 {
303  update_flags = UPDATE_ALL;
304  need_flags_update = true;
305 }
306 
308 {
309 }
310 
312  Scene *scene,
313  vector<AttributeRequestSet> &geom_attributes)
314 {
315 #ifdef WITH_OSL
316  /* for OSL, a hash map is used to lookup the attribute by name. */
317  OSLGlobals *og = (OSLGlobals *)device->osl_memory();
318 
319  og->object_name_map.clear();
320  og->attribute_map.clear();
321  og->object_names.clear();
322 
323  og->attribute_map.resize(scene->objects.size() * ATTR_PRIM_TYPES);
324 
325  for (size_t i = 0; i < scene->objects.size(); i++) {
326  /* set object name to object index map */
327  Object *object = scene->objects[i];
328  og->object_name_map[object->name] = i;
329  og->object_names.push_back(object->name);
330 
331  /* set object attributes */
332  foreach (ParamValue &attr, object->attributes) {
333  OSLGlobals::Attribute osl_attr;
334 
335  osl_attr.type = attr.type();
336  osl_attr.desc.element = ATTR_ELEMENT_OBJECT;
337  osl_attr.value = attr;
338  osl_attr.desc.offset = 0;
339  osl_attr.desc.flags = 0;
340 
341  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][attr.name()] = osl_attr;
342  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr;
343  }
344 
345  /* find geometry attributes */
346  size_t j = object->geometry->index;
347  assert(j < scene->geometry.size() && scene->geometry[j] == object->geometry);
348 
349  AttributeRequestSet &attributes = geom_attributes[j];
350 
351  /* set mesh attributes */
352  foreach (AttributeRequest &req, attributes.requests) {
353  OSLGlobals::Attribute osl_attr;
354 
355  if (req.desc.element != ATTR_ELEMENT_NONE) {
356  osl_attr.desc = req.desc;
357 
358  if (req.type == TypeDesc::TypeFloat)
359  osl_attr.type = TypeDesc::TypeFloat;
360  else if (req.type == TypeDesc::TypeMatrix)
361  osl_attr.type = TypeDesc::TypeMatrix;
362  else if (req.type == TypeFloat2)
363  osl_attr.type = TypeFloat2;
364  else if (req.type == TypeRGBA)
365  osl_attr.type = TypeRGBA;
366  else
367  osl_attr.type = TypeDesc::TypeColor;
368 
369  if (req.std != ATTR_STD_NONE) {
370  /* if standard attribute, add lookup by geom: name convention */
371  ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
372  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][stdname] = osl_attr;
373  }
374  else if (req.name != ustring()) {
375  /* add lookup by geometry attribute name */
376  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][req.name] = osl_attr;
377  }
378  }
379 
380  if (req.subd_desc.element != ATTR_ELEMENT_NONE) {
381  osl_attr.desc = req.subd_desc;
382 
383  if (req.subd_type == TypeDesc::TypeFloat)
384  osl_attr.type = TypeDesc::TypeFloat;
385  else if (req.subd_type == TypeDesc::TypeMatrix)
386  osl_attr.type = TypeDesc::TypeMatrix;
387  else if (req.subd_type == TypeFloat2)
388  osl_attr.type = TypeFloat2;
389  else if (req.subd_type == TypeRGBA)
390  osl_attr.type = TypeRGBA;
391  else
392  osl_attr.type = TypeDesc::TypeColor;
393 
394  if (req.std != ATTR_STD_NONE) {
395  /* if standard attribute, add lookup by geom: name convention */
396  ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
397  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr;
398  }
399  else if (req.name != ustring()) {
400  /* add lookup by geometry attribute name */
401  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr;
402  }
403  }
404  }
405  }
406 #else
407  (void)device;
408  (void)scene;
409  (void)geom_attributes;
410 #endif
411 }
412 
413 /* Generate a normal attribute map entry from an attribute descriptor. */
415  uint4 *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc)
416 {
417  attr_map[index].x = id;
418  attr_map[index].y = desc.element;
419  attr_map[index].z = as_uint(desc.offset);
420 
421  if (type == TypeDesc::TypeFloat)
422  attr_map[index].w = NODE_ATTR_FLOAT;
423  else if (type == TypeDesc::TypeMatrix)
424  attr_map[index].w = NODE_ATTR_MATRIX;
425  else if (type == TypeFloat2)
426  attr_map[index].w = NODE_ATTR_FLOAT2;
427  else if (type == TypeFloat4)
428  attr_map[index].w = NODE_ATTR_FLOAT4;
429  else if (type == TypeRGBA)
430  attr_map[index].w = NODE_ATTR_RGBA;
431  else
432  attr_map[index].w = NODE_ATTR_FLOAT3;
433 
434  attr_map[index].w |= desc.flags << 8;
435 }
436 
437 /* Generate an attribute map end marker, optionally including a link to another map.
438  * Links are used to connect object attribute maps to mesh attribute maps. */
439 static void emit_attribute_map_terminator(uint4 *attr_map, int index, bool chain, uint chain_link)
440 {
441  for (int j = 0; j < ATTR_PRIM_TYPES; j++) {
442  attr_map[index + j].x = ATTR_STD_NONE;
443  attr_map[index + j].y = chain; /* link is valid flag */
444  attr_map[index + j].z = chain ? chain_link + j : 0; /* link to the correct sub-entry */
445  attr_map[index + j].w = 0;
446  }
447 }
448 
449 /* Generate all necessary attribute map entries from the attribute request. */
451  uint4 *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom)
452 {
453  uint id;
454 
455  if (req.std == ATTR_STD_NONE)
457  else
459 
460  emit_attribute_map_entry(attr_map, index, id, req.type, req.desc);
461 
462  if (geom->is_mesh()) {
463  Mesh *mesh = static_cast<Mesh *>(geom);
464  if (mesh->get_num_subd_faces()) {
465  emit_attribute_map_entry(attr_map, index + 1, id, req.subd_type, req.subd_desc);
466  }
467  }
468 }
469 
471  DeviceScene *dscene,
472  Scene *scene,
473  vector<AttributeRequestSet> &geom_attributes,
474  vector<AttributeRequestSet> &object_attributes)
475 {
476  /* for SVM, the attributes_map table is used to lookup the offset of an
477  * attribute, based on a unique shader attribute id. */
478 
479  /* compute array stride */
480  int attr_map_size = 0;
481 
482  for (size_t i = 0; i < scene->geometry.size(); i++) {
483  Geometry *geom = scene->geometry[i];
484  geom->attr_map_offset = attr_map_size;
485  attr_map_size += (geom_attributes[i].size() + 1) * ATTR_PRIM_TYPES;
486  }
487 
488  for (size_t i = 0; i < scene->objects.size(); i++) {
489  Object *object = scene->objects[i];
490 
491  /* only allocate a table for the object if it actually has attributes */
492  if (object_attributes[i].size() == 0) {
493  object->attr_map_offset = 0;
494  }
495  else {
496  object->attr_map_offset = attr_map_size;
497  attr_map_size += (object_attributes[i].size() + 1) * ATTR_PRIM_TYPES;
498  }
499  }
500 
501  if (attr_map_size == 0)
502  return;
503 
504  if (!dscene->attributes_map.need_realloc()) {
505  return;
506  }
507 
508  /* create attribute map */
509  uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size);
510  memset(attr_map, 0, dscene->attributes_map.size() * sizeof(uint));
511 
512  for (size_t i = 0; i < scene->geometry.size(); i++) {
513  Geometry *geom = scene->geometry[i];
514  AttributeRequestSet &attributes = geom_attributes[i];
515 
516  /* set geometry attributes */
517  int index = geom->attr_map_offset;
518 
519  foreach (AttributeRequest &req, attributes.requests) {
520  emit_attribute_mapping(attr_map, index, scene, req, geom);
521  index += ATTR_PRIM_TYPES;
522  }
523 
524  emit_attribute_map_terminator(attr_map, index, false, 0);
525  }
526 
527  for (size_t i = 0; i < scene->objects.size(); i++) {
528  Object *object = scene->objects[i];
529  AttributeRequestSet &attributes = object_attributes[i];
530 
531  /* set object attributes */
532  if (attributes.size() > 0) {
533  int index = object->attr_map_offset;
534 
535  foreach (AttributeRequest &req, attributes.requests) {
536  emit_attribute_mapping(attr_map, index, scene, req, object->geometry);
537  index += ATTR_PRIM_TYPES;
538  }
539 
540  emit_attribute_map_terminator(attr_map, index, true, object->geometry->attr_map_offset);
541  }
542  }
543 
544  /* copy to device */
545  dscene->attributes_map.copy_to_device();
546 }
547 
549  Attribute *mattr,
550  AttributePrimitive prim,
551  size_t *attr_float_size,
552  size_t *attr_float2_size,
553  size_t *attr_float3_size,
554  size_t *attr_uchar4_size)
555 {
556  if (mattr) {
557  size_t size = mattr->element_size(geom, prim);
558 
559  if (mattr->element == ATTR_ELEMENT_VOXEL) {
560  /* pass */
561  }
562  else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
563  *attr_uchar4_size += size;
564  }
565  else if (mattr->type == TypeDesc::TypeFloat) {
566  *attr_float_size += size;
567  }
568  else if (mattr->type == TypeFloat2) {
569  *attr_float2_size += size;
570  }
571  else if (mattr->type == TypeDesc::TypeMatrix) {
572  *attr_float3_size += size * 4;
573  }
574  else {
575  *attr_float3_size += size;
576  }
577  }
578 }
579 
580 void GeometryManager::update_attribute_element_offset(Geometry *geom,
581  device_vector<float> &attr_float,
582  size_t &attr_float_offset,
583  device_vector<float2> &attr_float2,
584  size_t &attr_float2_offset,
585  device_vector<float4> &attr_float3,
586  size_t &attr_float3_offset,
587  device_vector<uchar4> &attr_uchar4,
588  size_t &attr_uchar4_offset,
589  Attribute *mattr,
590  AttributePrimitive prim,
591  TypeDesc &type,
592  AttributeDescriptor &desc)
593 {
594  if (mattr) {
595  /* store element and type */
596  desc.element = mattr->element;
597  desc.flags = mattr->flags;
598  type = mattr->type;
599 
600  /* store attribute data in arrays */
601  size_t size = mattr->element_size(geom, prim);
602 
604  int &offset = desc.offset;
605 
606  if (mattr->element == ATTR_ELEMENT_VOXEL) {
607  /* store slot in offset value */
608  ImageHandle &handle = mattr->data_voxel();
609  offset = handle.svm_slot();
610  }
611  else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
612  uchar4 *data = mattr->data_uchar4();
613  offset = attr_uchar4_offset;
614 
615  assert(attr_uchar4.size() >= offset + size);
616  if (mattr->modified) {
617  for (size_t k = 0; k < size; k++) {
618  attr_uchar4[offset + k] = data[k];
619  }
620  }
621  attr_uchar4_offset += size;
622  }
623  else if (mattr->type == TypeDesc::TypeFloat) {
624  float *data = mattr->data_float();
625  offset = attr_float_offset;
626 
627  assert(attr_float.size() >= offset + size);
628  if (mattr->modified) {
629  for (size_t k = 0; k < size; k++) {
630  attr_float[offset + k] = data[k];
631  }
632  }
633  attr_float_offset += size;
634  }
635  else if (mattr->type == TypeFloat2) {
636  float2 *data = mattr->data_float2();
637  offset = attr_float2_offset;
638 
639  assert(attr_float2.size() >= offset + size);
640  if (mattr->modified) {
641  for (size_t k = 0; k < size; k++) {
642  attr_float2[offset + k] = data[k];
643  }
644  }
645  attr_float2_offset += size;
646  }
647  else if (mattr->type == TypeDesc::TypeMatrix) {
648  Transform *tfm = mattr->data_transform();
649  offset = attr_float3_offset;
650 
651  assert(attr_float3.size() >= offset + size * 3);
652  if (mattr->modified) {
653  for (size_t k = 0; k < size * 3; k++) {
654  attr_float3[offset + k] = (&tfm->x)[k];
655  }
656  }
657  attr_float3_offset += size * 3;
658  }
659  else {
660  float4 *data = mattr->data_float4();
661  offset = attr_float3_offset;
662 
663  assert(attr_float3.size() >= offset + size);
664  if (mattr->modified) {
665  for (size_t k = 0; k < size; k++) {
666  attr_float3[offset + k] = data[k];
667  }
668  }
669  attr_float3_offset += size;
670  }
671 
672  /* mesh vertex/curve index is global, not per object, so we sneak
673  * a correction for that in here */
674  if (geom->is_mesh()) {
675  Mesh *mesh = static_cast<Mesh *>(geom);
676  if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK &&
677  desc.flags & ATTR_SUBDIVIDED) {
678  /* indices for subdivided attributes are retrieved
679  * from patch table so no need for correction here*/
680  }
681  else if (element == ATTR_ELEMENT_VERTEX)
682  offset -= mesh->vert_offset;
684  offset -= mesh->vert_offset;
685  else if (element == ATTR_ELEMENT_FACE) {
686  if (prim == ATTR_PRIM_GEOMETRY)
687  offset -= mesh->prim_offset;
688  else
689  offset -= mesh->face_offset;
690  }
692  if (prim == ATTR_PRIM_GEOMETRY)
693  offset -= 3 * mesh->prim_offset;
694  else
695  offset -= mesh->corner_offset;
696  }
697  }
698  else if (geom->is_hair()) {
699  Hair *hair = static_cast<Hair *>(geom);
701  offset -= hair->prim_offset;
702  else if (element == ATTR_ELEMENT_CURVE_KEY)
703  offset -= hair->curvekey_offset;
705  offset -= hair->curvekey_offset;
706  }
707  }
708  else {
709  /* attribute not found */
710  desc.element = ATTR_ELEMENT_NONE;
711  desc.offset = 0;
712  }
713 }
714 
716  DeviceScene *dscene,
717  Scene *scene,
718  Progress &progress)
719 {
720  progress.set_status("Updating Mesh", "Computing attributes");
721 
722  /* gather per mesh requested attributes. as meshes may have multiple
723  * shaders assigned, this merges the requested attributes that have
724  * been set per shader by the shader manager */
725  vector<AttributeRequestSet> geom_attributes(scene->geometry.size());
726 
727  for (size_t i = 0; i < scene->geometry.size(); i++) {
728  Geometry *geom = scene->geometry[i];
729 
730  geom->index = i;
731  scene->need_global_attributes(geom_attributes[i]);
732 
733  foreach (Node *node, geom->get_used_shaders()) {
734  Shader *shader = static_cast<Shader *>(node);
735  geom_attributes[i].add(shader->attributes);
736  }
737  }
738 
739  /* convert object attributes to use the same data structures as geometry ones */
740  vector<AttributeRequestSet> object_attributes(scene->objects.size());
741  vector<AttributeSet> object_attribute_values;
742 
743  object_attribute_values.reserve(scene->objects.size());
744 
745  for (size_t i = 0; i < scene->objects.size(); i++) {
746  Object *object = scene->objects[i];
747  Geometry *geom = object->geometry;
748  size_t geom_idx = geom->index;
749 
750  assert(geom_idx < scene->geometry.size() && scene->geometry[geom_idx] == geom);
751 
752  object_attribute_values.push_back(AttributeSet(geom, ATTR_PRIM_GEOMETRY));
753 
754  AttributeRequestSet &geom_requests = geom_attributes[geom_idx];
755  AttributeRequestSet &attributes = object_attributes[i];
756  AttributeSet &values = object_attribute_values[i];
757 
758  for (size_t j = 0; j < object->attributes.size(); j++) {
759  ParamValue &param = object->attributes[j];
760 
761  /* add attributes that are requested and not already handled by the mesh */
762  if (geom_requests.find(param.name()) && !geom->attributes.find(param.name())) {
763  attributes.add(param.name());
764 
765  Attribute *attr = values.add(param.name(), param.type(), ATTR_ELEMENT_OBJECT);
766  assert(param.datasize() == attr->buffer.size());
767  memcpy(attr->buffer.data(), param.data(), param.datasize());
768  }
769  }
770  }
771 
772  /* mesh attribute are stored in a single array per data type. here we fill
773  * those arrays, and set the offset and element type to create attribute
774  * maps next */
775 
776  /* Pre-allocate attributes to avoid arrays re-allocation which would
777  * take 2x of overall attribute memory usage.
778  */
779  size_t attr_float_size = 0;
780  size_t attr_float2_size = 0;
781  size_t attr_float3_size = 0;
782  size_t attr_uchar4_size = 0;
783 
784  for (size_t i = 0; i < scene->geometry.size(); i++) {
785  Geometry *geom = scene->geometry[i];
786  AttributeRequestSet &attributes = geom_attributes[i];
787  foreach (AttributeRequest &req, attributes.requests) {
788  Attribute *attr = geom->attributes.find(req);
789 
791  attr,
793  &attr_float_size,
794  &attr_float2_size,
795  &attr_float3_size,
796  &attr_uchar4_size);
797 
798  if (geom->is_mesh()) {
799  Mesh *mesh = static_cast<Mesh *>(geom);
800  Attribute *subd_attr = mesh->subd_attributes.find(req);
801 
803  subd_attr,
805  &attr_float_size,
806  &attr_float2_size,
807  &attr_float3_size,
808  &attr_uchar4_size);
809  }
810  }
811  }
812 
813  for (size_t i = 0; i < scene->objects.size(); i++) {
814  Object *object = scene->objects[i];
815 
816  foreach (Attribute &attr, object_attribute_values[i].attributes) {
817  update_attribute_element_size(object->geometry,
818  &attr,
820  &attr_float_size,
821  &attr_float2_size,
822  &attr_float3_size,
823  &attr_uchar4_size);
824  }
825  }
826 
827  dscene->attributes_float.alloc(attr_float_size);
828  dscene->attributes_float2.alloc(attr_float2_size);
829  dscene->attributes_float3.alloc(attr_float3_size);
830  dscene->attributes_uchar4.alloc(attr_uchar4_size);
831 
832  const bool copy_all_data = dscene->attributes_float.need_realloc() ||
833  dscene->attributes_float2.need_realloc() ||
834  dscene->attributes_float3.need_realloc() ||
836 
837  size_t attr_float_offset = 0;
838  size_t attr_float2_offset = 0;
839  size_t attr_float3_offset = 0;
840  size_t attr_uchar4_offset = 0;
841 
842  /* Fill in attributes. */
843  for (size_t i = 0; i < scene->geometry.size(); i++) {
844  Geometry *geom = scene->geometry[i];
845  AttributeRequestSet &attributes = geom_attributes[i];
846 
847  /* todo: we now store std and name attributes from requests even if
848  * they actually refer to the same mesh attributes, optimize */
849  foreach (AttributeRequest &req, attributes.requests) {
850  Attribute *attr = geom->attributes.find(req);
851 
852  if (attr) {
853  /* force a copy if we need to reallocate all the data */
854  attr->modified |= copy_all_data;
855  }
856 
857  update_attribute_element_offset(geom,
858  dscene->attributes_float,
859  attr_float_offset,
860  dscene->attributes_float2,
861  attr_float2_offset,
862  dscene->attributes_float3,
863  attr_float3_offset,
864  dscene->attributes_uchar4,
865  attr_uchar4_offset,
866  attr,
868  req.type,
869  req.desc);
870 
871  if (geom->is_mesh()) {
872  Mesh *mesh = static_cast<Mesh *>(geom);
873  Attribute *subd_attr = mesh->subd_attributes.find(req);
874 
875  if (subd_attr) {
876  /* force a copy if we need to reallocate all the data */
877  subd_attr->modified |= copy_all_data;
878  }
879 
880  update_attribute_element_offset(mesh,
881  dscene->attributes_float,
882  attr_float_offset,
883  dscene->attributes_float2,
884  attr_float2_offset,
885  dscene->attributes_float3,
886  attr_float3_offset,
887  dscene->attributes_uchar4,
888  attr_uchar4_offset,
889  subd_attr,
891  req.subd_type,
892  req.subd_desc);
893  }
894 
895  if (progress.get_cancel())
896  return;
897  }
898  }
899 
900  for (size_t i = 0; i < scene->objects.size(); i++) {
901  Object *object = scene->objects[i];
902  AttributeRequestSet &attributes = object_attributes[i];
903  AttributeSet &values = object_attribute_values[i];
904 
905  foreach (AttributeRequest &req, attributes.requests) {
906  Attribute *attr = values.find(req);
907 
908  update_attribute_element_offset(object->geometry,
909  dscene->attributes_float,
910  attr_float_offset,
911  dscene->attributes_float2,
912  attr_float2_offset,
913  dscene->attributes_float3,
914  attr_float3_offset,
915  dscene->attributes_uchar4,
916  attr_uchar4_offset,
917  attr,
919  req.type,
920  req.desc);
921 
922  /* object attributes don't care about subdivision */
923  req.subd_type = req.type;
924  req.subd_desc = req.desc;
925 
926  if (progress.get_cancel())
927  return;
928  }
929  }
930 
931  /* create attribute lookup maps */
932  if (scene->shader_manager->use_osl())
933  update_osl_attributes(device, scene, geom_attributes);
934 
935  update_svm_attributes(device, dscene, scene, geom_attributes, object_attributes);
936 
937  if (progress.get_cancel())
938  return;
939 
940  /* copy to device */
941  progress.set_status("Updating Mesh", "Copying Attributes to device");
942 
947 
948  if (progress.get_cancel())
949  return;
950 
951  /* After mesh attributes and patch tables have been copied to device memory,
952  * we need to update offsets in the objects. */
954 }
955 
957 {
958  size_t vert_size = 0;
959  size_t tri_size = 0;
960 
961  size_t curve_key_size = 0;
962  size_t curve_size = 0;
963 
964  size_t patch_size = 0;
965  size_t face_size = 0;
966  size_t corner_size = 0;
967 
968  size_t optix_prim_size = 0;
969 
970  foreach (Geometry *geom, scene->geometry) {
971  if (geom->optix_prim_offset != optix_prim_size) {
972  /* Need to rebuild BVH in OptiX, since refit only allows modified mesh data there */
973  const bool has_optix_bvh = bvh_layout == BVH_LAYOUT_OPTIX ||
974  bvh_layout == BVH_LAYOUT_MULTI_OPTIX ||
975  bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE;
976  geom->need_update_rebuild |= has_optix_bvh;
977  geom->need_update_bvh_for_offset = true;
978  }
979 
980  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
981  Mesh *mesh = static_cast<Mesh *>(geom);
982 
983  mesh->vert_offset = vert_size;
984  mesh->prim_offset = tri_size;
985 
986  mesh->patch_offset = patch_size;
987  mesh->face_offset = face_size;
988  mesh->corner_offset = corner_size;
989 
990  vert_size += mesh->verts.size();
991  tri_size += mesh->num_triangles();
992 
993  if (mesh->get_num_subd_faces()) {
995  patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
996 
997  /* patch tables are stored in same array so include them in patch_size */
998  if (mesh->patch_table) {
999  mesh->patch_table_offset = patch_size;
1000  patch_size += mesh->patch_table->total_size();
1001  }
1002  }
1003 
1004  face_size += mesh->get_num_subd_faces();
1005  corner_size += mesh->subd_face_corners.size();
1006 
1007  mesh->optix_prim_offset = optix_prim_size;
1008  optix_prim_size += mesh->num_triangles();
1009  }
1010  else if (geom->is_hair()) {
1011  Hair *hair = static_cast<Hair *>(geom);
1012 
1013  hair->curvekey_offset = curve_key_size;
1014  hair->prim_offset = curve_size;
1015 
1016  curve_key_size += hair->get_curve_keys().size();
1017  curve_size += hair->num_curves();
1018 
1019  hair->optix_prim_offset = optix_prim_size;
1020  optix_prim_size += hair->num_segments();
1021  }
1022  }
1023 }
1024 
1026  Device *, DeviceScene *dscene, Scene *scene, bool for_displacement, Progress &progress)
1027 {
1028  /* Count. */
1029  size_t vert_size = 0;
1030  size_t tri_size = 0;
1031 
1032  size_t curve_key_size = 0;
1033  size_t curve_size = 0;
1034 
1035  size_t patch_size = 0;
1036 
1037  foreach (Geometry *geom, scene->geometry) {
1038  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
1039  Mesh *mesh = static_cast<Mesh *>(geom);
1040 
1041  vert_size += mesh->verts.size();
1042  tri_size += mesh->num_triangles();
1043 
1044  if (mesh->get_num_subd_faces()) {
1046  patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
1047 
1048  /* patch tables are stored in same array so include them in patch_size */
1049  if (mesh->patch_table) {
1050  mesh->patch_table_offset = patch_size;
1051  patch_size += mesh->patch_table->total_size();
1052  }
1053  }
1054  }
1055  else if (geom->is_hair()) {
1056  Hair *hair = static_cast<Hair *>(geom);
1057 
1058  curve_key_size += hair->get_curve_keys().size();
1059  curve_size += hair->num_curves();
1060  }
1061  }
1062 
1063  /* Create mapping from triangle to primitive triangle array. */
1064  vector<uint> tri_prim_index(tri_size);
1065  if (for_displacement) {
1066  /* For displacement kernels we do some trickery to make them believe
1067  * we've got all required data ready. However, that data is different
1068  * from final render kernels since we don't have BVH yet, so can't
1069  * really use same semantic of arrays.
1070  */
1071  foreach (Geometry *geom, scene->geometry) {
1072  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
1073  Mesh *mesh = static_cast<Mesh *>(geom);
1074  for (size_t i = 0; i < mesh->num_triangles(); ++i) {
1075  tri_prim_index[i + mesh->prim_offset] = 3 * (i + mesh->prim_offset);
1076  }
1077  }
1078  }
1079  }
1080  else {
1081  for (size_t i = 0; i < dscene->prim_index.size(); ++i) {
1082  if ((dscene->prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
1083  tri_prim_index[dscene->prim_index[i]] = dscene->prim_tri_index[i];
1084  }
1085  }
1086  }
1087 
1088  /* Fill in all the arrays. */
1089  if (tri_size != 0) {
1090  /* normals */
1091  progress.set_status("Updating Mesh", "Computing normals");
1092 
1093  uint *tri_shader = dscene->tri_shader.alloc(tri_size);
1094  float4 *vnormal = dscene->tri_vnormal.alloc(vert_size);
1095  uint4 *tri_vindex = dscene->tri_vindex.alloc(tri_size);
1096  uint *tri_patch = dscene->tri_patch.alloc(tri_size);
1097  float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size);
1098 
1099  const bool copy_all_data = dscene->tri_shader.need_realloc() ||
1100  dscene->tri_vindex.need_realloc() ||
1101  dscene->tri_vnormal.need_realloc() ||
1102  dscene->tri_patch.need_realloc() ||
1103  dscene->tri_patch_uv.need_realloc();
1104 
1105  foreach (Geometry *geom, scene->geometry) {
1106  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
1107  Mesh *mesh = static_cast<Mesh *>(geom);
1108 
1109  if (mesh->shader_is_modified() || mesh->smooth_is_modified() ||
1110  mesh->triangles_is_modified() || copy_all_data) {
1111  mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]);
1112  }
1113 
1114  if (mesh->verts_is_modified() || copy_all_data) {
1115  mesh->pack_normals(&vnormal[mesh->vert_offset]);
1116  }
1117 
1118  if (mesh->triangles_is_modified() || mesh->vert_patch_uv_is_modified() || copy_all_data) {
1119  mesh->pack_verts(tri_prim_index,
1120  &tri_vindex[mesh->prim_offset],
1121  &tri_patch[mesh->prim_offset],
1122  &tri_patch_uv[mesh->vert_offset],
1123  mesh->vert_offset,
1124  mesh->prim_offset);
1125  }
1126 
1127  if (progress.get_cancel())
1128  return;
1129  }
1130  }
1131 
1132  /* vertex coordinates */
1133  progress.set_status("Updating Mesh", "Copying Mesh to device");
1134 
1140  }
1141 
1142  if (curve_size != 0) {
1143  progress.set_status("Updating Mesh", "Copying Strands to device");
1144 
1145  float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size);
1146  float4 *curves = dscene->curves.alloc(curve_size);
1147 
1148  const bool copy_all_data = dscene->curve_keys.need_realloc() || dscene->curves.need_realloc();
1149 
1150  foreach (Geometry *geom, scene->geometry) {
1151  if (geom->is_hair()) {
1152  Hair *hair = static_cast<Hair *>(geom);
1153 
1154  bool curve_keys_co_modified = hair->curve_radius_is_modified() ||
1155  hair->curve_keys_is_modified();
1156  bool curve_data_modified = hair->curve_shader_is_modified() ||
1157  hair->curve_first_key_is_modified();
1158 
1159  if (!curve_keys_co_modified && !curve_data_modified && !copy_all_data) {
1160  continue;
1161  }
1162 
1163  hair->pack_curves(scene,
1164  &curve_keys[hair->curvekey_offset],
1165  &curves[hair->prim_offset],
1166  hair->curvekey_offset);
1167  if (progress.get_cancel())
1168  return;
1169  }
1170  }
1171 
1174  }
1175 
1176  if (patch_size != 0 && dscene->patches.need_realloc()) {
1177  progress.set_status("Updating Mesh", "Copying Patches to device");
1178 
1179  uint *patch_data = dscene->patches.alloc(patch_size);
1180 
1181  foreach (Geometry *geom, scene->geometry) {
1182  if (geom->is_mesh()) {
1183  Mesh *mesh = static_cast<Mesh *>(geom);
1184  mesh->pack_patches(&patch_data[mesh->patch_offset],
1185  mesh->vert_offset,
1186  mesh->face_offset,
1187  mesh->corner_offset);
1188 
1189  if (mesh->patch_table) {
1190  mesh->patch_table->copy_adjusting_offsets(&patch_data[mesh->patch_table_offset],
1191  mesh->patch_table_offset);
1192  }
1193 
1194  if (progress.get_cancel())
1195  return;
1196  }
1197  }
1198 
1199  dscene->patches.copy_to_device();
1200  }
1201 
1202  if (for_displacement) {
1203  float4 *prim_tri_verts = dscene->prim_tri_verts.alloc(tri_size * 3);
1204  foreach (Geometry *geom, scene->geometry) {
1205  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
1206  Mesh *mesh = static_cast<Mesh *>(geom);
1207  for (size_t i = 0; i < mesh->num_triangles(); ++i) {
1209  size_t offset = 3 * (i + mesh->prim_offset);
1210  prim_tri_verts[offset + 0] = float3_to_float4(mesh->verts[t.v[0]]);
1211  prim_tri_verts[offset + 1] = float3_to_float4(mesh->verts[t.v[1]]);
1212  prim_tri_verts[offset + 2] = float3_to_float4(mesh->verts[t.v[2]]);
1213  }
1214  }
1215  }
1216  dscene->prim_tri_verts.copy_to_device();
1217  }
1218 }
1219 
1221  DeviceScene *dscene,
1222  Scene *scene,
1223  Progress &progress)
1224 {
1225  /* bvh build */
1226  progress.set_status("Updating Scene BVH", "Building");
1227 
1228  BVHParams bparams;
1229  bparams.top_level = true;
1231  device->get_bvh_layout_mask());
1233  bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
1237  bparams.bvh_type = scene->params.bvh_type;
1239 
1240  VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
1241 
1242  const bool can_refit = scene->bvh != nullptr &&
1244 
1245  PackFlags pack_flags = PackFlags::PACK_NONE;
1246 
1247  if (scene->bvh == nullptr) {
1248  pack_flags |= PackFlags::PACK_ALL;
1249  }
1250 
1251  if (dscene->prim_visibility.is_modified()) {
1252  pack_flags |= PackFlags::PACK_VISIBILITY;
1253  }
1254 
1255  BVH *bvh = scene->bvh;
1256  if (!scene->bvh) {
1257  bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
1258  }
1259 
1260  device->build_bvh(bvh, progress, can_refit);
1261 
1262  if (progress.get_cancel()) {
1263  return;
1264  }
1265 
1266  const bool has_bvh2_layout = (bparams.bvh_layout == BVH_LAYOUT_BVH2);
1267 
1268  PackedBVH pack;
1269  if (has_bvh2_layout) {
1270  pack = std::move(static_cast<BVH2 *>(bvh)->pack);
1271  }
1272  else {
1273  progress.set_status("Updating Scene BVH", "Packing BVH primitives");
1274 
1275  size_t num_prims = 0;
1276  size_t num_tri_verts = 0;
1277  foreach (Geometry *geom, scene->geometry) {
1278  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
1279  Mesh *mesh = static_cast<Mesh *>(geom);
1280  num_prims += mesh->num_triangles();
1281  num_tri_verts += 3 * mesh->num_triangles();
1282  }
1283  else if (geom->is_hair()) {
1284  Hair *hair = static_cast<Hair *>(geom);
1285  num_prims += hair->num_segments();
1286  }
1287  }
1288 
1289  pack.root_index = -1;
1290 
1291  if (pack_flags != PackFlags::PACK_ALL) {
1292  /* if we do not need to recreate the BVH, then only the vertices are updated, so we can
1293  * safely retake the memory */
1294  dscene->prim_tri_verts.give_data(pack.prim_tri_verts);
1295 
1296  if ((pack_flags & PackFlags::PACK_VISIBILITY) != 0) {
1298  }
1299  }
1300  else {
1301  /* It is not strictly necessary to skip those resizes we if do not have to repack, as the OS
1302  * will not allocate pages if we do not touch them, however it does help catching bugs. */
1303  pack.prim_tri_index.resize(num_prims);
1304  pack.prim_tri_verts.resize(num_tri_verts);
1305  pack.prim_type.resize(num_prims);
1306  pack.prim_index.resize(num_prims);
1307  pack.prim_object.resize(num_prims);
1308  pack.prim_visibility.resize(num_prims);
1309  }
1310 
1311  // Merge visibility flags of all objects and find object index for non-instanced geometry
1312  unordered_map<const Geometry *, pair<int, uint>> geometry_to_object_info;
1313  geometry_to_object_info.reserve(scene->geometry.size());
1314  foreach (Object *ob, scene->objects) {
1315  const Geometry *const geom = ob->get_geometry();
1316  pair<int, uint> &info = geometry_to_object_info[geom];
1317  info.second |= ob->visibility_for_tracing();
1318  if (!geom->is_instanced()) {
1319  info.first = ob->get_device_index();
1320  }
1321  }
1322 
1323  TaskPool pool;
1324  // Iterate over scene mesh list instead of objects, since 'optix_prim_offset' was calculated
1325  // based on that list, which may be ordered differently from the object list.
1326  foreach (Geometry *geom, scene->geometry) {
1327  /* Make a copy of the pack_flags so the current geometry's flags do not pollute the others'.
1328  */
1329  PackFlags geom_pack_flags = pack_flags;
1330 
1331  if (geom->is_modified()) {
1332  geom_pack_flags |= PackFlags::PACK_VERTICES;
1333  }
1334 
1335  if (geom_pack_flags == PACK_NONE) {
1336  continue;
1337  }
1338 
1339  const pair<int, uint> &info = geometry_to_object_info[geom];
1341  &Geometry::pack_primitives, geom, &pack, info.first, info.second, geom_pack_flags));
1342  }
1343  pool.wait_work();
1344  }
1345 
1346  /* copy to device */
1347  progress.set_status("Updating Scene BVH", "Copying BVH to device");
1348 
1349  /* When using BVH2, we always have to copy/update the data as its layout is dependent on the
1350  * BVH's leaf nodes which may be different when the objects or vertices move. */
1351 
1352  if (pack.nodes.size()) {
1353  dscene->bvh_nodes.steal_data(pack.nodes);
1354  dscene->bvh_nodes.copy_to_device();
1355  }
1356  if (pack.leaf_nodes.size()) {
1357  dscene->bvh_leaf_nodes.steal_data(pack.leaf_nodes);
1358  dscene->bvh_leaf_nodes.copy_to_device();
1359  }
1360  if (pack.object_node.size()) {
1361  dscene->object_node.steal_data(pack.object_node);
1362  dscene->object_node.copy_to_device();
1363  }
1364  if (pack.prim_tri_index.size() && (dscene->prim_tri_index.need_realloc() || has_bvh2_layout)) {
1366  dscene->prim_tri_index.copy_to_device();
1367  }
1368  if (pack.prim_tri_verts.size()) {
1370  dscene->prim_tri_verts.copy_to_device();
1371  }
1372  if (pack.prim_type.size() && (dscene->prim_type.need_realloc() || has_bvh2_layout)) {
1373  dscene->prim_type.steal_data(pack.prim_type);
1374  dscene->prim_type.copy_to_device();
1375  }
1376  if (pack.prim_visibility.size() && (dscene->prim_visibility.is_modified() || has_bvh2_layout)) {
1378  dscene->prim_visibility.copy_to_device();
1379  }
1380  if (pack.prim_index.size() && (dscene->prim_index.need_realloc() || has_bvh2_layout)) {
1381  dscene->prim_index.steal_data(pack.prim_index);
1382  dscene->prim_index.copy_to_device();
1383  }
1384  if (pack.prim_object.size() && (dscene->prim_object.need_realloc() || has_bvh2_layout)) {
1385  dscene->prim_object.steal_data(pack.prim_object);
1386  dscene->prim_object.copy_to_device();
1387  }
1388  if (pack.prim_time.size() && (dscene->prim_time.need_realloc() || has_bvh2_layout)) {
1389  dscene->prim_time.steal_data(pack.prim_time);
1390  dscene->prim_time.copy_to_device();
1391  }
1392 
1393  dscene->data.bvh.root = pack.root_index;
1396  /* The scene handle is set in 'CPUDevice::const_copy_to' and 'OptiXDevice::const_copy_to' */
1397  dscene->data.bvh.scene = 0;
1398 }
1399 
1400 /* Set of flags used to help determining what data has been modified or needs reallocation, so we
1401  * can decide which device data to free or update. */
1402 enum {
1405 
1410 
1413 
1418 
1423 };
1424 
1425 static void update_device_flags_attribute(uint32_t &device_update_flags,
1426  const AttributeSet &attributes)
1427 {
1428  foreach (const Attribute &attr, attributes.attributes) {
1429  if (!attr.modified) {
1430  continue;
1431  }
1432 
1433  if (attr.element == ATTR_ELEMENT_CORNER) {
1434  device_update_flags |= ATTR_UCHAR4_MODIFIED;
1435  }
1436  else if (attr.type == TypeDesc::TypeFloat) {
1437  device_update_flags |= ATTR_FLOAT_MODIFIED;
1438  }
1439  else if (attr.type == TypeFloat2) {
1440  device_update_flags |= ATTR_FLOAT2_MODIFIED;
1441  }
1442  else if (attr.type == TypeDesc::TypeMatrix) {
1443  device_update_flags |= ATTR_FLOAT3_MODIFIED;
1444  }
1445  else if (attr.element != ATTR_ELEMENT_VOXEL) {
1446  device_update_flags |= ATTR_FLOAT3_MODIFIED;
1447  }
1448  }
1449 }
1450 
1452 {
1453  if (!need_update() && !need_flags_update) {
1454  return;
1455  }
1456 
1457  uint32_t device_update_flags = 0;
1458 
1459  scoped_callback_timer timer([scene](double time) {
1460  if (scene->update_stats) {
1461  scene->update_stats->geometry.times.add_entry({"device_update_preprocess", time});
1462  }
1463  });
1464 
1465  progress.set_status("Updating Meshes Flags");
1466 
1467  /* Update flags. */
1468  bool volume_images_updated = false;
1469 
1470  foreach (Geometry *geom, scene->geometry) {
1471  geom->has_volume = false;
1472 
1473  if (geom->attributes.modified) {
1474  device_update_flags |= ATTRS_NEED_REALLOC;
1475  }
1476 
1477  if (geom->is_mesh()) {
1478  Mesh *mesh = static_cast<Mesh *>(geom);
1479 
1480  if (mesh->subd_attributes.modified) {
1481  device_update_flags |= ATTRS_NEED_REALLOC;
1482  }
1483  }
1484 
1485  foreach (Node *node, geom->get_used_shaders()) {
1486  Shader *shader = static_cast<Shader *>(node);
1487  if (shader->has_volume) {
1488  geom->has_volume = true;
1489  }
1490 
1491  if (shader->has_surface_bssrdf) {
1492  geom->has_surface_bssrdf = true;
1493  }
1494 
1495  if (shader->need_update_uvs) {
1496  device_update_flags |= ATTR_FLOAT2_NEEDS_REALLOC;
1497 
1498  /* Attributes might need to be tessellated if added. */
1499  if (geom->is_mesh()) {
1500  Mesh *mesh = static_cast<Mesh *>(geom);
1501  if (mesh->need_tesselation()) {
1502  mesh->tag_modified();
1503  }
1504  }
1505  }
1506 
1507  if (shader->need_update_attribute) {
1508  device_update_flags |= ATTRS_NEED_REALLOC;
1509 
1510  /* Attributes might need to be tessellated if added. */
1511  if (geom->is_mesh()) {
1512  Mesh *mesh = static_cast<Mesh *>(geom);
1513  if (mesh->need_tesselation()) {
1514  mesh->tag_modified();
1515  }
1516  }
1517  }
1518 
1519  if (shader->need_update_displacement) {
1520  /* tag displacement related sockets as modified */
1521  if (geom->is_mesh()) {
1522  Mesh *mesh = static_cast<Mesh *>(geom);
1523  mesh->tag_verts_modified();
1524  mesh->tag_subd_dicing_rate_modified();
1525  mesh->tag_subd_max_level_modified();
1526  mesh->tag_subd_objecttoworld_modified();
1527 
1528  device_update_flags |= ATTRS_NEED_REALLOC;
1529  }
1530  }
1531  }
1532 
1533  /* only check for modified attributes if we do not need to reallocate them already */
1534  if ((device_update_flags & ATTRS_NEED_REALLOC) == 0) {
1535  update_device_flags_attribute(device_update_flags, geom->attributes);
1536  /* don't check for subd_attributes, as if they were modified, we would need to reallocate
1537  * anyway */
1538  }
1539 
1540  /* Re-create volume mesh if we will rebuild or refit the BVH. Note we
1541  * should only do it in that case, otherwise the BVH and mesh can go
1542  * out of sync. */
1543  if (geom->is_modified() && geom->geometry_type == Geometry::VOLUME) {
1544  /* Create volume meshes if there is voxel data. */
1545  if (!volume_images_updated) {
1546  progress.set_status("Updating Meshes Volume Bounds");
1547  device_update_volume_images(device, scene, progress);
1548  volume_images_updated = true;
1549  }
1550 
1551  Volume *volume = static_cast<Volume *>(geom);
1552  create_volume_mesh(volume, progress);
1553 
1554  /* always reallocate when we have a volume, as we need to rebuild the BVH */
1555  device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
1556  }
1557 
1558  if (geom->is_hair()) {
1559  /* Set curve shape, still a global scene setting for now. */
1560  Hair *hair = static_cast<Hair *>(geom);
1562 
1563  if (hair->need_update_rebuild) {
1564  device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
1565  }
1566  else if (hair->is_modified()) {
1567  device_update_flags |= DEVICE_CURVE_DATA_MODIFIED;
1568  }
1569  }
1570 
1571  if (geom->is_mesh()) {
1572  Mesh *mesh = static_cast<Mesh *>(geom);
1573 
1574  if (mesh->need_update_rebuild) {
1575  device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
1576  }
1577  else if (mesh->is_modified()) {
1578  device_update_flags |= DEVICE_MESH_DATA_MODIFIED;
1579  }
1580  }
1581  }
1582 
1583  if (update_flags & (MESH_ADDED | MESH_REMOVED)) {
1584  device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
1585  }
1586 
1587  if (update_flags & (HAIR_ADDED | HAIR_REMOVED)) {
1588  device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
1589  }
1590 
1591  /* tag the device arrays for reallocation or modification */
1592  DeviceScene *dscene = &scene->dscene;
1593 
1594  if (device_update_flags & (DEVICE_MESH_DATA_NEEDS_REALLOC | DEVICE_CURVE_DATA_NEEDS_REALLOC)) {
1595  delete scene->bvh;
1596  scene->bvh = nullptr;
1597 
1598  dscene->bvh_nodes.tag_realloc();
1599  dscene->bvh_leaf_nodes.tag_realloc();
1600  dscene->object_node.tag_realloc();
1601  dscene->prim_tri_verts.tag_realloc();
1602  dscene->prim_tri_index.tag_realloc();
1603  dscene->prim_type.tag_realloc();
1604  dscene->prim_visibility.tag_realloc();
1605  dscene->prim_index.tag_realloc();
1606  dscene->prim_object.tag_realloc();
1607  dscene->prim_time.tag_realloc();
1608 
1609  if (device_update_flags & DEVICE_MESH_DATA_NEEDS_REALLOC) {
1610  dscene->tri_vnormal.tag_realloc();
1611  dscene->tri_vindex.tag_realloc();
1612  dscene->tri_patch.tag_realloc();
1613  dscene->tri_patch_uv.tag_realloc();
1614  dscene->tri_shader.tag_realloc();
1615  dscene->patches.tag_realloc();
1616  }
1617 
1618  if (device_update_flags & DEVICE_CURVE_DATA_NEEDS_REALLOC) {
1619  dscene->curves.tag_realloc();
1620  dscene->curve_keys.tag_realloc();
1621  }
1622  }
1623 
1624  if ((update_flags & VISIBILITY_MODIFIED) != 0) {
1625  dscene->prim_visibility.tag_modified();
1626  }
1627 
1628  if (device_update_flags & ATTR_FLOAT_NEEDS_REALLOC) {
1629  dscene->attributes_map.tag_realloc();
1630  dscene->attributes_float.tag_realloc();
1631  }
1632  else if (device_update_flags & ATTR_FLOAT_MODIFIED) {
1633  dscene->attributes_float.tag_modified();
1634  }
1635 
1636  if (device_update_flags & ATTR_FLOAT2_NEEDS_REALLOC) {
1637  dscene->attributes_map.tag_realloc();
1638  dscene->attributes_float2.tag_realloc();
1639  }
1640  else if (device_update_flags & ATTR_FLOAT2_MODIFIED) {
1641  dscene->attributes_float2.tag_modified();
1642  }
1643 
1644  if (device_update_flags & ATTR_FLOAT3_NEEDS_REALLOC) {
1645  dscene->attributes_map.tag_realloc();
1646  dscene->attributes_float3.tag_realloc();
1647  }
1648  else if (device_update_flags & ATTR_FLOAT3_MODIFIED) {
1649  dscene->attributes_float3.tag_modified();
1650  }
1651 
1652  if (device_update_flags & ATTR_UCHAR4_NEEDS_REALLOC) {
1653  dscene->attributes_map.tag_realloc();
1654  dscene->attributes_uchar4.tag_realloc();
1655  }
1656  else if (device_update_flags & ATTR_UCHAR4_MODIFIED) {
1657  dscene->attributes_uchar4.tag_modified();
1658  }
1659 
1660  if (device_update_flags & DEVICE_MESH_DATA_MODIFIED) {
1661  /* if anything else than vertices or shaders are modified, we would need to reallocate, so
1662  * these are the only arrays that can be updated */
1663  dscene->tri_vnormal.tag_modified();
1664  dscene->tri_shader.tag_modified();
1665  }
1666 
1667  if (device_update_flags & DEVICE_CURVE_DATA_MODIFIED) {
1668  dscene->curve_keys.tag_modified();
1669  dscene->curves.tag_modified();
1670  }
1671 
1672  need_flags_update = false;
1673 }
1674 
1676  Scene *scene,
1677  Progress &progress)
1678 {
1679  progress.set_status("Updating Displacement Images");
1680  TaskPool pool;
1681  ImageManager *image_manager = scene->image_manager;
1682  set<int> bump_images;
1683  foreach (Geometry *geom, scene->geometry) {
1684  if (geom->is_modified()) {
1685  foreach (Node *node, geom->get_used_shaders()) {
1686  Shader *shader = static_cast<Shader *>(node);
1687  if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) {
1688  continue;
1689  }
1690  foreach (ShaderNode *node, shader->graph->nodes) {
1691  if (node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
1692  continue;
1693  }
1694 
1695  ImageSlotTextureNode *image_node = static_cast<ImageSlotTextureNode *>(node);
1696  for (int i = 0; i < image_node->handle.num_tiles(); i++) {
1697  const int slot = image_node->handle.svm_slot(i);
1698  if (slot != -1) {
1699  bump_images.insert(slot);
1700  }
1701  }
1702  }
1703  }
1704  }
1705  }
1706  foreach (int slot, bump_images) {
1708  &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress));
1709  }
1710  pool.wait_work();
1711 }
1712 
1714 {
1715  progress.set_status("Updating Volume Images");
1716  TaskPool pool;
1717  ImageManager *image_manager = scene->image_manager;
1718  set<int> volume_images;
1719 
1720  foreach (Geometry *geom, scene->geometry) {
1721  if (!geom->is_modified()) {
1722  continue;
1723  }
1724 
1725  foreach (Attribute &attr, geom->attributes.attributes) {
1726  if (attr.element != ATTR_ELEMENT_VOXEL) {
1727  continue;
1728  }
1729 
1730  ImageHandle &handle = attr.data_voxel();
1731  /* We can build directly from OpenVDB data structures, no need to
1732  * load such images early. */
1733  if (!handle.vdb_loader()) {
1734  const int slot = handle.svm_slot();
1735  if (slot != -1) {
1736  volume_images.insert(slot);
1737  }
1738  }
1739  }
1740  }
1741 
1742  foreach (int slot, volume_images) {
1744  &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress));
1745  }
1746  pool.wait_work();
1747 }
1748 
1750  DeviceScene *dscene,
1751  Scene *scene,
1752  Progress &progress)
1753 {
1754  if (!need_update())
1755  return;
1756 
1757  VLOG(1) << "Total " << scene->geometry.size() << " meshes.";
1758 
1759  bool true_displacement_used = false;
1760  size_t total_tess_needed = 0;
1761 
1762  {
1763  scoped_callback_timer timer([scene](double time) {
1764  if (scene->update_stats) {
1765  scene->update_stats->geometry.times.add_entry({"device_update (normals)", time});
1766  }
1767  });
1768 
1769  foreach (Geometry *geom, scene->geometry) {
1770  if (geom->is_modified() &&
1772  Mesh *mesh = static_cast<Mesh *>(geom);
1773 
1774  /* Update normals. */
1777 
1779  mesh->add_undisplaced();
1780  }
1781 
1782  /* Test if we need tessellation. */
1783  if (mesh->need_tesselation()) {
1784  total_tess_needed++;
1785  }
1786 
1787  /* Test if we need displacement. */
1788  if (mesh->has_true_displacement()) {
1789  true_displacement_used = true;
1790  }
1791 
1792  if (progress.get_cancel()) {
1793  return;
1794  }
1795  }
1796  }
1797  }
1798 
1799  if (progress.get_cancel()) {
1800  return;
1801  }
1802 
1803  /* Tessellate meshes that are using subdivision */
1804  if (total_tess_needed) {
1805  scoped_callback_timer timer([scene](double time) {
1806  if (scene->update_stats) {
1807  scene->update_stats->geometry.times.add_entry(
1808  {"device_update (adaptive subdivision)", time});
1809  }
1810  });
1811 
1812  Camera *dicing_camera = scene->dicing_camera;
1813  dicing_camera->set_screen_size_and_resolution(
1814  dicing_camera->get_full_width(), dicing_camera->get_full_height(), 1);
1815  dicing_camera->update(scene);
1816 
1817  size_t i = 0;
1818  foreach (Geometry *geom, scene->geometry) {
1819  if (!(geom->is_modified() && geom->is_mesh())) {
1820  continue;
1821  }
1822 
1823  Mesh *mesh = static_cast<Mesh *>(geom);
1824  if (mesh->need_tesselation()) {
1825  string msg = "Tessellating ";
1826  if (mesh->name == "")
1827  msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed);
1828  else
1829  msg += string_printf(
1830  "%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)total_tess_needed);
1831 
1832  progress.set_status("Updating Mesh", msg);
1833 
1834  mesh->subd_params->camera = dicing_camera;
1835  DiagSplit dsplit(*mesh->subd_params);
1836  mesh->tessellate(&dsplit);
1837 
1838  i++;
1839 
1840  if (progress.get_cancel()) {
1841  return;
1842  }
1843  }
1844  }
1845 
1846  if (progress.get_cancel()) {
1847  return;
1848  }
1849  }
1850 
1851  /* Update images needed for true displacement. */
1852  bool old_need_object_flags_update = false;
1853  if (true_displacement_used) {
1854  scoped_callback_timer timer([scene](double time) {
1855  if (scene->update_stats) {
1856  scene->update_stats->geometry.times.add_entry(
1857  {"device_update (displacement: load images)", time});
1858  }
1859  });
1860  device_update_displacement_images(device, scene, progress);
1861  old_need_object_flags_update = scene->object_manager->need_flags_update;
1862  scene->object_manager->device_update_flags(device, dscene, scene, progress, false);
1863  }
1864 
1865  /* Device update. */
1866  device_free(device, dscene, false);
1867 
1869  device->get_bvh_layout_mask());
1870  mesh_calc_offset(scene, bvh_layout);
1871  if (true_displacement_used) {
1872  scoped_callback_timer timer([scene](double time) {
1873  if (scene->update_stats) {
1874  scene->update_stats->geometry.times.add_entry(
1875  {"device_update (displacement: copy meshes to device)", time});
1876  }
1877  });
1878  device_update_mesh(device, dscene, scene, true, progress);
1879  }
1880  if (progress.get_cancel()) {
1881  return;
1882  }
1883 
1884  {
1885  scoped_callback_timer timer([scene](double time) {
1886  if (scene->update_stats) {
1887  scene->update_stats->geometry.times.add_entry({"device_update (attributes)", time});
1888  }
1889  });
1890  device_update_attributes(device, dscene, scene, progress);
1891  if (progress.get_cancel()) {
1892  return;
1893  }
1894  }
1895 
1896  /* Update displacement. */
1897  bool displacement_done = false;
1898  size_t num_bvh = 0;
1899 
1900  {
1901  scoped_callback_timer timer([scene](double time) {
1902  if (scene->update_stats) {
1903  scene->update_stats->geometry.times.add_entry({"device_update (displacement)", time});
1904  }
1905  });
1906 
1907  foreach (Geometry *geom, scene->geometry) {
1908  if (geom->is_modified()) {
1909  if (geom->is_mesh()) {
1910  Mesh *mesh = static_cast<Mesh *>(geom);
1911  if (displace(device, dscene, scene, mesh, progress)) {
1912  displacement_done = true;
1913  }
1914  }
1915  }
1916 
1917  if (geom->is_modified() || geom->need_update_bvh_for_offset) {
1918  if (geom->need_build_bvh(bvh_layout)) {
1919  num_bvh++;
1920  }
1921  }
1922 
1923  if (progress.get_cancel()) {
1924  return;
1925  }
1926  }
1927  }
1928 
1929  if (progress.get_cancel()) {
1930  return;
1931  }
1932 
1933  /* Device re-update after displacement. */
1934  if (displacement_done) {
1935  scoped_callback_timer timer([scene](double time) {
1936  if (scene->update_stats) {
1937  scene->update_stats->geometry.times.add_entry(
1938  {"device_update (displacement: attributes)", time});
1939  }
1940  });
1941  device_free(device, dscene, false);
1942 
1943  device_update_attributes(device, dscene, scene, progress);
1944  if (progress.get_cancel()) {
1945  return;
1946  }
1947  }
1948 
1949  /* Update the BVH even when there is no geometry so the kernel's BVH data is still valid,
1950  * especially when removing all of the objects during interactive renders.
1951  * Also update the BVH if the transformations change, we cannot rely on tagging the Geometry
1952  * as modified in this case, as we may accumulate displacement if the vertices do not also
1953  * change. */
1954  bool need_update_scene_bvh = (scene->bvh == nullptr ||
1955  (update_flags & (TRANSFORM_MODIFIED | VISIBILITY_MODIFIED)) != 0);
1956  {
1957  scoped_callback_timer timer([scene](double time) {
1958  if (scene->update_stats) {
1959  scene->update_stats->geometry.times.add_entry({"device_update (build object BVHs)", time});
1960  }
1961  });
1962  TaskPool pool;
1963 
1964  size_t i = 0;
1965  foreach (Geometry *geom, scene->geometry) {
1966  if (geom->is_modified() || geom->need_update_bvh_for_offset) {
1967  need_update_scene_bvh = true;
1969  &Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh));
1970  if (geom->need_build_bvh(bvh_layout)) {
1971  i++;
1972  }
1973  }
1974  }
1975 
1976  TaskPool::Summary summary;
1977  pool.wait_work(&summary);
1978  VLOG(2) << "Objects BVH build pool statistics:\n" << summary.full_report();
1979  }
1980 
1981  foreach (Shader *shader, scene->shaders) {
1982  shader->need_update_uvs = false;
1983  shader->need_update_attribute = false;
1984  shader->need_update_displacement = false;
1985  }
1986 
1987  Scene::MotionType need_motion = scene->need_motion();
1988  bool motion_blur = need_motion == Scene::MOTION_BLUR;
1989 
1990  /* Update objects. */
1991  {
1992  scoped_callback_timer timer([scene](double time) {
1993  if (scene->update_stats) {
1994  scene->update_stats->geometry.times.add_entry({"device_update (compute bounds)", time});
1995  }
1996  });
1997  foreach (Object *object, scene->objects) {
1998  object->compute_bounds(motion_blur);
1999  }
2000  }
2001 
2002  if (progress.get_cancel()) {
2003  return;
2004  }
2005 
2006  if (need_update_scene_bvh) {
2007  scoped_callback_timer timer([scene](double time) {
2008  if (scene->update_stats) {
2009  scene->update_stats->geometry.times.add_entry({"device_update (build scene BVH)", time});
2010  }
2011  });
2012  device_update_bvh(device, dscene, scene, progress);
2013  if (progress.get_cancel()) {
2014  return;
2015  }
2016  }
2017 
2018  /* Always set BVH layout again after displacement where it was set to none,
2019  * to avoid ray-tracing at that stage. */
2021  device->get_bvh_layout_mask());
2022 
2023  {
2024  scoped_callback_timer timer([scene](double time) {
2025  if (scene->update_stats) {
2026  scene->update_stats->geometry.times.add_entry(
2027  {"device_update (copy meshes to device)", time});
2028  }
2029  });
2030  device_update_mesh(device, dscene, scene, false, progress);
2031  if (progress.get_cancel()) {
2032  return;
2033  }
2034  }
2035 
2036  if (true_displacement_used) {
2037  /* Re-tag flags for update, so they're re-evaluated
2038  * for meshes with correct bounding boxes.
2039  *
2040  * This wouldn't cause wrong results, just true
2041  * displacement might be less optimal ot calculate.
2042  */
2043  scene->object_manager->need_flags_update = old_need_object_flags_update;
2044  }
2045 
2046  /* unset flags */
2047 
2048  foreach (Geometry *geom, scene->geometry) {
2049  geom->clear_modified();
2050  geom->attributes.clear_modified();
2051 
2052  if (geom->is_mesh()) {
2053  Mesh *mesh = static_cast<Mesh *>(geom);
2054  mesh->subd_attributes.clear_modified();
2055  }
2056  }
2057 
2058  update_flags = UPDATE_NONE;
2059 
2060  dscene->bvh_nodes.clear_modified();
2061  dscene->bvh_leaf_nodes.clear_modified();
2062  dscene->object_node.clear_modified();
2063  dscene->prim_tri_verts.clear_modified();
2064  dscene->prim_tri_index.clear_modified();
2065  dscene->prim_type.clear_modified();
2066  dscene->prim_visibility.clear_modified();
2067  dscene->prim_index.clear_modified();
2068  dscene->prim_object.clear_modified();
2069  dscene->prim_time.clear_modified();
2070  dscene->tri_shader.clear_modified();
2071  dscene->tri_vindex.clear_modified();
2072  dscene->tri_patch.clear_modified();
2073  dscene->tri_vnormal.clear_modified();
2074  dscene->tri_patch_uv.clear_modified();
2075  dscene->curves.clear_modified();
2076  dscene->curve_keys.clear_modified();
2077  dscene->patches.clear_modified();
2078  dscene->attributes_map.clear_modified();
2079  dscene->attributes_float.clear_modified();
2083 }
2084 
2085 void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool force_free)
2086 {
2087  dscene->bvh_nodes.free_if_need_realloc(force_free);
2088  dscene->bvh_leaf_nodes.free_if_need_realloc(force_free);
2089  dscene->object_node.free_if_need_realloc(force_free);
2090  dscene->prim_tri_verts.free_if_need_realloc(force_free);
2091  dscene->prim_tri_index.free_if_need_realloc(force_free);
2092  dscene->prim_type.free_if_need_realloc(force_free);
2093  dscene->prim_visibility.free_if_need_realloc(force_free);
2094  dscene->prim_index.free_if_need_realloc(force_free);
2095  dscene->prim_object.free_if_need_realloc(force_free);
2096  dscene->prim_time.free_if_need_realloc(force_free);
2097  dscene->tri_shader.free_if_need_realloc(force_free);
2098  dscene->tri_vnormal.free_if_need_realloc(force_free);
2099  dscene->tri_vindex.free_if_need_realloc(force_free);
2100  dscene->tri_patch.free_if_need_realloc(force_free);
2101  dscene->tri_patch_uv.free_if_need_realloc(force_free);
2102  dscene->curves.free_if_need_realloc(force_free);
2103  dscene->curve_keys.free_if_need_realloc(force_free);
2104  dscene->patches.free_if_need_realloc(force_free);
2105  dscene->attributes_map.free_if_need_realloc(force_free);
2106  dscene->attributes_float.free_if_need_realloc(force_free);
2107  dscene->attributes_float2.free_if_need_realloc(force_free);
2108  dscene->attributes_float3.free_if_need_realloc(force_free);
2109  dscene->attributes_uchar4.free_if_need_realloc(force_free);
2110 
2111  /* Signal for shaders like displacement not to do ray tracing. */
2112  dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE;
2113 
2114 #ifdef WITH_OSL
2115  OSLGlobals *og = (OSLGlobals *)device->osl_memory();
2116 
2117  if (og) {
2118  og->object_name_map.clear();
2119  og->attribute_map.clear();
2120  og->object_names.clear();
2121  }
2122 #else
2123  (void)device;
2124 #endif
2125 }
2126 
2128 {
2129  update_flags |= flag;
2130 
2131  /* do not tag the object manager for an update if it is the one who tagged us */
2132  if ((flag & OBJECT_MANAGER) == 0) {
2134  }
2135 }
2136 
2138 {
2139  return update_flags != UPDATE_NONE;
2140 }
2141 
2143 {
2144  foreach (Geometry *geometry, scene->geometry) {
2145  stats->mesh.geometry.add_entry(
2146  NamedSizeEntry(string(geometry->name.c_str()), geometry->get_total_size_in_bytes()));
2147  }
2148 }
2149 
unsigned int uint
Definition: BLI_sys_types.h:83
_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 type
_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
ATTR_WARN_UNUSED_RESULT const void * element
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
CCL_NAMESPACE_BEGIN const char * bvh_layout_name(BVHLayout layout)
Definition: bvh.cpp:32
CCL_NAMESPACE_BEGIN typedef KernelBVHLayout BVHLayout
Definition: bvh_params.h:32
vector< AttributeRequest > requests
Definition: attribute.h:235
bool find(ustring name)
Definition: attribute.cpp:816
void add(ustring name)
Definition: attribute.cpp:770
TypeDesc subd_type
Definition: attribute.h:222
TypeDesc type
Definition: attribute.h:222
AttributeDescriptor subd_desc
Definition: attribute.h:223
AttributeDescriptor desc
Definition: attribute.h:223
AttributeStandard std
Definition: attribute.h:219
Attribute * add(ustring name, TypeDesc type, AttributeElement element)
Definition: attribute.cpp:428
list< Attribute > attributes
Definition: attribute.h:181
Attribute * find(ustring name) const
Definition: attribute.cpp:447
void clear_modified()
Definition: attribute.cpp:697
bool modified
Definition: attribute.h:182
ImageHandle & data_voxel()
Definition: attribute.h:113
AttributeElement element
Definition: attribute.h:54
float * data_float()
Definition: attribute.h:96
uchar4 * data_uchar4()
Definition: attribute.h:101
Transform * data_transform()
Definition: attribute.h:106
TypeDesc type
Definition: attribute.h:52
size_t element_size(Geometry *geom, AttributePrimitive prim) const
Definition: attribute.cpp:185
float4 * data_float4()
Definition: attribute.h:91
vector< char > buffer
Definition: attribute.h:53
bool modified
Definition: attribute.h:57
static const char * standard_name(AttributeStandard std)
Definition: attribute.cpp:311
uint flags
Definition: attribute.h:55
float2 * data_float2()
Definition: attribute.h:81
Definition: bvh2.h:46
bool use_spatial_split
Definition: bvh_params.h:49
int num_motion_triangle_steps
Definition: bvh_params.h:86
static BVHLayout best_bvh_layout(BVHLayout requested_layout, BVHLayoutMask supported_layouts)
Definition: bvh.cpp:53
BVHLayout bvh_layout
Definition: bvh_params.h:70
bool use_unaligned_nodes
Definition: bvh_params.h:75
int curve_subdivisions
Definition: bvh_params.h:92
bool top_level
Definition: bvh_params.h:67
int bvh_type
Definition: bvh_params.h:89
int num_motion_curve_steps
Definition: bvh_params.h:83
Definition: bvh/bvh.h:80
vector< Geometry * > geometry
Definition: bvh/bvh.h:83
static BVH * create(const BVHParams &params, const vector< Geometry * > &geometry, const vector< Object * > &objects, Device *device)
Definition: bvh.cpp:85
vector< Object * > objects
Definition: bvh/bvh.h:84
device_vector< float4 > tri_vnormal
Definition: scene.h:87
device_vector< float4 > prim_tri_verts
Definition: scene.h:78
device_vector< float2 > prim_time
Definition: scene.h:83
device_vector< uint > patches
Definition: scene.h:95
device_vector< uint > prim_visibility
Definition: scene.h:80
device_vector< uint4 > tri_vindex
Definition: scene.h:88
device_vector< uint > prim_tri_index
Definition: scene.h:77
device_vector< float2 > attributes_float2
Definition: scene.h:110
device_vector< uint4 > attributes_map
Definition: scene.h:108
device_vector< float4 > curves
Definition: scene.h:92
device_vector< int > object_node
Definition: scene.h:76
device_vector< int > prim_object
Definition: scene.h:82
device_vector< float4 > curve_keys
Definition: scene.h:93
device_vector< int4 > bvh_leaf_nodes
Definition: scene.h:75
device_vector< uint > tri_shader
Definition: scene.h:86
device_vector< float > attributes_float
Definition: scene.h:109
device_vector< float2 > tri_patch_uv
Definition: scene.h:90
device_vector< uint > tri_patch
Definition: scene.h:89
KernelData data
Definition: scene.h:136
device_vector< int > prim_type
Definition: scene.h:79
device_vector< float4 > attributes_float3
Definition: scene.h:111
device_vector< int4 > bvh_nodes
Definition: scene.h:74
device_vector< int > prim_index
Definition: scene.h:81
device_vector< uchar4 > attributes_uchar4
Definition: scene.h:112
Definition: device.h:293
virtual BVHLayoutMask get_bvh_layout_mask() const =0
virtual void build_bvh(BVH *bvh, Progress &progress, bool refit)
Definition: device.cpp:369
virtual void * osl_memory()
Definition: device.h:374
void device_update_displacement_images(Device *device, Scene *scene, Progress &progress)
Definition: geometry.cpp:1675
void update_osl_attributes(Device *device, Scene *scene, vector< AttributeRequestSet > &geom_attributes)
Definition: geometry.cpp:311
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
Definition: geometry.cpp:1749
void device_update_mesh(Device *device, DeviceScene *dscene, Scene *scene, bool for_displacement, Progress &progress)
Definition: geometry.cpp:1025
void mesh_calc_offset(Scene *scene, BVHLayout bvh_layout)
Definition: geometry.cpp:956
void device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
Definition: geometry.cpp:715
void device_free(Device *device, DeviceScene *dscene, bool force_free)
Definition: geometry.cpp:2085
void tag_update(Scene *scene, uint32_t flag)
Definition: geometry.cpp:2127
void device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
Definition: geometry.cpp:1220
void collect_statistics(const Scene *scene, RenderStats *stats)
Definition: geometry.cpp:2142
void device_update_preprocess(Device *device, Scene *scene, Progress &progress)
Definition: geometry.cpp:1451
void device_update_volume_images(Device *device, Scene *scene, Progress &progress)
Definition: geometry.cpp:1713
void update_svm_attributes(Device *device, DeviceScene *dscene, Scene *scene, vector< AttributeRequestSet > &geom_attributes, vector< AttributeRequestSet > &object_attributes)
Definition: geometry.cpp:470
bool need_flags_update
Definition: geometry.h:224
bool need_update() const
Definition: geometry.cpp:2137
Transform transform_normal
Definition: geometry.h:90
void compute_bvh(Device *device, DeviceScene *dscene, SceneParams *params, Progress *progress, int n, int total)
Definition: geometry.cpp:199
float motion_time(int step) const
Definition: geometry.cpp:145
Type geometry_type
Definition: geometry.h:78
virtual void compute_bounds()=0
@ MESH
Definition: geometry.h:73
@ VOLUME
Definition: geometry.h:75
BoundBox bounds
Definition: geometry.h:87
virtual void pack_primitives(PackedBVH *pack, int object, uint visibility, PackFlags pack_flags)=0
bool need_update_bvh_for_offset
Definition: geometry.h:111
bool transform_applied
Definition: geometry.h:88
size_t optix_prim_offset
Definition: geometry.h:103
BVH * bvh
Definition: geometry.h:100
bool has_volume
Definition: geometry.h:106
bool has_voxel_attributes() const
Definition: geometry.cpp:260
bool has_true_displacement() const
Definition: geometry.cpp:187
bool need_build_bvh(BVHLayout layout) const
Definition: geometry.cpp:171
size_t index
Definition: geometry.h:114
int motion_step(float time) const
Definition: geometry.cpp:150
bool need_attribute(Scene *scene, AttributeStandard std)
Definition: geometry.cpp:102
bool is_hair() const
Definition: geometry.h:175
bool has_surface_bssrdf
Definition: geometry.h:107
bool is_instanced() const
Definition: geometry.cpp:177
AttributeRequestSet needed_attributes()
Definition: geometry.cpp:133
size_t attr_map_offset
Definition: geometry.h:101
size_t prim_offset
Definition: geometry.h:102
bool has_motion_blur() const
Definition: geometry.cpp:255
void tag_update(Scene *scene, bool rebuild)
Definition: geometry.cpp:271
bool need_update_rebuild
Definition: geometry.h:110
AttributeSet attributes
Definition: geometry.h:81
bool is_mesh() const
Definition: geometry.h:170
virtual ~Geometry()
Definition: geometry.cpp:86
Geometry(const NodeType *node_type, const Type type)
Definition: geometry.cpp:66
bool transform_negative_scaled
Definition: geometry.h:89
void tag_bvh_update(bool rebuild)
Definition: geometry.cpp:290
virtual void clear(bool preserve_shaders=false)
Definition: geometry.cpp:91
VDBImageLoader * vdb_loader(const int tile_index=0) const
Definition: image.cpp:180
int num_tiles()
Definition: image.cpp:138
int svm_slot(const int tile_index=0) const
Definition: image.cpp:154
void device_update_slot(Device *device, Scene *scene, int slot, Progress *progress)
Definition: image.cpp:836
ImageHandle handle
Definition: nodes.h:100
@ MESH_NEED_REBUILD
Definition: light.h:96
@ EMISSIVE_MESH_MODIFIED
Definition: light.h:97
void tag_update(Scene *scene, uint32_t flag)
Definition: light.cpp:1036
NamedSizeStats geometry
Definition: stats.h:162
void add_entry(const NamedSizeEntry &entry)
Definition: stats.cpp:78
void tag_update(Scene *scene, uint32_t flag)
Definition: object.cpp:903
@ GEOMETRY_MANAGER
Definition: object.h:130
bool need_flags_update
Definition: object.h:145
void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress, bool bounds_valid=true)
Definition: object.cpp:694
void device_update_mesh_offsets(Device *device, DeviceScene *dscene, Scene *scene)
Definition: object.cpp:781
bool get_cancel()
void set_status(const string &status_, const string &substatus_="")
BVHLayout bvh_layout
Definition: scene.h:173
bool use_bvh_unaligned_nodes
Definition: scene.h:177
bool use_bvh_spatial_split
Definition: scene.h:176
int curve_subdivisions()
Definition: scene.h:210
CurveShapeType hair_shape
Definition: scene.h:180
int num_bvh_time_steps
Definition: scene.h:178
BVHType bvh_type
Definition: scene.h:175
uint get_attribute_id(ustring name)
Definition: shader.cpp:429
virtual bool use_osl()
Definition: shader.h:184
Definition: shader.h:80
size_t size() const
Definition: util_array.h:203
T * resize(size_t newsize)
Definition: util_array.h:150
T * alloc(size_t width, size_t height=0, size_t depth=0)
void clear_modified()
size_t size() const
void copy_to_device_if_modified()
void tag_modified()
bool need_realloc()
void copy_to_device()
void give_data(array< T > &to)
void tag_realloc()
bool is_modified() const
void steal_data(array< T > &from)
void free_if_need_realloc(bool force_free)
OperationNode * node
double time
Scene scene
#define function_bind
static void emit_attribute_map_terminator(uint4 *attr_map, int index, bool chain, uint chain_link)
Definition: geometry.cpp:439
static void update_device_flags_attribute(uint32_t &device_update_flags, const AttributeSet &attributes)
Definition: geometry.cpp:1425
NODE_ABSTRACT_DEFINE(Geometry)
Definition: geometry.cpp:55
static void emit_attribute_map_entry(uint4 *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc)
Definition: geometry.cpp:414
static void emit_attribute_mapping(uint4 *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom)
Definition: geometry.cpp:450
CCL_NAMESPACE_BEGIN PackFlags operator|=(PackFlags &pack_flags, uint32_t value)
Definition: geometry.cpp:49
static void update_attribute_element_size(Geometry *geom, Attribute *mattr, AttributePrimitive prim, size_t *attr_float_size, size_t *attr_float2_size, size_t *attr_float3_size, size_t *attr_uchar4_size)
Definition: geometry.cpp:548
@ ATTR_UCHAR4_MODIFIED
Definition: geometry.cpp:1409
@ MESH_DATA_NEED_REALLOC
Definition: geometry.cpp:1412
@ DEVICE_MESH_DATA_NEEDS_REALLOC
Definition: geometry.cpp:1421
@ ATTR_FLOAT3_MODIFIED
Definition: geometry.cpp:1408
@ ATTR_UCHAR4_NEEDS_REALLOC
Definition: geometry.cpp:1417
@ ATTR_FLOAT_MODIFIED
Definition: geometry.cpp:1406
@ ATTR_FLOAT2_NEEDS_REALLOC
Definition: geometry.cpp:1415
@ DEVICE_MESH_DATA_MODIFIED
Definition: geometry.cpp:1404
@ DEVICE_CURVE_DATA_MODIFIED
Definition: geometry.cpp:1403
@ ATTR_FLOAT2_MODIFIED
Definition: geometry.cpp:1407
@ ATTR_FLOAT_NEEDS_REALLOC
Definition: geometry.cpp:1414
@ CURVE_DATA_NEED_REALLOC
Definition: geometry.cpp:1411
@ DEVICE_CURVE_DATA_NEEDS_REALLOC
Definition: geometry.cpp:1422
@ ATTR_FLOAT3_NEEDS_REALLOC
Definition: geometry.cpp:1416
@ ATTRS_NEED_REALLOC
Definition: geometry.cpp:1419
PackFlags
Definition: geometry.h:47
@ PACK_ALL
Definition: geometry.h:59
@ PACK_NONE
Definition: geometry.h:48
@ PACK_VERTICES
Definition: geometry.h:54
@ PACK_VISIBILITY
Definition: geometry.h:57
@ SHADER_SPECIAL_TYPE_IMAGE_SLOT
Definition: graph.h:65
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define CCL_NAMESPACE_END
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
@ PRIMITIVE_ALL_TRIANGLE
Definition: kernel_types.h:697
AttributeStandard
Definition: kernel_types.h:744
@ ATTR_STD_NONE
Definition: kernel_types.h:745
@ ATTR_STD_POSITION_UNDISPLACED
Definition: kernel_types.h:755
@ ATTR_STD_MOTION_VERTEX_POSITION
Definition: kernel_types.h:756
@ ATTR_SUBDIVIDED
Definition: kernel_types.h:778
@ BVH_LAYOUT_OPTIX
@ BVH_LAYOUT_NONE
@ BVH_LAYOUT_MULTI_OPTIX
@ BVH_LAYOUT_BVH2
@ BVH_LAYOUT_MULTI_OPTIX_EMBREE
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_CURVE_KEY
Definition: kernel_types.h:739
@ ATTR_ELEMENT_CURVE_KEY_MOTION
Definition: kernel_types.h:740
@ ATTR_ELEMENT_VOXEL
Definition: kernel_types.h:741
@ ATTR_ELEMENT_CORNER
Definition: kernel_types.h:736
@ ATTR_ELEMENT_OBJECT
Definition: kernel_types.h:731
@ ATTR_ELEMENT_VERTEX_MOTION
Definition: kernel_types.h:735
@ ATTR_ELEMENT_VERTEX
Definition: kernel_types.h:734
@ ATTR_ELEMENT_FACE
Definition: kernel_types.h:733
@ ATTR_ELEMENT_CURVE
Definition: kernel_types.h:738
AttributePrimitive
Definition: kernel_types.h:722
@ ATTR_PRIM_SUBD
Definition: kernel_types.h:724
@ ATTR_PRIM_TYPES
Definition: kernel_types.h:726
@ ATTR_PRIM_GEOMETRY
Definition: kernel_types.h:723
static void vnormal(PROCESS *process, const float point[3], float r_no[3])
#define SOCKET_NODE_ARRAY(name, ui_name, node_type,...)
Definition: node_type.h:281
#define SOCKET_UINT(name, ui_name, default_value,...)
Definition: node_type.h:202
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition: node_type.h:198
@ DISPLACE_BUMP
Definition: shader.h:67
unsigned int uint32_t
Definition: stdint.h:83
AttributeElement element
Definition: kernel_types.h:782
NodeAttributeType type
Definition: kernel_types.h:783
void update(Scene *scene)
Definition: camera.cpp:231
void set_screen_size_and_resolution(int width_, int height_, int resolution_)
Definition: camera.cpp:792
size_t curvekey_offset
Definition: hair.h:98
void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset)
Definition: hair.cpp:463
size_t num_curves() const
Definition: hair.h:133
size_t num_segments() const
Definition: hair.h:138
CurveShapeType curve_shape
Definition: hair.h:99
int use_bvh_steps
int curve_subdivisions
KernelBVH bvh
int num_ptex_faces() const
Definition: mesh.h:110
int ptex_offset
Definition: mesh.h:103
void tessellate(DiagSplit *split)
size_t get_num_subd_faces() const
Definition: mesh.h:246
void add_undisplaced()
Definition: mesh.cpp:656
float size[3]
void add_vertex_normals()
Definition: mesh.cpp:565
Triangle get_triangle(size_t i) const
Definition: mesh.h:86
void pack_verts(const vector< uint > &tri_prim_index, uint4 *tri_vindex, uint *tri_patch, float2 *tri_patch_uv, size_t vert_offset, size_t tri_offset)
Definition: mesh.cpp:732
void pack_normals(float4 *vnormal)
Definition: mesh.cpp:708
void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset)
Definition: mesh.cpp:762
bool need_tesselation()
Definition: mesh.cpp:179
@ SUBDIVISION_CATMULL_CLARK
Definition: mesh.h:135
size_t num_triangles() const
Definition: mesh.h:92
SubdFace get_subd_face(size_t index) const
Definition: mesh.cpp:400
void pack_shaders(Scene *scene, uint *shader)
Definition: mesh.cpp:685
void add_face_normals()
Definition: mesh.cpp:535
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
Definition: node.h:98
bool is_modified()
Definition: node.cpp:781
ustring name
Definition: node.h:174
size_t get_total_size_in_bytes() const
Definition: node.cpp:692
void clear_modified()
Definition: node.cpp:791
void tag_modified()
Definition: node.cpp:786
size_t attr_map_offset
Definition: object.h:116
vector< ParamValue > attributes
Definition: object.h:61
int get_device_index() const
Definition: object.cpp:369
uint visibility_for_tracing() const
Definition: object.cpp:271
array< int > prim_index
Definition: bvh/bvh.h:63
array< int > prim_type
Definition: bvh/bvh.h:58
array< int4 > nodes
Definition: bvh/bvh.h:48
array< uint > prim_visibility
Definition: bvh/bvh.h:60
array< float4 > prim_tri_verts
Definition: bvh/bvh.h:56
array< float2 > prim_time
Definition: bvh/bvh.h:67
array< int4 > leaf_nodes
Definition: bvh/bvh.h:50
array< uint > prim_tri_index
Definition: bvh/bvh.h:54
array< int > prim_object
Definition: bvh/bvh.h:65
int root_index
Definition: bvh/bvh.h:70
array< int > object_node
Definition: bvh/bvh.h:52
void copy_adjusting_offsets(uint *dest, int doffset)
MeshStats mesh
Definition: stats.h:189
BVH * bvh
Definition: scene.h:225
bool need_global_attribute(AttributeStandard std)
Definition: scene.cpp:376
vector< Geometry * > geometry
Definition: scene.h:235
void need_global_attributes(AttributeRequestSet &attributes)
Definition: scene.cpp:388
vector< Shader * > shaders
Definition: scene.h:236
Camera * dicing_camera
Definition: scene.h:227
SceneParams params
Definition: scene.h:264
ImageManager * image_manager
Definition: scene.h:243
vector< Object * > objects
Definition: scene.h:234
MotionType need_motion()
Definition: scene.cpp:358
ObjectManager * object_manager
Definition: scene.h:247
MotionType
Definition: scene.h:280
@ MOTION_BLUR
Definition: scene.h:280
ShaderManager * shader_manager
Definition: scene.h:245
LightManager * light_manager
Definition: scene.h:244
SceneUpdateStats * update_stats
Definition: scene.h:270
GeometryManager * geometry_manager
Definition: scene.h:246
DeviceScene dscene
Definition: scene.h:261
Camera * camera
Definition: subd_dice.h:44
string full_report() const
Definition: util_task.cpp:243
void push(TaskRunFunction &&task)
Definition: util_task.cpp:36
void wait_work(Summary *stats=NULL)
Definition: util_task.cpp:42
@ NODE_ATTR_FLOAT
Definition: svm_types.h:167
@ NODE_ATTR_FLOAT3
Definition: svm_types.h:169
@ NODE_ATTR_RGBA
Definition: svm_types.h:171
@ NODE_ATTR_FLOAT2
Definition: svm_types.h:168
@ NODE_ATTR_FLOAT4
Definition: svm_types.h:170
@ NODE_ATTR_MATRIX
Definition: svm_types.h:172
#define MEM_GUARDED_CALL(progress, func,...)
#define VLOG(severity)
Definition: util_logging.h:50
ccl_device_inline float4 float3_to_float4(const float3 a)
Definition: util_math.h:420
ccl_device_inline uint as_uint(int i)
Definition: util_math.h:182
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_NAMESPACE_BEGIN string string_printf(const char *format,...)
Definition: util_string.cpp:32
ccl_device_inline Transform transform_identity()