10#include "utility/example_shared.h"
12#include <nv/index/icamera.h>
13#include <nv/index/icolormap.h>
14#include <nv/index/iindex.h>
15#include <nv/index/iscene.h>
16#include <nv/index/isession.h>
17#include <nv/index/isparse_volume_rendering_properties.h>
19#include "utility/app_rendering_context.h"
20#include "utility/canvas_utility.h"
22#include <nv/index/app/idata_analysis_and_processing.h>
23#include <nv/index/app/index_connect.h>
24#include <nv/index/app/string_dict.h>
25#include <nv/index/app/time_functions.h>
32 public nv::index::app::Index_connect
52 virtual bool evaluate_options(nv::index::app::String_dict& sdict) CPP11_OVERRIDE;
55 mi::neuraylib::INetwork_configuration* network_configuration,
56 nv::index::app::String_dict& options) CPP11_OVERRIDE
61 const bool is_unittest = nv::index::app::get_bool(options.get(
"unittest"));
64 info_cout(
"NETWORK: disabled networking mode.", options);
65 network_configuration->set_mode(mi::neuraylib::INetwork_configuration:
:MODE_OFF);
69 return initialize_networking_as_default_udp(network_configuration, options);
74 mi::math::Color_struct jetmap(mi::Float32 v, mi::Float32 vmin, mi::Float32 vmax)
const;
75 nv::index::IColormap* create_colormap(nv::index::IScene* scene)
const;
76 void edit_volume_data(
77 mi::neuraylib::Tag sparse_volume_tag,
78 mi::neuraylib::Tag session_tag,
79 mi::neuraylib::IDice_transaction* dice_transaction)
const;
81 void setup_camera(nv::index::IPerspective_camera* cam)
const;
85 nv::index::IFrame_results* render_frame(
const std::string& output_fname)
const;
88 mi::neuraylib::Tag m_session_tag;
90 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
92 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
94 std::string m_outfname;
96 std::string m_verify_image_fname;
97 std::string m_verify_image_fname_second;
99 std::string m_unittest_verify_image_fbase;
100 std::string m_unittest_verify_image_fbase_second;
106 mi::Sint32 exit_code = 0;
110 m_cluster_configuration = get_index_interface()->get_api_component<nv::index::ICluster_configuration>();
114 m_image_file_canvas = create_image_file_canvas(get_application_layer_interface());
119 check_success(is_local_host_joined(m_cluster_configuration.get()));
122 mi::neuraylib::Tag sparse_volume_tag = mi::neuraylib:
:NULL_TAG;
126 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
127 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
131 m_session_tag = m_index_session->create_session(dice_transaction.get());
137 mi::base::Handle<const nv::index::ISession> session(
138 dice_transaction->access<
const nv::index::ISession>(m_session_tag));
145 mi::base::Handle<const nv::index::ISession> session(
146 dice_transaction->access<
const nv::index::ISession>(m_session_tag));
150 mi::base::Handle<nv::index::IScene> scene_edit(
151 dice_transaction->edit<nv::index::IScene>(session->get_scene()));
155 mi::base::Handle<nv::index::IStatic_scene_group> static_group(
156 scene_edit->create_scene_group<nv::index::IStatic_scene_group>());
160 mi::math::Vector<mi::Uint32, 3> volume_size(1020, 1020, 1020);
161 const mi::math::Bbox<mi::Uint32, 3> bbox(
162 mi::math::Vector<mi::Uint32, 3>(0),
167 mi::base::Handle<nv::index::ISparse_volume_rendering_properties> sparse_render_prop(
168 scene_edit->create_attribute<nv::index::ISparse_volume_rendering_properties>());
169 sparse_render_prop->set_filter_mode(nv::index:
:SPARSE_VOLUME_FILTER_NEAREST);
170 sparse_render_prop->set_sampling_distance( 1.0);
171 sparse_render_prop->set_reference_sampling_distance( 1.0);
172 sparse_render_prop->set_voxel_offsets( mi::math::Vector<mi::Float32, 3>(0.5f, 0.5f, 0.5f));
173 sparse_render_prop->set_preintegrated_volume_rendering(
false);
174 sparse_render_prop->set_lod_rendering_enabled(
false);
175 sparse_render_prop->set_lod_pixel_threshold( 2.0);
176 sparse_render_prop->set_debug_visualization_option( 0);
177 const mi::neuraylib::Tag sparse_render_prop_tag
178 = dice_transaction->store_for_reference_counting(sparse_render_prop.get());
180 static_group->append(sparse_render_prop_tag, dice_transaction.get());
181 INFO_LOG <<
"Created a sparse_render_prop_tag: tag = " << sparse_render_prop_tag;
184 mi::base::Handle<nv::index::IColormap> colormap(create_colormap(scene_edit.get()));
186 const mi::neuraylib::Tag colormap_tag = dice_transaction->store_for_reference_counting(colormap.get());
187 static_group->append(colormap_tag, dice_transaction.get());
188 INFO_LOG <<
"Add a colormap to the scene: tag = " << colormap_tag;
192 nv::index::app::String_dict sparse_volume_opt;
193 sparse_volume_opt.insert(
"args::type",
"sparse_volume");
194 sparse_volume_opt.insert(
"args::importer",
"synthetic");
196 std::stringstream sstr;
197 sstr <<
"0 0 0 " << volume_size.x <<
" " << volume_size.y <<
" " << volume_size.z;
198 sparse_volume_opt.insert(
"args::bbox", sstr.str());
200 sparse_volume_opt.insert(
"args::voxel_format",
"uint8");
201 sparse_volume_opt.insert(
"args::synthetic_type",
"default");
204 sparse_volume_opt.insert(
"args::synthetic_type",
"perlin_noise");
205 sparse_volume_opt.insert(
"args::parameter::cube_unit",
"400");
206 sparse_volume_opt.insert(
"args::parameter::time",
"0");
207 sparse_volume_opt.insert(
"args::parameter::terms",
"5");
208 sparse_volume_opt.insert(
"args::parameter::turbulence_weight",
"1 1 1 1");
209 sparse_volume_opt.insert(
"args::parameter::abs_noise",
"0");
210 sparse_volume_opt.insert(
"args::parameter::ridged",
"1");
212 nv::index::IDistributed_data_import_callback* generator =
213 get_importer_from_application_layer(
214 get_application_layer_interface(),
215 "nv::index::plugin::base_importer.Sparse_volume_generator_synthetic",
219 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(1.0f);
221 const mi::math::Bbox<mi::Float32, 3> ijk_bbox(
222 mi::math::Vector<mi::Float32, 3 >(0.0f),
223 mi::math::Vector<mi::Float32, 3 >(
static_cast<mi::Float32
>(volume_size.x),
224 static_cast<mi::Float32
>(volume_size.y),
225 static_cast<mi::Float32
>(volume_size.z)));
227 mi::base::Handle<nv::index::ISparse_volume_scene_element>
sparse_volume(
228 scene_edit->create_sparse_volume(ijk_bbox, transform_mat, generator, dice_transaction.get()));
234 sparse_volume_tag = dice_transaction->store_for_reference_counting(
sparse_volume.get());
237 static_group->append(sparse_volume_tag, dice_transaction.get());
238 mi::neuraylib::Tag static_group_tag = dice_transaction->store_for_reference_counting(static_group.get());
242 scene_edit->append(static_group_tag, dice_transaction.get());
244 std::stringstream sstr;
245 sstr <<
"Created a synthetic volume: size = ["
246 << volume_size.x <<
" " << volume_size.y <<
" " << volume_size.z
247 <<
"], tag = " << sparse_volume_tag.id;
248 INFO_LOG << sstr.str();
251 mi::base::Handle< nv::index::IPerspective_camera > cam(
252 scene_edit->create_camera<nv::index::IPerspective_camera>());
254 setup_camera(cam.get());
255 const mi::neuraylib::Tag camera_tag = dice_transaction->store(cam.get());
258 scene_edit->set_camera(camera_tag);
260 const mi::math::Vector<mi::Uint32, 2> buffer_resolution(1024, 1024);
261 m_image_file_canvas->set_resolution(buffer_resolution);
265 const mi::math::Bbox_struct<mi::Float32, 3> region_of_interest =
267 { 0.0f, 0.0f, 0.0f, },
269 static_cast< mi::Float32
>(volume_size.x),
270 static_cast< mi::Float32
>(volume_size.y),
271 static_cast< mi::Float32
>(volume_size.z),
274 scene_edit->set_clipped_bounding_box(region_of_interest);
277 mi::math::Matrix<mi::Float32, 4, 4> transform(
278 1.0f, 0.0f, 0.0f, 0.0f,
279 0.0f, 1.0f, 0.0f, 0.0f,
280 0.0f, 0.0f, -1.0f, 0.0f,
281 0.0f, 0.0f, 0.0f, 1.0f
283 scene_edit->set_transform_matrix(transform);
286 dice_transaction->commit();
292 const mi::Sint32 frame_idx = 0;
293 const std::string fname = get_output_file_name(m_outfname, frame_idx);
295 mi::base::Handle<nv::index::IFrame_results> frame_results(render_frame(fname));
296 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
297 if (err_set->any_errors())
299 std::ostringstream os;
300 const mi::Uint32 nb_err = err_set->get_nb_errors();
301 for (mi::Uint32 e = 0; e < nb_err; ++e)
303 if (e != 0) os <<
'\n';
304 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
305 os << err->get_error_string();
308 ERROR_LOG <<
"IIndex_rendering rendering call failed with the following error(s): " <<
'\n'
314 if (!verify_canvas_result(get_application_layer_interface(),
315 m_image_file_canvas.get(), m_verify_image_fname, get_options()))
323 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
324 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
327 edit_volume_data(sparse_volume_tag, m_session_tag, dice_transaction.get());
329 dice_transaction->commit();
335 const mi::Sint32 frame_idx = 0;
336 const std::string fname =
"edited_" + get_output_file_name(m_outfname, frame_idx);
337 mi::base::Handle<nv::index::IFrame_results> frame_results(render_frame(fname));
339 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
340 if (err_set->any_errors())
342 std::ostringstream os;
344 const mi::Uint32 nb_err = err_set->get_nb_errors();
345 for (mi::Uint32 e = 0; e < nb_err; ++e)
347 if (e != 0) os <<
'\n';
348 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
349 os << err->get_error_string();
352 ERROR_LOG <<
"NVIDIA IndeX rendering call failed with the following error(s): " <<
'\n'
357 if (!verify_canvas_result(get_application_layer_interface(),
358 m_image_file_canvas.get(), m_verify_image_fname_second, get_options()))
371 const std::string com_name = sdict.get(
"command:",
"<unknown_command>");
372 m_is_unittest = nv::index::app::get_bool(sdict.get(
"unittest",
"false"));
376 if (nv::index::app::get_bool(sdict.get(
"is_call_from_test",
"false")))
378 sdict.insert(
"is_dump_comparison_image_when_failed",
"0");
380 sdict.insert(
"outfname",
"");
381 sdict.insert(
"dice::verbose",
"2");
382 const std::string vimage_base1 = sdict.get(
"unittest_verify_image_fbase");
383 const std::string vimage_base2 = sdict.get(
"unittest_verify_image_fbase_second");
384 if(!vimage_base1.empty())
386 sdict.get(
"verify_image_fname") = vimage_base1 +
".ppm";
388 if(!vimage_base2.empty())
390 sdict.get(
"verify_image_fname_second") = vimage_base2 +
".ppm";
394 m_outfname = sdict.get(
"outfname");
395 m_verify_image_fname = sdict.get(
"verify_image_fname");
396 m_verify_image_fname_second = sdict.get(
"verify_image_fname_second");
397 m_perlin_noise = nv::index::app::get_bool(sdict.get(
"perlin_noise",
"false"));
398 m_unittest_verify_image_fbase = sdict.get(
"unittest_verify_image_fbase");
399 m_unittest_verify_image_fbase_second = sdict.get(
"unittest_verify_image_fbase_second");
401 info_cout(std::string(
"running ") + com_name, sdict);
402 info_cout(
"outfname = [" + m_outfname +
403 "], verify_image_fname = [" + m_verify_image_fname +
404 "], verify_image_fname_second = [" + m_verify_image_fname_second +
405 "], dice::verbose = " + sdict.get(
"dice::verbose"), sdict);
408 if (sdict.is_defined(
"h"))
411 <<
"info: Usage: " << com_name <<
" [option]\n"
413 <<
" print out this message\n"
415 <<
" [-dice::verbose severity_level INT]\n"
416 <<
" verbose severity level by INT (3 is info).\n"
417 <<
" (default: " + sdict.get(
"dice::verbose") <<
")\n"
419 <<
" [-perlin_noise BOOL]\n"
420 <<
" when true, use Perlin noise to generate the volume, instead of\n"
421 <<
" a simpler color scheme. Note that this can be computationally expensive.\n"
422 <<
" (default: [" << m_perlin_noise <<
"])\n"
424 <<
" [-outfname FILE_BASENAME]\n"
425 <<
" output ppm file base name. When empty, no output.\n"
426 <<
" A frame number and extension (.ppm) will be added.\n"
427 <<
" (default: [" << m_outfname <<
"])\n"
429 <<
" [-verify_image_fname REF_IMAGE_FILENAME]\n"
430 <<
" when REF_IMAGE_FILENAME exist, verify the first rendered image.\n"
431 <<
" (default: [" << m_verify_image_fname <<
"])\n"
433 <<
" [-verify_image_fname_second REF_IMAGE_FILENAME]\n"
434 <<
" when REF_IMAGE_FILENAME exist, verify the second rendered image.\n"
435 <<
" (default: [" << m_verify_image_fname_second <<
"])\n"
437 <<
" [-unittest BOOL]\n"
438 <<
" when true, unit test mode. \n"
439 <<
" (default: [" << m_is_unittest <<
"])"
441 <<
" [-unittest_verify_image_fbase REF_IMAGE_FILENAME]\n"
442 <<
" when REF_IMAGE_FILENAME exist, verify the first rendered image.\n"
443 <<
" Only effective with -unittest 1.\n"
444 <<
" (default: [" << m_unittest_verify_image_fbase <<
"])\n"
446 <<
" [-unittest_verify_image_fbase_second REF_IMAGE_FILENAME]\n"
447 <<
" when REF_IMAGE_FILENAME exist, verify the second rendered image.\n"
448 <<
" Only effective with -unittest 1.\n"
449 <<
" (default: [" << m_unittest_verify_image_fbase_second <<
"])\n"
458mi::math::Color_struct Parallel_volume_editing::jetmap(mi::Float32 v, mi::Float32 vmin, mi::Float32 vmax)
const
460 mi::math::Color_struct c = {1.f, 1.f, 1.f, 0.01f};
469 if (v < (vmin + 0.25f * dv))
472 c.g = 4.f * (v - vmin) / dv;
474 else if (v < (vmin + 0.5f * dv))
477 c.b = 1.f + 4.f * (vmin + 0.25f * dv - v) / dv;
479 else if (v < (vmin + 0.75f * dv))
481 c.r = 4.f * (v - vmin - 0.5f * dv) / dv;
486 c.g = 1.f + 4.f * (vmin + 0.75f * dv - v) / dv;
494nv::index::IColormap* Parallel_volume_editing::create_colormap(nv::index::IScene* scene)
const
496 nv::index::IColormap* colormap = scene->create_attribute<nv::index::IColormap>();
498 std::vector<mi::math::Color_struct> colormap_entries;
499 colormap_entries.resize(256);
500 for(mi::Uint32 i=0; i<256; ++i)
502 colormap_entries[i] = jetmap((
static_cast<mi::Float32
>(i)+0.5f)/256.0f, 0.0f, 1.0f);
506 colormap->set_colormap(&colormap_entries[0], colormap_entries.size());
511void Parallel_volume_editing::edit_volume_data(
512 mi::neuraylib::Tag sparse_volume_tag,
513 mi::neuraylib::Tag session_tag,
514 mi::neuraylib::IDice_transaction* dice_transaction)
const
517 mi::base::Handle<const nv::index::ISession> session(
518 dice_transaction->access<nv::index::ISession>(session_tag));
522 mi::base::Handle<const nv::index::ISparse_volume_scene_element>
sparse_volume(
523 dice_transaction->access<nv::index::ISparse_volume_scene_element>(sparse_volume_tag));
525 const mi::math::Bbox<mi::Float32, 3> query_bbox_f32 =
sparse_volume->get_bounding_box();
528 const mi::neuraylib::Tag dist_layout_tag = session->get_distribution_layout();
530 mi::base::Handle<const nv::index::IData_distribution> distribution_layout(
531 dice_transaction->access<nv::index::IData_distribution>(dist_layout_tag));
534 const mi::math::Bbox<mi::Sint32, 3> query_bbox_s32(query_bbox_f32);
535 mi::base::Handle<nv::index::IDistributed_data_locality> svol_data_locality(
536 distribution_layout->get_data_locality<nv::index::ISparse_volume_scene_element>(sparse_volume_tag, query_bbox_f32, dice_transaction));
540 for (mi::Uint32 i=0; i < svol_data_locality->get_nb_cluster_nodes(); ++i)
545 const mi::Uint32 host_id = svol_data_locality->get_cluster_node(i);
546 INFO_LOG <<
"Cluster host "
547 << svol_data_locality->get_cluster_node(i)
548 <<
" is responsible for processing "
549 << svol_data_locality->get_nb_bounding_box(host_id)
554 const mi::Float64 start_time = nv::index::app::util::time::get_time();
555 const mi::Uint8 voxel_value = 255;
557 mi::base::Handle<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing> processing(
558 get_application_layer_interface()->get_api_component<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing>());
563 mi::base::Handle<nv::index::IDistributed_data_job> algo(processing->get_sample_tool_set()->create_sparse_volume_voxel_value_setting(
569 distribution_layout->create_scheduler()->execute(algo.get(), dice_transaction);
572 const mi::Float64 end_time = nv::index::app::util::time::get_time();
573 const mi::Float64 elapsed_time = end_time - start_time;
574 INFO_LOG <<
"Total elapsed time for volume edit: " << elapsed_time;
578void Parallel_volume_editing::setup_camera(nv::index::IPerspective_camera* cam)
const
583 const mi::math::Vector< mi::Float32, 3 > from(2048.f, 1536.f,-756.f);
584 const mi::math::Vector< mi::Float32, 3 > to ( 512.f, 512.2f,-512.7f);
585 const mi::math::Vector< mi::Float32, 3 > up ( 0.f, 0.f, -1.f);
586 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
589 cam->set(from, viewdir, up);
590 cam->set_aperture(0.033f);
591 cam->set_aspect(1.0f);
592 cam->set_focal(0.03f);
593 cam->set_clip_min(2.0f);
594 cam->set_clip_max(400.0f);
598nv::index::IFrame_results* Parallel_volume_editing::render_frame(
const std::string& output_fname)
const
603 m_image_file_canvas->set_rgba_file_name(output_fname.c_str());
607 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
608 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
611 m_index_session->update(m_session_tag, dice_transaction.get());
613 mi::base::Handle<nv::index::IFrame_results> frame_results(
614 m_index_rendering->render(
616 m_image_file_canvas.get(),
617 dice_transaction.get()));
620 dice_transaction->commit();
622 frame_results->retain();
623 return frame_results.get();
628int main(
int argc,
const char* argv[])
630 nv::index::app::String_dict sdict;
631 sdict.insert(
"dice::verbose",
"3");
632 sdict.insert(
"dice::network::multicast_address",
"");
633 sdict.insert(
"dice::network::cluster_interface",
"");
634 sdict.insert(
"perlin_noise",
"0");
636 sdict.insert(
"outfname",
"frame_parallel_volume_editing");
637 sdict.insert(
"verify_image_fname",
"");
638 sdict.insert(
"verify_image_fname_second",
"");
639 sdict.insert(
"unittest_verify_image_fbase",
"");
640 sdict.insert(
"unittest_verify_image_fbase_second",
"");
641 sdict.insert(
"unittest",
"0");
642 sdict.insert(
"is_dump_comparison_image_when_failed",
"1");
643 sdict.insert(
"is_call_from_test",
"0");
646 sdict.insert(
"dice::network::mode",
"OFF");
649 sdict.insert(
"index::config::set_monitor_performance_values",
"true");
650 sdict.insert(
"index::service",
"rendering_and_compositing");
651 sdict.insert(
"index::cuda_debug_checks",
"false");
654 sdict.insert(
"index::app::components::application_layer::component_name_list",
655 "canvas_infrastructure image io data_analysis_and_processing");
657 sdict.insert(
"index::app::plugins::base_importer::enabled",
"true");
661 parallel_volume_editing.initialize(argc, argv, sdict);
665 const mi::Sint32 exit_code = parallel_volume_editing.
launch();
666 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
virtual ~Parallel_volume_editing()
Parallel_volume_editing()
int main(int argc, const char *argv[])
#define check_success(expr)