74 if (!preserve_shaders) {
86 return (motion_steps > 1) ? 2.0f *
step / (motion_steps - 1) - 1.0f : 0.0f;
91 if (motion_steps > 1) {
96 if (step_time ==
time) {
101 if (
step != motion_steps / 2) {
186 og->object_name_map.clear();
187 og->object_names.clear();
192 og->object_name_map[
object->name] = i;
205 if (!attr.modified) {
211 switch (kernel_type) {
261 size_t vert_size = 0;
264 size_t curve_size = 0;
265 size_t curve_key_size = 0;
266 size_t curve_segment_size = 0;
268 size_t point_size = 0;
270 size_t face_size = 0;
271 size_t corner_size = 0;
274 bool prim_offset_changed =
false;
276 if (geom->is_mesh() || geom->is_volume()) {
287 vert_size +=
mesh->verts.size();
291 corner_size +=
mesh->subd_face_corners.size();
293 else if (geom->is_hair()) {
294 Hair *hair =
static_cast<Hair *
>(geom);
302 curve_key_size += hair->get_curve_keys().size();
305 else if (geom->is_pointcloud()) {
308 prim_offset_changed = (pointcloud->
prim_offset != point_size);
314 if (prim_offset_changed) {
324 geom->need_update_rebuild |= need_update_rebuild;
325 geom->need_update_bvh_for_offset =
true;
340 scene->update_stats->geometry.times.add_entry({
"device_update_preprocess", time});
344 progress.set_status(
"Updating Meshes Flags");
347 bool volume_images_updated =
false;
350 geom->has_volume =
false;
354 if (geom->is_mesh()) {
359 for (
Node *
node : geom->get_used_shaders()) {
366 geom->has_surface_bssrdf =
true;
373 if (geom->is_mesh()) {
385 if (geom->is_mesh()) {
395 if (geom->is_mesh()) {
397 mesh->tag_verts_modified();
398 mesh->tag_subd_dicing_rate_modified();
399 mesh->tag_subd_max_level_modified();
400 mesh->tag_subd_objecttoworld_modified();
417 if (geom->is_modified() && geom->is_volume()) {
419 if (!volume_images_updated) {
420 progress.set_status(
"Updating Meshes Volume Bounds");
421 device_update_volume_images(device,
scene, progress);
422 volume_images_updated =
true;
426 create_volume_mesh(
scene, volume, progress);
432 if (geom->is_hair()) {
434 Hair *hair =
static_cast<Hair *
>(geom);
445 if (geom->is_mesh()) {
456 if (geom->is_pointcloud()) {
468 if (update_flags & (MESH_ADDED | MESH_REMOVED)) {
472 if (update_flags & (HAIR_ADDED | HAIR_REMOVED)) {
476 if (update_flags & (POINT_ADDED | POINT_REMOVED)) {
511 dscene->
points.tag_realloc();
516 if ((update_flags & VISIBILITY_MODIFIED) != 0) {
575 dscene->
points.tag_modified();
579 need_flags_update =
false;
586 progress.
set_status(
"Updating Displacement Images");
589 set<int> bump_images;
591 bool has_osl_node =
false;
594 if (geom->is_modified()) {
598 bool need_shadow_transparency =
false;
599 if (geom->is_hair()) {
600 Hair *hair =
static_cast<Hair *
>(geom);
604 for (
Node *
node : geom->get_used_shaders()) {
608 if (!is_true_displacement && !need_shadow_transparency) {
625 bump_images.insert(slot);
637 OSLShaderManager::osl_image_slots(device, image_manager, bump_images);
641 for (
const int slot : bump_images) {
642 pool.
push([image_manager, device,
scene, slot, &progress] {
651 progress.
set_status(
"Updating Volume Images");
654 set<int> volume_images;
657 if (!geom->is_modified()) {
661 for (
Attribute &attr : geom->attributes.attributes) {
672 volume_images.insert(slot);
678 for (
const int slot : volume_images) {
679 pool.
push([image_manager, device,
scene, slot, &progress] {
697 bool true_displacement_used =
false;
698 bool curve_shadow_transparency_used =
false;
699 size_t num_tessellation = 0;
704 scene->update_stats->geometry.times.add_entry({
"device_update (normals)", time});
709 if (geom->is_modified()) {
710 if (geom->is_mesh() || geom->is_volume()) {
718#ifdef WITH_OPENSUBDIV
731 true_displacement_used =
true;
734 else if (geom->is_hair()) {
735 Hair *hair =
static_cast<Hair *
>(geom);
737 curve_shadow_transparency_used =
true;
748 if (progress.get_cancel()) {
755 scene->update_stats->geometry.times.add_entry(
756 {(num_tessellation) ?
"device_update (tessellation and tangents)" :
757 "device_update (tangents)",
763 if (num_tessellation) {
765 dicing_camera->get_full_height());
771 if (!(geom->is_modified() && geom->is_mesh())) {
778 string msg =
"Tessellating ";
787 progress.set_status(
"Updating Mesh", msg);
790 subd_params.dicing_rate =
mesh->get_subd_dicing_rate();
791 subd_params.max_level =
mesh->get_subd_max_level();
792 subd_params.objecttoworld =
mesh->get_subd_objecttoworld();
793 subd_params.camera = dicing_camera;
805 if (progress.get_cancel()) {
810 if (progress.get_cancel()) {
815 if (true_displacement_used || curve_shadow_transparency_used) {
818 scene->update_stats->geometry.times.add_entry(
819 {
"device_update (displacement: load images)", time});
822 device_update_displacement_images(device,
scene, progress);
827 device_free(device, dscene,
false);
831 geom_calc_offset(
scene, bvh_layout);
832 if (true_displacement_used || curve_shadow_transparency_used) {
835 scene->update_stats->geometry.times.add_entry(
836 {
"device_update (displacement: copy meshes to device)", time});
839 device_update_mesh(device, dscene,
scene, progress);
842 if (progress.get_cancel()) {
850 scene->update_stats->object.times.add_entry(
851 {
"device_update (apply static transforms)", time});
855 progress.set_status(
"Updating Objects",
"Applying Static Transformations");
859 if (progress.get_cancel()) {
866 scene->update_stats->geometry.times.add_entry({
"device_update (attributes)", time});
869 device_update_attributes(device, dscene,
scene, progress);
870 if (progress.get_cancel()) {
876 bool displacement_done =
false;
877 bool curve_shadow_transparency_done =
false;
881 device->const_copy_to(
"data", &dscene->
data,
sizeof(dscene->
data));
885 scene->update_stats->geometry.times.add_entry({
"device_update (displacement)", time});
890 if (geom->is_modified()) {
891 if (geom->is_mesh()) {
893 if (displace(device,
scene,
mesh, progress)) {
894 displacement_done =
true;
897 else if (geom->is_hair()) {
898 Hair *hair =
static_cast<Hair *
>(geom);
900 curve_shadow_transparency_done =
true;
905 if (progress.get_cancel()) {
911 if (progress.get_cancel()) {
916 if (displacement_done || curve_shadow_transparency_done) {
919 scene->update_stats->geometry.times.add_entry(
920 {
"device_update (displacement: attributes)", time});
923 device_free(device, dscene,
false);
925 device_update_attributes(device, dscene,
scene, progress);
926 if (progress.get_cancel()) {
936 bool need_update_scene_bvh = (
scene->
bvh ==
nullptr ||
937 (update_flags & (TRANSFORM_MODIFIED | VISIBILITY_MODIFIED)) != 0);
941 scene->update_stats->geometry.times.add_entry({
"device_update (build object BVHs)", time});
947 const bool use_multithreaded_build = first_bvh_build ||
949 first_bvh_build =
false;
954 if (geom->is_modified() || geom->need_update_bvh_for_offset) {
955 need_update_scene_bvh =
true;
957 if (geom->need_build_bvh(bvh_layout)) {
962 if (use_multithreaded_build) {
963 bvh_task_pool_.push([geom, device, dscene,
scene, &progress, i, &num_bvh] {
964 geom->compute_bvh(device, dscene, &
scene->
params, &progress, i, num_bvh);
968 geom->compute_bvh(device, dscene, &
scene->
params, &progress, i, num_bvh);
974 bvh_task_pool_.wait_work(&summary);
991 scene->update_stats->geometry.times.add_entry({
"device_update (compute bounds)", time});
995 object->compute_bounds(motion_blur);
999 if (progress.get_cancel()) {
1003 if (need_update_scene_bvh) {
1006 scene->update_stats->geometry.times.add_entry({
"device_update (build scene BVH)", time});
1009 device_update_bvh(device, dscene,
scene, progress);
1010 if (progress.get_cancel()) {
1023 scene->update_stats->geometry.times.add_entry(
1024 {
"device_update (copy meshes to device)", time});
1027 device_update_mesh(device, dscene,
scene, progress);
1028 if (progress.get_cancel()) {
1036 geom->clear_modified();
1037 geom->attributes.clear_modified();
1039 if (geom->is_mesh()) {
1045 update_flags = UPDATE_NONE;
1062 dscene->
points.clear_modified();
1087 dscene->
curve_keys.free_if_need_realloc(force_free);
1089 dscene->
points.free_if_need_realloc(force_free);
1105 og->object_name_map.clear();
1106 og->object_names.clear();
1115 update_flags |=
flag;
1132 NamedSizeEntry(
string(geometry->name.c_str()), geometry->get_total_size_in_bytes()));
list< Attribute > attributes
Attribute * find(ustring name) const
bool modified(AttrKernelDataType kernel_type) const
static BVHLayout best_bvh_layout(BVHLayout requested_layout, BVHLayoutMask supported_layouts)
device_vector< uint > points_shader
device_vector< float2 > prim_time
device_vector< float4 > points
device_vector< uint > prim_visibility
device_vector< float4 > attributes_float4
device_vector< KernelCurveSegment > curve_segments
device_vector< float2 > attributes_float2
device_vector< AttributeMap > attributes_map
device_vector< KernelCurve > curves
device_vector< packed_uint3 > tri_vindex
device_vector< int > object_node
device_vector< packed_float3 > attributes_float3
device_vector< int > prim_object
device_vector< float4 > curve_keys
device_vector< packed_float3 > tri_vnormal
device_vector< int4 > bvh_leaf_nodes
device_vector< uint > tri_shader
device_vector< packed_float3 > tri_verts
device_vector< float > attributes_float
device_vector< int > prim_type
device_vector< int4 > bvh_nodes
device_vector< int > prim_index
device_vector< uchar4 > attributes_uchar4
virtual OSLGlobals * get_cpu_osl_memory()
void device_update_displacement_images(Device *device, Scene *scene, Progress &progress)
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void geom_calc_offset(Scene *scene, BVHLayout bvh_layout)
void tag_update(Scene *scene, const uint32_t flag)
void update_osl_globals(Device *device, Scene *scene)
void device_free(Device *device, DeviceScene *dscene, bool force_free)
void collect_statistics(const Scene *scene, RenderStats *stats)
void device_update_preprocess(Device *device, Scene *scene, Progress &progress)
void device_update_volume_images(Device *device, Scene *scene, Progress &progress)
Transform transform_normal
int motion_step(const float time) const
bool need_update_bvh_for_offset
bool has_true_displacement() const
bool need_build_bvh(BVHLayout layout) const
bool is_instanced() const
virtual bool has_motion_blur() const
void tag_update(Scene *scene, bool rebuild)
Geometry(const NodeType *node_type, const Type type)
bool transform_negative_scaled
float motion_time(const int step) const
virtual void clear(bool preserve_shaders=false)
bool need_shadow_transparency()
size_t curve_segment_offset
size_t num_curves() const
bool update_shadow_transparency(Device *device, Scene *scene, Progress &progress)
size_t num_segments() const
CurveShapeType curve_shape
VDBImageLoader * vdb_loader() const
int num_svm_slots() const
int svm_slot(const int slot_index=0) const
void device_update_slot(Device *device, Scene *scene, const size_t slot, Progress &progress)
void add_entry(const NamedSizeEntry &entry)
void set_status(const string &status_, const string &substatus_="")
CurveShapeType hair_shape
bool need_update_attribute
bool need_update_displacement
EmissionSampling emission_sampling
NODE_DECLARE unique_ptr< ShaderGraph > graph
void free_if_need_realloc(bool force_free)
void push_back(unique_ptr< T > &&value)
#define CCL_NAMESPACE_END
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
@ ATTR_STD_MOTION_VERTEX_POSITION
@ BVH_LAYOUT_MULTI_HIPRT_EMBREE
@ BVH_LAYOUT_MULTI_EMBREEGPU
@ BVH_LAYOUT_MULTI_METAL_EMBREE
@ BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE
@ BVH_LAYOUT_MULTI_OPTIX_EMBREE
#define SOCKET_NODE_ARRAY(name, ui_name, node_type,...)
#define SOCKET_UINT(name, ui_name, default_value,...)
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
#define NODE_ABSTRACT_DEFINE(structname)
static void update_device_flags_attribute(uint32_t &device_update_flags, const AttributeSet &attributes)
static void update_attribute_realloc_flags(uint32_t &device_update_flags, const AttributeSet &attributes)
@ DEVICE_MESH_DATA_NEEDS_REALLOC
@ DEVICE_POINT_DATA_MODIFIED
@ DEVICE_POINT_DATA_NEEDS_REALLOC
@ ATTR_FLOAT4_NEEDS_REALLOC
@ ATTR_UCHAR4_NEEDS_REALLOC
@ ATTR_FLOAT2_NEEDS_REALLOC
@ DEVICE_MESH_DATA_MODIFIED
@ DEVICE_CURVE_DATA_MODIFIED
@ ATTR_FLOAT_NEEDS_REALLOC
@ DEVICE_CURVE_DATA_NEEDS_REALLOC
@ ATTR_FLOAT3_NEEDS_REALLOC
@ SHADER_SPECIAL_TYPE_IMAGE_SLOT
@ SHADER_SPECIAL_TYPE_OSL
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
static AttrKernelDataType kernel_type(const Attribute &attr)
void update(Scene *scene)
bool set_screen_size(const int width_, int height_)
void tessellate(SubdParams ¶ms)
size_t get_num_subd_faces() const
void update_tangents(Scene *scene)
void add_vertex_normals()
AttributeSet subd_attributes
@ SUBDIVISION_CATMULL_CLARK
size_t num_triangles() const
void update_generated(Scene *scene)
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=nullptr)
void dereference_all_used_nodes()
size_t num_points() const
unique_ptr< ObjectManager > object_manager
MotionType need_motion() const
unique_ptr< LightManager > light_manager
unique_ptr_vector< Geometry > geometry
unique_ptr< SceneUpdateStats > update_stats
unique_ptr< GeometryManager > geometry_manager
unique_ptr_vector< Object > objects
unique_ptr< ImageManager > image_manager
string full_report() const
void push(TaskRunFunction &&task)
void wait_work(Summary *stats=nullptr)