15#include "utility/example_shared.h"
17#include <nv/index/icamera.h>
18#include <nv/index/iconfig_settings.h>
19#include <nv/index/idistributed_data_access.h>
20#include <nv/index/iindex.h>
21#include <nv/index/ilight.h>
22#include <nv/index/imaterial.h>
23#include <nv/index/iscene.h>
24#include <nv/index/isession.h>
25#include <nv/index/isparse_volume_subset.h>
26#include <nv/index/isparse_volume_rendering_properties.h>
28#include <nv/index/app/forwarding_logger.h>
29#include <nv/index/app/idata_analysis_and_processing.h>
30#include <nv/index/app/index_connect.h>
31#include <nv/index/app/string_dict.h>
35 public nv::index::app::Index_connect
55 virtual bool evaluate_options(nv::index::app::String_dict& sdict) CPP11_OVERRIDE;
58 mi::neuraylib::INetwork_configuration* network_configuration,
59 nv::index::app::String_dict& options) CPP11_OVERRIDE
64 const bool is_unittest = nv::index::app::get_bool(options.get(
"unittest"));
67 info_cout(
"NETWORK: disabled networking mode.", options);
68 network_configuration->set_mode(mi::neuraylib::INetwork_configuration:
:MODE_OFF);
72 return initialize_networking_as_default_udp(network_configuration, options);
76 mi::Size calc_offset(
const mi::math::Vector<mi::Sint32, 3>& p,
const mi::math::Vector<mi::Uint32, 3>& s, mi::Uint32 b)
const;
77 mi::Float32 analyze_sparse_volume_data(
78 mi::neuraylib::IDice_transaction* dice_transaction)
const;
81 void edit_sparse_volume_data(
82 mi::neuraylib::IDice_transaction* dice_transaction)
const;
86 mi::Float32 export_sparse_volume_data(
87 mi::neuraylib::IDice_transaction* dice_transaction)
const;
88 void render_frame(
const std::string& output_filename)
const;
91 mi::neuraylib::Tag create_synthetic_volume(
92 const nv::index::ISession* session,
93 const mi::math::Vector<mi::Uint32, 3>& volume_size,
94 mi::neuraylib::IDice_transaction* dice_transaction)
const;
95 std::vector<mi::Uint32> evaluate_sparse_volume_data_locality(
96 const nv::index::IDistributed_data_locality* data_locality,
97 const mi::math::Bbox<mi::Sint32, 3>& query_bound,
98 const mi::neuraylib::Tag& scene_element_tag,
99 const std::string& scene_element_type)
const;
108 void get_brick_clamped_bbox(
109 const nv::index::ISparse_volume_subset_data_descriptor* svol_data_subset_desc,
110 const mi::Uint32 brick_idx,
111 const mi::math::Vector<mi::Sint32, 3>& brick_position,
112 const mi::math::Bbox<mi::Sint32, 3>& query_bbox_s32,
113 mi::math::Bbox<mi::Sint32, 3>& out_brick_box_subdata_clamped,
114 mi::math::Bbox<mi::Sint32, 3>& out_brick_box_clamped)
const;
117 mi::neuraylib::Tag m_session_tag;
119 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
121 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
123 std::string m_outfname;
125 std::string m_voxel_format;
126 mi::neuraylib::Tag m_sparse_volume_tag;
132 m_cluster_configuration = get_index_interface()->get_api_component<nv::index::ICluster_configuration>();
136 m_image_file_canvas = create_image_file_canvas(get_application_layer_interface());
141 check_success(is_local_host_joined(m_cluster_configuration.get()));
144 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(create_transaction());
148 m_session_tag = m_index_session->create_session(dice_transaction.get());
151 mi::base::Handle<const nv::index::ISession> session(dice_transaction->access<nv::index::ISession>(m_session_tag));
156 mi::base::Handle<nv::index::IConfig_settings> edit_config_settings(
157 dice_transaction->edit<nv::index::IConfig_settings>(session->get_config()));
161 edit_config_settings->set_force_data_upload(
true);
166 const mi::math::Vector<mi::Uint32, 3> subcube_size(30);
167 mi::math::Vector<mi::Float32, 3> minimal_volume_scaling;
168 edit_config_settings->get_minimal_volume_scaling(minimal_volume_scaling);
169 edit_config_settings->set_subcube_configuration(
171 edit_config_settings->get_subcube_border_size(),
172 edit_config_settings->get_continuous_volume_translation_supported(),
173 edit_config_settings->get_volume_rotation_supported(),
174 minimal_volume_scaling);
183 mi::math::Vector<mi::Uint32, 3> volume_size(1000, 1000, 1000);
184 mi::math::Matrix<mi::Float32, 4, 4> transform(
185 0.02f, 0.0f, 0.0f, 0.0f,
186 0.0f, 0.02f, 0.0f, 0.0f,
187 0.0f, 0.0f, -0.02f, 0.0f,
188 0.0f, 0.0f, 0.0f, 1.0f
194 volume_size = mi::math::Vector<mi::Uint32, 3>(100, 100, 100);
195 transform = mi::math::Matrix<mi::Float32, 4, 4>(
196 0.2f, 0.0f, 0.0f, 0.0f,
197 0.0f, 0.2f, 0.0f, 0.0f,
198 0.0f, 0.0f, -0.2f, 0.0f,
199 0.0f, 0.0f, 0.0f, 1.0f
203 m_sparse_volume_tag = create_synthetic_volume(session.get(), volume_size, dice_transaction.get());
205 INFO_LOG <<
"Created a synthetic sparse volume dataset: size = "
206 <<
"[" << volume_size.x <<
" " << volume_size.y <<
" " << volume_size.z <<
"], " <<
"tag = " << m_sparse_volume_tag.id;
209 mi::base::Handle<nv::index::IScene> scene_edit(dice_transaction->edit<nv::index::IScene>(session->get_scene()));
213 const mi::math::Bbox<mi::Float32, 3> global_roi(
215 static_cast<mi::Float32
>(volume_size.x),
216 static_cast<mi::Float32
>(volume_size.y),
217 static_cast<mi::Float32
>(volume_size.z));
218 scene_edit->set_clipped_bounding_box(global_roi);
219 scene_edit->set_transform_matrix(transform);
222 mi::base::Handle< nv::index::IPerspective_camera > cam(
223 scene_edit->create_camera<nv::index::IPerspective_camera>());
226 const mi::math::Vector< mi::Float32, 3 > from(-6.0f, 35.0f, 7.0f);
227 const mi::math::Vector< mi::Float32, 3 > to ( 9.0f, 14.f, -11.0f);
228 const mi::math::Vector< mi::Float32, 3 > up ( 0.0f, -0.10f, 1.0f);
229 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
232 cam->set(from, viewdir, up);
233 cam->set_aperture(0.033f);
234 cam->set_aspect(1.0f);
235 cam->set_focal(0.03f);
236 cam->set_clip_min(2.0f);
237 cam->set_clip_max(400.0f);
239 const mi::neuraylib::Tag camera_tag = dice_transaction->store(cam.get());
242 scene_edit->set_camera(camera_tag);
244 const mi::math::Vector<mi::Uint32, 2> canvas_resolution(1024, 1024);
245 m_image_file_canvas->set_resolution(canvas_resolution);
247 dice_transaction->commit();
252 INFO_LOG <<
"Render the initial sparse 3D volume ...";
253 mi::Sint32 frame_idx = 0;
255 const std::string outfname = get_output_file_name(m_outfname, frame_idx);
257 render_frame(outfname);
261 INFO_LOG <<
"Analyzing the sparse volume data ...";
263 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(create_transaction());
266 mi::Float32 value = analyze_sparse_volume_data(dice_transaction.get());
267 INFO_LOG <<
"voxel_format: " << m_voxel_format <<
", unittest: " << m_is_unittest <<
", generated value: " << value;
269 if (m_voxel_format ==
"uint8")
280 else if (m_voxel_format ==
"rgba8")
291 else if (m_voxel_format ==
"sint16")
302 else if (m_voxel_format ==
"float32")
315 ERROR_LOG <<
"Unknown voxel format: " << m_voxel_format;
318 dice_transaction->commit();
321 INFO_LOG <<
"Editing the sparse volume data ...";
323 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(create_transaction());
326 edit_sparse_volume_data(dice_transaction.get());
328 dice_transaction->commit();
331 INFO_LOG <<
"Render the edited sparse 3D volume ...";
333 const std::string outfname = get_output_file_name(m_outfname, frame_idx);
335 render_frame(outfname);
338 INFO_LOG <<
"Analyzing the sparse volume data after editing ...";
340 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(create_transaction());
343 mi::Float32 value = analyze_sparse_volume_data(dice_transaction.get());
347 dice_transaction->commit();
350 INFO_LOG <<
"Exporting subset of the sparse volume data ...";
352 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(create_transaction());
355 mi::Float32 value = export_sparse_volume_data(dice_transaction.get());
357 INFO_LOG <<
"voxel_format: " << m_voxel_format <<
", unittest: " << m_is_unittest <<
", export value: " << value;
359 if (m_voxel_format ==
"uint8")
370 else if (m_voxel_format ==
"rgba8")
381 else if (m_voxel_format ==
"sint16")
392 else if (m_voxel_format ==
"float32")
405 ERROR_LOG <<
"Unknown voxel format: " << m_voxel_format;
408 dice_transaction->commit();
418 const std::string com_name = sdict.get(
"command:",
"<unknown_command>");
419 m_is_unittest = nv::index::app::get_bool(sdict.get(
"unittest",
"false"));
423 if (nv::index::app::get_bool(sdict.get(
"is_call_from_test",
"false")))
425 sdict.insert(
"is_dump_comparison_image_when_failed",
"0");
427 sdict.insert(
"dice::verbose",
"2");
428 sdict.insert(
"outfname",
"");
431 m_outfname = sdict.get(
"outfname");
432 m_voxel_format = sdict.get(
"voxel_format");
434 info_cout(std::string(
"Running ") + com_name, sdict);
437 if (sdict.is_defined(
"h"))
440 <<
"info: Usage: " << com_name <<
" [option]\n"
442 <<
" print this message\n"
444 <<
" [-dice::network::multicast_address address]\n"
445 <<
" set multicast address. (default: ["
446 << sdict.get(
"dice::network::multicast_address") +
"])\n"
448 <<
" [-dice::network::cluster_interface]\n"
449 <<
" set cluster interface. (default: ["
450 << sdict.get(
"dice::network::cluster_interface") +
"])\n"
452 <<
" [-voxel_format VOXEL_FORMAT]\n"
453 <<
" the voxel format. 'uint8', 'rgba8', 'sint16', 'float32' \n"
454 <<
" (default: [" << m_voxel_format <<
"])\n"
460 <<
" [-unittest bool]\n"
461 <<
" when true, unit test mode (create smaller volume). Also small subcube_size."
462 << sdict.get(
"unittest") +
"])\n"
472mi::Size Distributed_sparse_volume_data::calc_offset(
const mi::math::Vector<mi::Sint32, 3>& p,
const mi::math::Vector<mi::Uint32, 3>& s, mi::Uint32 b)
const
474 const mi::Size o =
static_cast<mi::Size
>(p.x + b)
475 +
static_cast<mi::Size
>(p.y + b) * s.x
476 +
static_cast<mi::Size
>(p.z + b) * s.x * s.y;
481mi::neuraylib::Tag Distributed_sparse_volume_data::create_synthetic_volume(
482 const nv::index::ISession* session,
483 const mi::math::Vector<mi::Uint32, 3>& volume_size,
484 mi::neuraylib::IDice_transaction* dice_transaction)
const
487 check_success(volume_size.x > 0 && volume_size.y > 0 && volume_size.z > 0);
489 const mi::math::Bbox<mi::Uint32, 3> volume_bbox(mi::math::Vector<mi::Uint32, 3>(0), volume_size);
494 nv::index::app::String_dict sparse_volume_opt;
495 sparse_volume_opt.insert(
"args::type",
"sparse_volume");
496 sparse_volume_opt.insert(
"args::importer",
"nv::index::plugin::base_importer.Sparse_volume_generator_synthetic");
498 std::stringstream sstr;
499 sstr <<
"0 0 0 " << volume_size.x <<
" " << volume_size.y <<
" " << volume_size.z;
500 sparse_volume_opt.insert(
"args::bbox", sstr.str());
502 sparse_volume_opt.insert(
"args::voxel_format", m_voxel_format);
503 sparse_volume_opt.insert(
"args::synthetic_type",
"perlin_noise");
504 sparse_volume_opt.insert(
"args::parameter::cube_unit",
"1024");
505 sparse_volume_opt.insert(
"args::parameter::time",
"0");
506 sparse_volume_opt.insert(
"args::parameter::terms",
"2");
507 sparse_volume_opt.insert(
"args::parameter::turbulence_weight",
"1 1 1 1");
508 sparse_volume_opt.insert(
"args::parameter::abs_noise",
"false");
509 sparse_volume_opt.insert(
"args::parameter::ridged",
"true");
510 nv::index::IDistributed_data_import_callback* generator =
511 get_importer_from_application_layer(
512 get_application_layer_interface(),
513 "nv::index::plugin::base_importer.Sparse_volume_generator_synthetic",
517 mi::base::Handle<nv::index::IScene> scene(dice_transaction->edit<nv::index::IScene>(session->get_scene()));
520 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(1.0f);
521 const bool is_rendering_enabled =
true;
522 const mi::math::Bbox<mi::Float32, 3> ijk_bbox(volume_bbox);
523 mi::base::Handle<nv::index::ISparse_volume_scene_element> svol_scene_element(
524 scene->create_sparse_volume(ijk_bbox, transform_mat, generator, dice_transaction));
526 svol_scene_element->set_enabled(is_rendering_enabled);
528 if(svol_scene_element.is_valid_interface())
530 const mi::neuraylib::Tag svol_scene_element_tag = dice_transaction->store_for_reference_counting(svol_scene_element.get());
534 mi::base::Handle<nv::index::IStatic_scene_group> static_group(scene->create_scene_group<nv::index::IStatic_scene_group>());
538 mi::base::Handle<nv::index::ISparse_volume_rendering_properties> sparse_render_prop(
539 scene->create_attribute<nv::index::ISparse_volume_rendering_properties>());
540 sparse_render_prop->set_filter_mode(nv::index:
:SPARSE_VOLUME_FILTER_NEAREST);
541 sparse_render_prop->set_sampling_distance( 1.0);
542 sparse_render_prop->set_reference_sampling_distance( 1.0);
543 sparse_render_prop->set_voxel_offsets( mi::math::Vector<mi::Float32, 3>(0.0f, 0.0f, 0.0f));
544 sparse_render_prop->set_preintegrated_volume_rendering(
false);
545 sparse_render_prop->set_lod_rendering_enabled(
false);
546 sparse_render_prop->set_lod_pixel_threshold( 2.0);
547 sparse_render_prop->set_debug_visualization_option( 0);
548 const mi::neuraylib::Tag sparse_render_prop_tag
549 = dice_transaction->store_for_reference_counting(sparse_render_prop.get());
551 static_group->append(sparse_render_prop_tag, dice_transaction);
552 INFO_LOG <<
"Created a sparse_render_prop_tag: tag = " << sparse_render_prop_tag;
555 const mi::Sint32 colormap_entry_id = 1;
556 const mi::neuraylib::Tag colormap_tag =
557 create_colormap(colormap_entry_id, scene.get(), dice_transaction);
559 static_group->append(colormap_tag, dice_transaction);
562 static_group->append(svol_scene_element_tag, dice_transaction);
563 const mi::neuraylib::Tag static_group_tag = dice_transaction->store_for_reference_counting(static_group.get());
567 scene->append(static_group_tag, dice_transaction);
569 return svol_scene_element_tag;
572 return mi::neuraylib:
:NULL_TAG;
576std::vector<mi::Uint32> Distributed_sparse_volume_data::evaluate_sparse_volume_data_locality(
577 const nv::index::IDistributed_data_locality* svol_data_locality,
578 const mi::math::Bbox<mi::Sint32, 3>& query_bound,
579 const mi::neuraylib::Tag& scene_element_tag,
580 const std::string& scene_element_type)
const
583 std::vector<mi::Uint32> cluster_host_ids;
584 std::ostringstream hosts;
585 std::ostringstream locality_report;
586 for(mi::Uint32 i = 0; i < svol_data_locality->get_nb_cluster_nodes(); ++i)
591 const mi::Uint32 host_id = svol_data_locality->get_cluster_node(i);
592 cluster_host_ids.push_back(host_id);
595 hosts << host_id <<
" ";
597 const mi::Size nb_subregions = svol_data_locality->get_nb_bounding_box(host_id);
598 locality_report <<
"Host " << host_id <<
" stores part of the distributed data in the following " << nb_subregions <<
" regions:\n";
599 for(mi::Uint32 j = 0; j < nb_subregions; ++j)
601 const mi::math::Bbox<mi::Sint32, 3> bbox = svol_data_locality->get_bounding_box(host_id, j);
602 locality_report <<
" " << (j+1) <<
")\t" << bbox;
603 if(j < nb_subregions-1)
605 locality_report <<
"\n";
610 <<
"Data locality for a " << scene_element_type
611 <<
" with tag id " << scene_element_tag.id
612 <<
" and query region " << query_bound <<
"\n"
613 <<
"The distributed data is located on the following hosts (ids): [ " << hosts.str() <<
"]." <<
"\n"
614 << locality_report.str()
617 return cluster_host_ids;
621void Distributed_sparse_volume_data::get_brick_clamped_bbox(
622 const nv::index::ISparse_volume_subset_data_descriptor* svol_data_subset_desc,
623 const mi::Uint32 brick_idx,
624 const mi::math::Vector<mi::Sint32, 3>& brick_position,
625 const mi::math::Bbox<mi::Sint32, 3>& query_bbox_s32,
626 mi::math::Bbox<mi::Sint32, 3>& out_brick_box_subdata_clamped,
627 mi::math::Bbox<mi::Sint32, 3>& out_brick_box_clamped)
const
631 const mi::math::Vector<mi::Sint32, 3> query_bbox_ext_s32 = query_bbox_s32.extent();
633 const mi::math::Vector<mi::Uint32,3> svol_data_brick_dim = svol_data_subset_desc->get_subset_data_brick_dimensions();
634 const mi::Uint32 svol_data_brick_border = svol_data_subset_desc->get_subset_data_brick_shared_border_size();
636 const mi::math::Vector<mi::Sint32, 3> brick_pos_vol = mi::math::Vector<mi::Sint32, 3>(brick_position) + mi::math::Vector<mi::Sint32, 3>(svol_data_brick_border);
638 const mi::math::Bbox<mi::Sint32, 3> brick_box_global = mi::math::Bbox<mi::Sint32, 3>(brick_pos_vol,
639 brick_pos_vol + mi::math::Vector<mi::Sint32, 3>(svol_data_brick_dim)
640 - 2 * mi::math::Vector<mi::Sint32, 3>(svol_data_brick_border));
641 const mi::math::Bbox<mi::Sint32, 3> brick_box_subdata = mi::math::Bbox<mi::Sint32, 3>(brick_box_global.min - query_bbox_s32.min,
642 brick_box_global.max - query_bbox_s32.min);
644 const mi::math::Bbox<mi::Sint32, 3> brick_box_subdata_clamped = mi::math::Bbox<mi::Sint32, 3>(mi::math::clamp(brick_box_subdata.min, mi::math::Vector<mi::Sint32, 3>(0u), query_bbox_ext_s32),
645 mi::math::clamp(brick_box_subdata.max, mi::math::Vector<mi::Sint32, 3>(0u), query_bbox_ext_s32));
646 const mi::math::Bbox<mi::Sint32, 3> brick_box_global_clamped = mi::math::Bbox<mi::Sint32, 3>(brick_box_subdata_clamped.min + query_bbox_s32.min,
647 brick_box_subdata_clamped.max + query_bbox_s32.min);
648 const mi::math::Bbox<mi::Sint32, 3> brick_box_clamped = mi::math::Bbox<mi::Sint32, 3>(brick_box_global_clamped.min - brick_pos_vol,
649 brick_box_global_clamped.max - brick_pos_vol);
651 out_brick_box_subdata_clamped = brick_box_subdata_clamped;
652 out_brick_box_clamped = brick_box_clamped;
656mi::Float32 Distributed_sparse_volume_data::analyze_sparse_volume_data(
657 mi::neuraylib::IDice_transaction* dice_transaction)
const
659 mi::base::Handle<const nv::index::ISession> the_session(dice_transaction->access<nv::index::ISession>(m_session_tag));
662 mi::base::Handle<const nv::index::ISparse_volume_scene_element>
sparse_volume(dice_transaction->access<nv::index::ISparse_volume_scene_element>(m_sparse_volume_tag));
665 const mi::math::Vector<mi::Sint32, 2> trace(50, 50);
666 const mi::math::Bbox<mi::Sint32, 3> query_bbox_s32(
668 trace.x + 1, trace.y + 1,
static_cast<mi::Uint32
>(
sparse_volume->get_bounding_box().max.z));
669 const mi::math::Bbox<mi::Float32, 3> query_bbox_f32(query_bbox_s32);
672 const mi::neuraylib::Tag dist_layout_tag = the_session->get_distribution_layout();
675 mi::base::Handle<const nv::index::IData_distribution> distribution_layout(dice_transaction->access<nv::index::IData_distribution>(dist_layout_tag));
679 mi::base::Handle<nv::index::IDistributed_data_locality> svol_data_locality(
680 distribution_layout->get_data_locality<nv::index::ISparse_volume_scene_element>(m_sparse_volume_tag, query_bbox_f32, dice_transaction));
684 std::vector<mi::Uint32> cluster_host_ids = evaluate_sparse_volume_data_locality(svol_data_locality.get(), query_bbox_s32, m_sparse_volume_tag,
sparse_volume->get_class_name());
687 const mi::neuraylib::Tag data_access_tag = the_session->get_data_access_factory();
690 mi::base::Handle<const nv::index::IDistributed_data_access_factory> svol_access_factory(
691 dice_transaction->access<nv::index::IDistributed_data_access_factory>(data_access_tag));
694 mi::base::Handle<nv::index::IDistributed_data_access> svol_data_access(
695 svol_access_factory->create_distributed_data_access<nv::index::ISparse_volume_scene_element>(m_sparse_volume_tag));
699 check_success(svol_data_access->access(query_bbox_f32, dice_transaction) >= 0);
701 const mi::math::Bbox<mi::Float32, 3> effective_bbox_f32 = svol_data_access->get_bounding_box();
704 mi::Float32 avg = -1.0f;
706 mi::base::Handle<const nv::index::IDistributed_data_subset> data_subset(svol_data_access->get_distributed_data_subset());
707 mi::base::Handle<const nv::index::ISparse_volume_subset> svol_data_subset(data_subset->get_interface<
const nv::index::ISparse_volume_subset>());
710 mi::base::Handle<const nv::index::ISparse_volume_attribute_set_descriptor> svol_data_attrib_desc(svol_data_subset->get_attribute_set_descriptor());
711 mi::base::Handle<const nv::index::ISparse_volume_subset_data_descriptor> svol_data_subset_desc(svol_data_subset->get_subset_data_descriptor());
713 const mi::Uint32 svol_attrib_index_0 = 0u;
714 nv::index::ISparse_volume_attribute_set_descriptor::Attribute_parameters svol_attrib_param_0;
715 check_success(svol_data_attrib_desc->get_attribute_parameters(svol_attrib_index_0, svol_attrib_param_0));
717 const nv::index::Sparse_volume_voxel_format svol_voxel_fmt = svol_attrib_param_0.format;
718 const mi::Sint32 svol_voxel_fmt_size = nv::index::get_sizeof(svol_voxel_fmt);
720 const mi::math::Vector<mi::Sint32, 3> query_bbox_ext_s32 = query_bbox_s32.extent();
722 const mi::Size svol_query_buffer_size =
723 static_cast<mi::Size
>(query_bbox_ext_s32.x) *
724 static_cast<mi::Size
>(query_bbox_ext_s32.y) *
725 static_cast<mi::Size
>(query_bbox_ext_s32.z) *
728 mi::Uint8* svol_query_buffer =
new mi::Uint8[svol_query_buffer_size];
730 const mi::math::Vector<mi::Uint32,3> svol_data_brick_dim = svol_data_subset_desc->get_subset_data_brick_dimensions();
731 const mi::Uint32 svol_data_brick_border = svol_data_subset_desc->get_subset_data_brick_shared_border_size();
732 const mi::Uint32 svol_subset_nb_bricks = svol_data_subset_desc->get_subset_number_of_data_bricks();
733 for (mi::Uint32 b = 0u; b < svol_subset_nb_bricks; ++b)
735 const nv::index::ISparse_volume_subset_data_descriptor::Data_brick_info brick_info = svol_data_subset_desc->get_subset_data_brick_info(b);
736 const nv::index::ISparse_volume_subset::Data_brick_buffer_info brick_data_nfo = svol_data_subset->access_brick_data_buffer(b, svol_attrib_index_0);
738 const mi::Uint8* svol_brick_data_raw =
reinterpret_cast<mi::Uint8*
>(brick_data_nfo.data);
739 if (svol_brick_data_raw == NULL)
741 ERROR_LOG <<
"error accessing brick data pointer "
742 <<
"(brick_idx: " << b
743 <<
", brick_level: " << brick_info.brick_lod_level <<
").";
744 delete [] svol_query_buffer;
748 mi::math::Bbox<mi::Sint32, 3> brick_box_subdata_clamped;
749 mi::math::Bbox<mi::Sint32, 3> brick_box_clamped;
750 get_brick_clamped_bbox(svol_data_subset_desc.get(), b, brick_info.brick_position, query_bbox_s32, brick_box_subdata_clamped, brick_box_clamped);
752 for (mi::Uint32 z = 0u; z < static_cast<mi::Uint32>(brick_box_subdata_clamped.extent().z); ++z)
754 for (mi::Uint32 y = 0u; y < static_cast<mi::Uint32>(brick_box_subdata_clamped.extent().y); ++y)
756 const mi::math::Vector<mi::Sint32, 3> line_pos_dst =
757 mi::math::Vector<mi::Sint32, 3>(brick_box_subdata_clamped.min.x,
758 brick_box_subdata_clamped.min.y + y,
759 brick_box_subdata_clamped.min.z + z);
761 const mi::Size dst_off = calc_offset(line_pos_dst, mi::math::Vector<mi::Uint32, 3>(query_bbox_ext_s32), 0u);
763 const mi::math::Vector<mi::Sint32, 3> line_pos_src =
764 mi::math::Vector<mi::Sint32, 3>(brick_box_clamped.min.x,
765 brick_box_clamped.min.y + y,
766 brick_box_clamped.min.z + z);
767 const mi::Size src_off = calc_offset(line_pos_src, svol_data_brick_dim, svol_data_brick_border);
769 const mi::Size line_size =
static_cast<mi::Size
>(brick_box_subdata_clamped.extent().x) * svol_voxel_fmt_size;
771 memcpy(svol_query_buffer + dst_off * svol_voxel_fmt_size,
772 svol_brick_data_raw + src_off * svol_voxel_fmt_size,
778 if(svol_voxel_fmt == nv::index:
:SPARSE_VOLUME_VOXEL_FORMAT_UINT8)
781 const mi::Uint8* voxel_data = svol_query_buffer;
784 mi::Sint64 count =
static_cast<mi::Sint64
>(effective_bbox_f32.max.z - effective_bbox_f32.min.z);
785 for (mi::Sint64 k = 0; k < count; ++k)
787 sum +=
static_cast<mi::Sint64
>(voxel_data[k]);
790 avg =
static_cast<mi::Float32
>(sum) /
static_cast<mi::Float32
>(count);
791 INFO_LOG <<
"Tracing 8-bit volume: [" << trace.x <<
", " << trace.y
792 <<
", " << query_bbox_s32.min.z <<
":" << query_bbox_s32.max.z - 1 <<
"]: "
793 <<
"count=" << count <<
", sum=" << sum <<
", avg=" << avg;
795 else if(svol_voxel_fmt == nv::index:
:SPARSE_VOLUME_VOXEL_FORMAT_UINT8_4)
798 const mi::math::Vector_struct<mi::Uint8, 4>* voxel_data =
799 reinterpret_cast< mi::math::Vector_struct<mi::Uint8, 4>*
>(svol_query_buffer);
802 mi::Sint64 count =
static_cast<mi::Sint64
>(effective_bbox_f32.max.z - effective_bbox_f32.min.z);
803 for (mi::Sint64 k = 0; k < count; ++k)
805 mi::math::Vector<mi::Uint8, 4> voxel_v(voxel_data[k]);
806 mi::math::Vector<mi::Float32, 4> voxel_f32_4(voxel_v);
807 sum +=
static_cast<mi::Sint64
>(((voxel_f32_4.x + voxel_f32_4.y + voxel_f32_4.z) / 3.0f));
810 avg =
static_cast<mi::Float32
>(sum) /
static_cast<mi::Float32
>(count);
811 INFO_LOG <<
"Tracing rgba8 volume: [" << trace.x <<
", " << trace.y
812 <<
", " << query_bbox_s32.min.z <<
":" << query_bbox_s32.max.z - 1 <<
"]: "
813 <<
"count=" << count <<
", sum=" << sum <<
", avg=" << avg;
815 else if(svol_voxel_fmt == nv::index:
:SPARSE_VOLUME_VOXEL_FORMAT_SINT16)
818 const mi::Sint16* voxel_data =
reinterpret_cast<mi::Sint16*
>(svol_query_buffer);
821 mi::Sint64 count =
static_cast<mi::Sint64
>(effective_bbox_f32.max.z - effective_bbox_f32.min.z);
822 for (mi::Sint64 k = 0; k < count; ++k)
824 sum += voxel_data[k];
827 avg =
static_cast<mi::Float32
>(sum) /
static_cast<mi::Float32
>(count);
828 INFO_LOG <<
"Tracing sint16 volume: [" << trace.x <<
", " << trace.y
829 <<
", " << query_bbox_s32.min.z <<
":" << query_bbox_s32.max.z - 1 <<
"]: "
830 <<
"count=" << count <<
", sum=" << sum <<
", avg=" << avg;
832 else if(svol_voxel_fmt == nv::index:
:SPARSE_VOLUME_VOXEL_FORMAT_FLOAT32)
835 const mi::Float32* voxel_data =
reinterpret_cast<mi::Float32*
>(svol_query_buffer);
838 mi::Sint64 count =
static_cast<mi::Sint64
>(effective_bbox_f32.max.z - effective_bbox_f32.min.z);
839 for (mi::Sint64 k = 0; k < count; ++k)
841 sum += voxel_data[k];
844 avg =
static_cast<mi::Float32
>(sum) /
static_cast<mi::Float32
>(count);
845 INFO_LOG <<
"Tracing uint16 volume: [" << trace.x <<
", " << trace.y
846 <<
", " << query_bbox_s32.min.z <<
":" << query_bbox_s32.max.z - 1 <<
"]: "
847 <<
"count=" << count <<
", sum=" << sum <<
", avg=" << avg;
851 ERROR_LOG <<
"Analyze volume data failed: data access on not-known volume type.";
858void Distributed_sparse_volume_data::edit_sparse_volume_data(
859 mi::neuraylib::IDice_transaction* dice_transaction)
const
861 mi::base::Handle<const nv::index::ISession> the_session(
862 dice_transaction->access<nv::index::ISession>(m_session_tag));
865 mi::base::Handle<const nv::index::ISparse_volume_scene_element>
sparse_volume(
866 dice_transaction->access<nv::index::ISparse_volume_scene_element>(m_sparse_volume_tag));
869 const mi::math::Vector<mi::Sint32, 2> trace(50, 50);
870 const mi::math::Bbox<mi::Sint32, 3> query_bbox_s32(
872 trace.x + 1, trace.y + 1,
static_cast<mi::Sint32
>(
sparse_volume->get_bounding_box().max.z));
873 INFO_LOG <<
"The sparse volume will be edited inside the following 3D bounding box: " << query_bbox_s32 <<
".";
874 const mi::math::Bbox<mi::Float32, 3> query_bbox_f32(query_bbox_s32);
877 const mi::neuraylib::Tag dist_layout_tag = the_session->get_distribution_layout();
880 mi::base::Handle<const nv::index::IData_distribution> distribution_layout(dice_transaction->access<nv::index::IData_distribution>(dist_layout_tag));
884 mi::base::Handle<nv::index::IDistributed_data_locality> svol_data_locality(
885 distribution_layout->get_data_locality<nv::index::ISparse_volume_scene_element>(m_sparse_volume_tag, query_bbox_f32, dice_transaction));
889 std::vector<mi::Uint32> cluster_host_ids = evaluate_sparse_volume_data_locality(
890 svol_data_locality.get(), query_bbox_s32, m_sparse_volume_tag,
sparse_volume->get_class_name());
893 const mi::Sint32 voxel_value = 42;
896 mi::base::Handle<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing> processing(
897 get_application_layer_interface()->get_api_component<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing>());
902 mi::base::Handle<nv::index::IDistributed_data_job> algo(processing->get_sample_tool_set()->create_sparse_volume_voxel_value_setting(
906 distribution_layout->create_scheduler()->execute(algo.get(), dice_transaction);
910mi::Float32 Distributed_sparse_volume_data::export_sparse_volume_data(
911 mi::neuraylib::IDice_transaction* dice_transaction)
const
913 mi::base::Handle<const nv::index::ISession> the_session(dice_transaction->access<nv::index::ISession>(m_session_tag));
916 mi::base::Handle<const nv::index::ISparse_volume_scene_element>
sparse_volume(dice_transaction->access<nv::index::ISparse_volume_scene_element>(m_sparse_volume_tag));
920 mi::math::Bbox<mi::Sint32, 3> query_bbox_s32(
sparse_volume->get_bounding_box());
921 query_bbox_s32.min += (query_bbox_s32.max - query_bbox_s32.min) / 4;
922 query_bbox_s32.max -= (query_bbox_s32.max - query_bbox_s32.min) / 4;
923 const mi::math::Bbox<mi::Float32, 3> query_bbox_f32(query_bbox_s32);
926 const mi::neuraylib::Tag dist_layout_tag = the_session->get_distribution_layout();
929 mi::base::Handle<const nv::index::IData_distribution> distribution_layout(dice_transaction->access<nv::index::IData_distribution>(dist_layout_tag));
933 mi::base::Handle<nv::index::IDistributed_data_locality> svol_data_locality(
934 distribution_layout->get_data_locality<nv::index::ISparse_volume_scene_element>(m_sparse_volume_tag, query_bbox_f32, dice_transaction));
938 std::vector<mi::Uint32> cluster_host_ids = evaluate_sparse_volume_data_locality(svol_data_locality.get(), query_bbox_s32, m_sparse_volume_tag,
sparse_volume->get_class_name());
941 const mi::neuraylib::Tag data_access_tag = the_session->get_data_access_factory();
944 mi::base::Handle<const nv::index::IDistributed_data_access_factory> svol_access_factory(
945 dice_transaction->access<nv::index::IDistributed_data_access_factory>(data_access_tag));
948 mi::base::Handle<nv::index::IDistributed_data_access> svol_data_access(
949 svol_access_factory->create_distributed_data_access<nv::index::ISparse_volume_scene_element>(m_sparse_volume_tag));
953 check_success(svol_data_access->access(query_bbox_f32, dice_transaction) >= 0);
955 const mi::math::Bbox<mi::Float32, 3> effective_bbox_f32 = svol_data_access->get_bounding_box();
958 mi::Float32 avg = -1.0f;
960 mi::base::Handle<const nv::index::IDistributed_data_subset> data_subset(svol_data_access->get_distributed_data_subset());
961 mi::base::Handle<const nv::index::ISparse_volume_subset> svol_data_subset(data_subset->get_interface<
const nv::index::ISparse_volume_subset>());
964 mi::base::Handle<const nv::index::ISparse_volume_attribute_set_descriptor> svol_data_attrib_desc(svol_data_subset->get_attribute_set_descriptor());
965 mi::base::Handle<const nv::index::ISparse_volume_subset_data_descriptor> svol_data_subset_desc(svol_data_subset->get_subset_data_descriptor());
967 const mi::Uint32 svol_attrib_index_0 = 0u;
968 nv::index::ISparse_volume_attribute_set_descriptor::Attribute_parameters svol_attrib_param_0;
969 check_success(svol_data_attrib_desc->get_attribute_parameters(svol_attrib_index_0, svol_attrib_param_0));
971 const nv::index::Sparse_volume_voxel_format svol_voxel_fmt = svol_attrib_param_0.format;
972 const mi::Sint32 svol_voxel_fmt_size = nv::index::get_sizeof(svol_voxel_fmt);
975 const mi::math::Vector<mi::Uint32,3> svol_data_brick_dim = svol_data_subset_desc->get_subset_data_brick_dimensions();
976 const mi::Uint32 svol_data_brick_border = svol_data_subset_desc->get_subset_data_brick_shared_border_size();
977 const mi::Uint32 svol_subset_nb_bricks = svol_data_subset_desc->get_subset_number_of_data_bricks();
980 mi::Sint64 nb_voxels = 0;
982 if(svol_voxel_fmt == nv::index:
:SPARSE_VOLUME_VOXEL_FORMAT_UINT8)
984 for (mi::Uint32 b = 0u; b < svol_subset_nb_bricks; ++b)
986 const nv::index::ISparse_volume_subset_data_descriptor::Data_brick_info brick_info = svol_data_subset_desc->get_subset_data_brick_info(b);
987 const nv::index::ISparse_volume_subset::Data_brick_buffer_info brick_data_nfo = svol_data_subset->access_brick_data_buffer(b, svol_attrib_index_0);
988 const mi::Uint8* svol_brick_data_raw =
reinterpret_cast<mi::Uint8*
>(brick_data_nfo.data);
991 mi::math::Bbox<mi::Sint32, 3> brick_box_subdata_clamped;
992 mi::math::Bbox<mi::Sint32, 3> brick_box_clamped;
993 get_brick_clamped_bbox(svol_data_subset_desc.get(), b, brick_info.brick_position, query_bbox_s32, brick_box_subdata_clamped, brick_box_clamped);
994 for (mi::Uint32 z = 0u; z < static_cast<mi::Uint32>(brick_box_subdata_clamped.extent().z); ++z)
996 for (mi::Uint32 y = 0u; y < static_cast<mi::Uint32>(brick_box_subdata_clamped.extent().y); ++y)
998 const mi::math::Vector<mi::Sint32, 3> line_pos_src =
999 mi::math::Vector<mi::Sint32, 3>(brick_box_clamped.min.x,
1000 brick_box_clamped.min.y + y,
1001 brick_box_clamped.min.z + z);
1002 const mi::Size src_off = calc_offset(line_pos_src, svol_data_brick_dim, svol_data_brick_border);
1005 const mi::Uint8* voxel_data = svol_brick_data_raw + src_off * svol_voxel_fmt_size;
1006 mi::Sint64 count =
static_cast<mi::Sint64
>(effective_bbox_f32.max.z - effective_bbox_f32.min.z);
1007 for (mi::Sint64 k = 0; k < count; ++k)
1009 sum +=
static_cast<mi::Sint64
>(voxel_data[k]);
1015 avg =
static_cast<mi::Float32
>(sum) /
static_cast<mi::Float32
>(nb_voxels);
1016 INFO_LOG <<
"Average voxel value in exported data: " << avg <<
" of " << nb_voxels;
1018 else if(svol_voxel_fmt == nv::index:
:SPARSE_VOLUME_VOXEL_FORMAT_UINT8_4)
1020 for (mi::Uint32 b = 0u; b < svol_subset_nb_bricks; ++b)
1022 const nv::index::ISparse_volume_subset_data_descriptor::Data_brick_info brick_info = svol_data_subset_desc->get_subset_data_brick_info(b);
1023 const nv::index::ISparse_volume_subset::Data_brick_buffer_info brick_data_nfo = svol_data_subset->access_brick_data_buffer(b, svol_attrib_index_0);
1024 const mi::Uint8* svol_brick_data_raw =
reinterpret_cast<mi::Uint8*
>(brick_data_nfo.data);
1027 mi::math::Bbox<mi::Sint32, 3> brick_box_subdata_clamped;
1028 mi::math::Bbox<mi::Sint32, 3> brick_box_clamped;
1029 get_brick_clamped_bbox(svol_data_subset_desc.get(), b, brick_info.brick_position, query_bbox_s32, brick_box_subdata_clamped, brick_box_clamped);
1030 for (mi::Uint32 z = 0u; z < static_cast<mi::Uint32>(brick_box_subdata_clamped.extent().z); ++z)
1032 for (mi::Uint32 y = 0u; y < static_cast<mi::Uint32>(brick_box_subdata_clamped.extent().y); ++y)
1034 const mi::math::Vector<mi::Sint32, 3> line_pos_src =
1035 mi::math::Vector<mi::Sint32, 3>(brick_box_clamped.min.x,
1036 brick_box_clamped.min.y + y,
1037 brick_box_clamped.min.z + z);
1038 const mi::Size src_off = calc_offset(line_pos_src, svol_data_brick_dim, svol_data_brick_border);
1041 const mi::math::Vector_struct<mi::Uint8, 4>* voxel_data =
1042 reinterpret_cast<const mi::math::Vector_struct<mi::Uint8, 4>*
>(svol_brick_data_raw + src_off * svol_voxel_fmt_size);
1043 mi::Sint64 count =
static_cast<mi::Sint64
>(effective_bbox_f32.max.z - effective_bbox_f32.min.z);
1044 for (mi::Sint64 k = 0; k < count; ++k)
1046 sum += (
static_cast<mi::Sint64
>(voxel_data[k].x) +
1047 static_cast<mi::Sint64
>(voxel_data[k].y) +
1048 static_cast<mi::Sint64
>(voxel_data[k].z)) / 3;
1054 avg =
static_cast<mi::Float32
>(sum) /
static_cast<mi::Float32
>(nb_voxels);
1055 INFO_LOG <<
"Average voxel value in exported data: " << avg <<
" of " << nb_voxels;
1057 else if(svol_voxel_fmt == nv::index:
:SPARSE_VOLUME_VOXEL_FORMAT_SINT16)
1059 for (mi::Uint32 b = 0u; b < svol_subset_nb_bricks; ++b)
1061 const nv::index::ISparse_volume_subset_data_descriptor::Data_brick_info brick_info = svol_data_subset_desc->get_subset_data_brick_info(b);
1062 const nv::index::ISparse_volume_subset::Data_brick_buffer_info brick_data_nfo = svol_data_subset->access_brick_data_buffer(b, svol_attrib_index_0);
1063 const mi::Uint8* svol_brick_data_raw =
reinterpret_cast<mi::Uint8*
>(brick_data_nfo.data);
1066 mi::math::Bbox<mi::Sint32, 3> brick_box_subdata_clamped;
1067 mi::math::Bbox<mi::Sint32, 3> brick_box_clamped;
1068 get_brick_clamped_bbox(svol_data_subset_desc.get(), b, brick_info.brick_position, query_bbox_s32, brick_box_subdata_clamped, brick_box_clamped);
1069 for (mi::Uint32 z = 0u; z < static_cast<mi::Uint32>(brick_box_subdata_clamped.extent().z); ++z)
1071 for (mi::Uint32 y = 0u; y < static_cast<mi::Uint32>(brick_box_subdata_clamped.extent().y); ++y)
1073 const mi::math::Vector<mi::Sint32, 3> line_pos_src =
1074 mi::math::Vector<mi::Sint32, 3>(brick_box_clamped.min.x,
1075 brick_box_clamped.min.y + y,
1076 brick_box_clamped.min.z + z);
1077 const mi::Size src_off = calc_offset(line_pos_src, svol_data_brick_dim, svol_data_brick_border);
1080 const mi::Sint16* voxel_data =
reinterpret_cast<const mi::Sint16*
>(svol_brick_data_raw + src_off * svol_voxel_fmt_size);
1081 mi::Sint64 count =
static_cast<mi::Sint64
>(effective_bbox_f32.max.z - effective_bbox_f32.min.z);
1082 for (mi::Sint64 k = 0; k < count; ++k)
1084 sum += voxel_data[k];
1090 avg =
static_cast<mi::Float32
>(sum) /
static_cast<mi::Float32
>(nb_voxels);
1091 INFO_LOG <<
"Average voxel value in exported data: " << avg <<
" of " << nb_voxels;
1093 else if(svol_voxel_fmt == nv::index:
:SPARSE_VOLUME_VOXEL_FORMAT_FLOAT32)
1095 for (mi::Uint32 b = 0u; b < svol_subset_nb_bricks; ++b)
1097 const nv::index::ISparse_volume_subset_data_descriptor::Data_brick_info brick_info = svol_data_subset_desc->get_subset_data_brick_info(b);
1098 const nv::index::ISparse_volume_subset::Data_brick_buffer_info brick_data_nfo = svol_data_subset->access_brick_data_buffer(b, svol_attrib_index_0);
1099 const mi::Uint8* svol_brick_data_raw =
reinterpret_cast<mi::Uint8*
>(brick_data_nfo.data);
1102 mi::math::Bbox<mi::Sint32, 3> brick_box_subdata_clamped;
1103 mi::math::Bbox<mi::Sint32, 3> brick_box_clamped;
1104 get_brick_clamped_bbox(svol_data_subset_desc.get(), b, brick_info.brick_position, query_bbox_s32, brick_box_subdata_clamped, brick_box_clamped);
1105 for (mi::Uint32 z = 0u; z < static_cast<mi::Uint32>(brick_box_subdata_clamped.extent().z); ++z)
1107 for (mi::Uint32 y = 0u; y < static_cast<mi::Uint32>(brick_box_subdata_clamped.extent().y); ++y)
1109 const mi::math::Vector<mi::Sint32, 3> line_pos_src =
1110 mi::math::Vector<mi::Sint32, 3>(brick_box_clamped.min.x,
1111 brick_box_clamped.min.y + y,
1112 brick_box_clamped.min.z + z);
1113 const mi::Size src_off = calc_offset(line_pos_src, svol_data_brick_dim, svol_data_brick_border);
1116 const mi::Float32* voxel_data =
1117 reinterpret_cast<const mi::Float32*
>(svol_brick_data_raw + src_off * svol_voxel_fmt_size);
1118 mi::Sint64 count =
static_cast<mi::Sint64
>(effective_bbox_f32.max.z - effective_bbox_f32.min.z);
1119 for (mi::Sint64 k = 0; k < count; ++k)
1121 sum +=
static_cast<mi::Sint64
>(voxel_data[k]);
1127 avg =
static_cast<mi::Float32
>(sum) /
static_cast<mi::Float32
>(nb_voxels);
1128 INFO_LOG <<
"Average voxel value in exported data: " << avg <<
" of " << nb_voxels;
1132 ERROR_LOG <<
"unknown voxel_format: " << svol_voxel_fmt;
1138void Distributed_sparse_volume_data::render_frame(
1139 const std::string& output_filename)
const
1142 m_image_file_canvas->set_rgba_file_name(output_filename.c_str());
1144 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
1145 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
1148 m_index_session->update(m_session_tag, dice_transaction.get());
1150 mi::base::Handle<nv::index::IFrame_results> frame_results(
1151 m_index_rendering->render(
1153 m_image_file_canvas.get(),
1154 dice_transaction.get()));
1157 dice_transaction->commit();
1163int main(
int argc,
const char* argv[])
1165 nv::index::app::String_dict sdict;
1166 sdict.insert(
"dice::verbose",
"3");
1167 sdict.insert(
"unittest",
"0");
1168 sdict.insert(
"outfname",
"frame_distributed_sparse_volume_data");
1169 sdict.insert(
"verify_image_fname",
"");
1170 sdict.insert(
"dice::network::multicast_address",
"224.1.3.2");
1171 sdict.insert(
"dice::network::cluster_interface",
"");
1172 sdict.insert(
"voxel_format",
"uint8");
1173 sdict.insert(
"is_dump_comparison_image_when_failed",
"1");
1174 sdict.insert(
"is_call_from_test",
"0");
1177 sdict.insert(
"dice::network::mode",
"OFF");
1180 sdict.insert(
"index::config::set_monitor_performance_values",
"true");
1181 sdict.insert(
"index::service",
"rendering_and_compositing");
1182 sdict.insert(
"index::cuda_debug_checks",
"false");
1185 sdict.insert(
"index::app::components::application_layer::component_name_list",
1186 "canvas_infrastructure image io data_analysis_and_processing");
1187 sdict.insert(
"index::app::plugins::base_importer::enabled",
"true");
1191 distributed_data_example.initialize(argc, argv, sdict);
1195 const mi::Sint32 exit_code = distributed_data_example.
launch();
1196 INFO_LOG <<
"Shutting down ...";
virtual bool initialize_networking(mi::neuraylib::INetwork_configuration *network_configuration, nv::index::app::String_dict &options) CPP11_OVERRIDE
virtual bool evaluate_options(nv::index::app::String_dict &sdict) CPP11_OVERRIDE
Distributed_sparse_volume_data()
virtual ~Distributed_sparse_volume_data()
int main(int argc, const char *argv[])
#define check_success(expr)