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>
26#include <nv/index/app/index_connect.h>
27#include <nv/index/app/string_dict.h>
28#include <nv/index/app/idata_analysis_and_processing.h>
82 public nv::index::app::Index_connect
102 virtual bool evaluate_options(nv::index::app::String_dict& sdict) CPP11_OVERRIDE;
105 mi::neuraylib::INetwork_configuration* network_configuration,
106 nv::index::app::String_dict& options) CPP11_OVERRIDE
111 const bool is_unittest = nv::index::app::get_bool(options.get(
"unittest"));
114 info_cout(
"NETWORK: disabled networking mode.", options);
115 network_configuration->set_mode(mi::neuraylib::INetwork_configuration:
:MODE_OFF);
119 return initialize_networking_as_default_udp(network_configuration, options);
123 mi::neuraylib::Tag add_synthetic_heightfield(
124 const mi::neuraylib::Tag& session_tag,
125 const std::string& synthetic_heightfield_type_str,
126 const std::string& technique_param_str,
127 const mi::math::Vector<mi::Uint32, 2>& heightfield_size,
128 mi::neuraylib::IDice_transaction* dice_transaction);
129 std::vector<mi::Uint32> evaluate_data_locality(
130 const nv::index::IDistributed_data_locality* data_locality,
131 const mi::math::Bbox<mi::Uint32, 2>& query_bound,
132 const mi::neuraylib::Tag& scene_element_tag,
133 const std::string& scene_element_type)
const;
139 mi::Float32 analyze_heightfield_data(
140 const mi::neuraylib::Tag& heightfield_tag,
141 const mi::neuraylib::Tag& session_tag,
142 mi::neuraylib::IDice_transaction* dice_transaction)
const;
144 void edit_heightfield_data(
145 const mi::neuraylib::Tag& heightfield_tag,
146 const mi::neuraylib::Tag& session_tag,
147 mi::neuraylib::IDice_transaction* dice_transaction)
const;
151 nv::index::IFrame_results* render_frame(
const std::string& output_fname)
const;
154 mi::neuraylib::Tag m_session_tag;
156 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
158 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
167 mi::neuraylib::Tag heightfield_tag;
169 m_cluster_configuration =
170 get_index_interface()->
171 get_api_component<nv::index::ICluster_configuration>();
175 m_image_file_canvas = create_image_file_canvas(get_application_layer_interface());
180 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
184 m_session_tag = m_index_session->create_session(dice_transaction.get());
186 mi::base::Handle<const nv::index::ISession> session(dice_transaction->access<nv::index::ISession>(m_session_tag));
189 mi::base::Handle< nv::index::IScene > scene_edit(
190 dice_transaction->edit<nv::index::IScene>(session->get_scene()));
195 mi::base::Handle<nv::index::IConfig_settings> edit_config_settings(dice_transaction->edit<nv::index::IConfig_settings>(session->get_config()));
199 edit_config_settings->set_force_data_upload(
true);
204 const mi::math::Vector<mi::Uint32, 3> subcube_size(30);
205 mi::math::Vector<mi::Float32, 3> minimal_volume_scaling;
206 edit_config_settings->get_minimal_volume_scaling(minimal_volume_scaling);
207 INFO_LOG <<
"minimal_volume_scaling: " << minimal_volume_scaling
208 <<
", border: " << edit_config_settings->get_subcube_border_size()
209 <<
", rotation support: "
210 << edit_config_settings->get_volume_rotation_supported();
211 edit_config_settings->set_subcube_configuration(
213 edit_config_settings->get_continuous_volume_translation_supported(),
214 edit_config_settings->get_subcube_border_size(),
215 edit_config_settings->get_volume_rotation_supported(),
216 minimal_volume_scaling);
225 mi::math::Vector<mi::Uint32, 2> heightfield_size(1000, 1000);
228 heightfield_size = mi::math::Vector<mi::Uint32, 2>(100, 100);
230 const std::string synthetic_heightfield_type_str =
"i";
231 const std::string technique_param_str =
"";
232 heightfield_tag = add_synthetic_heightfield(
233 m_session_tag, synthetic_heightfield_type_str, technique_param_str, heightfield_size,
234 dice_transaction.get());
237 INFO_LOG <<
"Created a synthetic regular heightfield: tag = " << heightfield_tag.id;
242 mi::base::Handle<nv::index::IScene> scene(dice_transaction->edit<nv::index::IScene>(session->get_scene()));
245 const mi::math::Bbox<mi::Float32, 3> global_region_of_interest(
246 0.0f, 0.0f, 0.0f, 1000.f,1000.f,1000.f);
247 scene->set_clipped_bounding_box(global_region_of_interest);
250 mi::base::Handle< nv::index::IPerspective_camera > cam(
251 scene_edit->create_camera<nv::index::IPerspective_camera>());
253 const mi::neuraylib::Tag camera_tag = dice_transaction->store(cam.get());
256 scene->set_camera(camera_tag);
258 const mi::math::Vector<mi::Uint32, 2> buffer_resolution(1024, 1024);
259 m_image_file_canvas->set_resolution(buffer_resolution);
261 dice_transaction->commit();
266 const std::string fname =
"";
273 INFO_LOG <<
"Analyzing heightfield data before editing ...";
274 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
275 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
277 mi::Float32 value = analyze_heightfield_data(heightfield_tag, m_session_tag, dice_transaction.get());
288 dice_transaction->commit();
293 INFO_LOG <<
"Editing heightfield data...";
294 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
295 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
298 edit_heightfield_data(heightfield_tag, m_session_tag, dice_transaction.get());
300 dice_transaction->commit();
305 INFO_LOG <<
"Analyzing heightfield data after editing ...";
306 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
307 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
309 mi::Float32 value = analyze_heightfield_data(heightfield_tag, m_session_tag, dice_transaction.get());
318 dice_transaction->commit();
327 const std::string com_name = sdict.get(
"command:",
"<unknown_command>");
328 m_is_unittest = nv::index::app::get_bool(sdict.get(
"unittest",
"false"));
332 if (nv::index::app::get_bool(sdict.get(
"is_call_from_test",
"false")))
334 sdict.insert(
"is_dump_comparison_image_when_failed",
"0");
336 sdict.insert(
"dice::verbose",
"2");
339 info_cout(std::string(
"running ") + com_name, sdict);
342 if (sdict.is_defined(
"h"))
345 <<
"info: Usage: " << com_name <<
" [option]\n"
347 <<
" print this message\n"
348 <<
" [-dice::network::multicast_address address]\n"
349 <<
" set multicast address. (default: ["
350 << sdict.get(
"dice::network::multicast_address") +
"])\n"
351 <<
" [-dice::network::cluster_interface]\n"
352 <<
" set cluster interface. (default: ["
353 << sdict.get(
"dice::network::cluster_interface") +
"])\n"
361mi::neuraylib::Tag Distributed_heightfield_data::add_synthetic_heightfield(
362 const mi::neuraylib::Tag& session_tag,
363 const std::string& synthetic_heightfield_type_str,
364 const std::string& technique_param_str,
365 const mi::math::Vector<mi::Uint32, 2>& heightfield_size,
366 mi::neuraylib::IDice_transaction* dice_transaction)
375 nv::index::app::String_dict heightfield_opt;
376 heightfield_opt.insert(
"args::type",
"heightfield");
377 heightfield_opt.insert(
"args::importer",
"nv::index::plugin::legacy_importer.Synthetic_heightfield_generator");
378 heightfield_opt.insert(
"args::synthetic_type", synthetic_heightfield_type_str);
379 heightfield_opt.insert(
"args::parameter", technique_param_str);
380 std::stringstream sstr;
381 sstr << heightfield_size.x <<
" " << heightfield_size.y;
382 heightfield_opt.insert(
"args::size", sstr.str());
383 heightfield_opt.insert(
"args::range",
"0.1 1000");
384 nv::index::IDistributed_data_import_callback* importer_callback =
385 get_importer_from_application_layer(
386 get_application_layer_interface(),
387 "nv::index::plugin::legacy_importer.Synthetic_heightfield_generator",
390 mi::base::Handle<nv::index::ISession> session(dice_transaction->edit<nv::index::ISession>(session_tag));
394 mi::base::Handle<nv::index::IScene> scene_edit(dice_transaction->edit<nv::index::IScene>(session->get_scene()));
397 const std::string heightfield_name =
"distributed_heightfield_data";
398 const mi::math::Vector<mi::Float32, 3> scale(1.0f, 1.0f, 1.0f);
399 const mi::Float32 rotate_k = 0.0f;
400 const mi::math::Vector<mi::Float32, 3> translate(1.0f, 1.0f, 1.0f);
403 const mi::math::Vector<mi::Float32, 2> heightfield_elevation_range(0.0f, 2000.0f);
404 mi::base::Handle<nv::index::IRegular_heightfield> heightfield_scene_element(
405 scene_edit->create_regular_heightfield(
406 scale, rotate_k, translate,
408 heightfield_elevation_range,
411 check_success(heightfield_scene_element.is_valid_interface());
414 heightfield_scene_element->set_name(heightfield_name.c_str());
415 const mi::neuraylib::Tag heightfield_tag = dice_transaction->store_for_reference_counting(heightfield_scene_element.get());
419 mi::base::Handle<nv::index::IStatic_scene_group> static_group_node(
420 scene_edit->create_scene_group<nv::index::IStatic_scene_group>());
424 mi::base::Handle<nv::index::IDirectional_headlight> headlight(scene_edit->create_attribute<nv::index::IDirectional_headlight>());
427 const mi::math::Color_struct color_intensity = { 1.0f, 1.0f, 1.0f, 1.0f, };
428 headlight->set_intensity(color_intensity);
429 headlight->set_direction(mi::math::Vector<mi::Float32, 3>(1.0f, -1.0f, -1.0f));
430 const mi::neuraylib::Tag headlight_tag = dice_transaction->store_for_reference_counting(headlight.get());
433 static_group_node->append(headlight_tag, dice_transaction);
436 mi::base::Handle<nv::index::IPhong_gl> phong_1(scene_edit->create_attribute<nv::index::IPhong_gl>());
439 const mi::neuraylib::Tag phong_1_tag = dice_transaction->store_for_reference_counting(phong_1.get());
441 static_group_node->append(phong_1_tag, dice_transaction);
444 static_group_node->append(heightfield_tag, dice_transaction);
445 const mi::neuraylib::Tag static_group_node_tag = dice_transaction->store_for_reference_counting(static_group_node.get());
449 scene_edit->append(static_group_node_tag, dice_transaction);
452 DEBUG_LOG <<
"Adding the following synthetic heightfield to the scene: " << heightfield_name
453 <<
", size: " << heightfield_size
454 <<
", scale: " << scale
455 <<
", rotate_k: " << rotate_k
456 <<
", translate: " << translate
457 <<
", (value) range: " << heightfield_elevation_range;
459 return heightfield_tag;
463std::vector<mi::Uint32> Distributed_heightfield_data::evaluate_data_locality(
464 const nv::index::IDistributed_data_locality* data_locality,
465 const mi::math::Bbox<mi::Uint32, 2>& query_bound,
466 const mi::neuraylib::Tag& scene_element_tag,
467 const std::string& scene_element_type)
const
470 std::vector<mi::Uint32> cluster_host_ids;
471 std::ostringstream hosts;
472 std::ostringstream locality_report;
473 for (mi::Uint32 i=0; i < data_locality->get_nb_cluster_nodes(); ++i)
478 const mi::Uint32 host_id = data_locality->get_cluster_node(i);
479 cluster_host_ids.push_back(host_id);
482 hosts << host_id <<
" ";
484 const mi::Size nb_subregions = data_locality->get_nb_bounding_box(host_id);
485 locality_report <<
"Host " << host_id <<
" stores part of the distributed data in the following " << nb_subregions <<
" regions:\n";
486 for (mi::Uint32 j=0; j<nb_subregions; ++j)
488 const mi::math::Bbox<mi::Sint32, 3> bbox = data_locality->get_bounding_box(host_id, j);
489 locality_report <<
" " << (j+1) <<
")\t" << bbox;
490 if (j < nb_subregions - 1)
492 locality_report <<
"\n";
497 <<
"Data locality for a " << scene_element_type
498 <<
" with tag id " << scene_element_tag.id
499 <<
" and query region " << query_bound <<
"\n:"
500 <<
"The distributed data is located on the following hosts (ids): [ " << hosts.str() <<
"]." <<
"\n"
501 << locality_report.str()
504 return cluster_host_ids;
508mi::Float32 Distributed_heightfield_data::analyze_heightfield_data(
509 const mi::neuraylib::Tag& heightfield_tag,
510 const mi::neuraylib::Tag& session_tag,
511 mi::neuraylib::IDice_transaction* dice_transaction)
const
513 mi::base::Handle<const nv::index::ISession> the_session(dice_transaction->access<nv::index::ISession>(session_tag));
516 mi::base::Handle<const nv::index::IRegular_heightfield>
heightfield(
517 dice_transaction->access<nv::index::IRegular_heightfield>(heightfield_tag));
520 const mi::math::Bbox<mi::Float32, 3> heightfield_bbox =
heightfield->get_IJK_bounding_box();
522 const mi::math::Bbox<mi::Uint32, 2> query_bbox(
523 static_cast<mi::Uint32
>(heightfield_bbox.min.x),
static_cast<mi::Uint32
>(heightfield_bbox.min.y),
524 static_cast<mi::Uint32
>(heightfield_bbox.max.x),
static_cast<mi::Uint32
>(heightfield_bbox.max.y));
527 const mi::neuraylib::Tag dist_layout_tag = the_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));
535 mi::base::Handle<nv::index::Regular_heightfield_locality_query_mode> mode(
536 new nv::index::Regular_heightfield_locality_query_mode(heightfield_tag, query_bbox,
false));
537 mi::base::Handle<nv::index::IDistributed_data_locality> data_locality(
538 distribution_layout->get_data_locality<nv::index::IRegular_heightfield>(mode.get(), dice_transaction));
541 std::vector<mi::Uint32> cluster_host_ids = evaluate_data_locality(
542 data_locality.get(), query_bbox, heightfield_tag,
heightfield->get_class_name());
545 const mi::neuraylib::Tag data_access_tag = the_session->get_data_access_factory();
548 mi::base::Handle<const nv::index::IDistributed_data_access_factory> access_factory(
549 dice_transaction->access<nv::index::IDistributed_data_access_factory>(data_access_tag));
552 mi::base::Handle<nv::index::IRegular_heightfield_data_access> data_access(
553 access_factory->create_regular_heightfield_data_access(heightfield_tag));
557 data_access->access(query_bbox, dice_transaction);
559 const mi::math::Bbox<mi::Uint32, 2> effective_bbox = data_access->get_patch_bounding_box();
560 INFO_LOG << effective_bbox;
561 INFO_LOG << query_bbox;
564 const mi::Float32* height_data = data_access->get_elevation_values();
566 mi::Sint64 count = effective_bbox.volume();
567 mi::Float32 height_sum = 0;
568 mi::Float32 height_min = std::numeric_limits<mi::Float32>::max();
569 mi::Float32 height_max = std::numeric_limits<mi::Float32>::min();
571 for (mi::Sint64 k = 0; k < count; ++k)
573 mi::Float32 height = height_data[k];
574 height_sum += height;
576 if (height > height_max)
580 if (height < height_min)
586 mi::Float32 avg =
static_cast<mi::Float32
>(height_sum) /
static_cast<mi::Float32
>(count);
587 INFO_LOG <<
"Heightfield height: "
589 <<
", min=" << height_min
590 <<
", max=" << height_max
597void Distributed_heightfield_data::edit_heightfield_data(
598 const mi::neuraylib::Tag& heightfield_tag,
599 const mi::neuraylib::Tag& session_tag,
600 mi::neuraylib::IDice_transaction* dice_transaction)
const
602 mi::base::Handle<const nv::index::ISession> the_session(dice_transaction->access<nv::index::ISession>(session_tag));
605 mi::base::Handle<const nv::index::IRegular_heightfield>
heightfield(dice_transaction->access<nv::index::IRegular_heightfield>(heightfield_tag));
608 const mi::math::Bbox<mi::Float32, 3> heightfield_bbox =
heightfield->get_IJK_bounding_box();
610 const mi::math::Bbox<mi::Uint32, 2> query_bbox(
611 static_cast<mi::Uint32
>(heightfield_bbox.min.x),
static_cast<mi::Uint32
>(heightfield_bbox.min.y),
612 static_cast<mi::Uint32
>(heightfield_bbox.max.x),
static_cast<mi::Uint32
>(heightfield_bbox.max.y));
615 const mi::neuraylib::Tag dist_layout_tag = the_session->get_distribution_layout();
617 mi::base::Handle<const nv::index::IData_distribution> distribution_layout(dice_transaction->access<nv::index::IData_distribution>(dist_layout_tag));
621 mi::base::Handle<nv::index::Regular_heightfield_locality_query_mode> mode(
622 new nv::index::Regular_heightfield_locality_query_mode(heightfield_tag, query_bbox,
false));
623 mi::base::Handle<nv::index::IDistributed_data_locality> data_locality(
624 distribution_layout->get_data_locality<nv::index::IRegular_heightfield>(mode.get(), dice_transaction));
627 std::vector<mi::Uint32> cluster_host_ids = evaluate_data_locality(
634 const bool do_scaling =
true;
635 const mi::Float32 scale_factor = 0.5f;
636 INFO_LOG <<
"-----------------Scaling the height field's elevation values using the following scale factor: " << scale_factor <<
"... ";
638 std::vector<mi::math::Vector_struct<mi::Float32, 2> > region;
639 region.push_back(mi::math::Vector<mi::Float32, 2>(heightfield_bbox.min.x, heightfield_bbox.min.y));
640 region.push_back(mi::math::Vector<mi::Float32, 2>(heightfield_bbox.min.x, heightfield_bbox.max.y));
641 region.push_back(mi::math::Vector<mi::Float32, 2>(heightfield_bbox.max.x, heightfield_bbox.max.y));
642 region.push_back(mi::math::Vector<mi::Float32, 2>(heightfield_bbox.max.x, heightfield_bbox.min.y));
646 mi::base::Handle<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing> processing(
647 get_application_layer_interface()->get_api_component<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing>());
652 mi::base::Handle<nv::index::IDistributed_data_job> distributed_job(
653 processing->get_sample_tool_set()->create_heightfield_elevation_editing(
654 heightfield_tag, do_scaling, scale_factor, ®ion.at(0), 4));
657 distribution_layout->create_scheduler()->execute(distributed_job.get(), dice_transaction);
661nv::index::IFrame_results* Distributed_heightfield_data::render_frame(
const std::string& output_fname)
const
666 m_image_file_canvas->set_rgba_file_name(output_fname.c_str());
670 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
671 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
674 m_index_session->update(m_session_tag, dice_transaction.get());
676 mi::base::Handle<nv::index::IFrame_results> frame_results(
677 m_index_rendering->render(
679 m_image_file_canvas.get(),
680 dice_transaction.get()));
683 dice_transaction->commit();
685 frame_results->retain();
686 return frame_results.get();
693int main(
int argc,
const char* argv[])
695 nv::index::app::String_dict sdict;
696 sdict.insert(
"dice::verbose",
"3");
697 sdict.insert(
"unittest",
"0");
698 sdict.insert(
"dice::network::multicast_address",
"224.1.3.2");
699 sdict.insert(
"dice::network::cluster_interface",
"");
700 sdict.insert(
"is_dump_comparison_image_when_failed",
"1");
701 sdict.insert(
"is_call_from_test",
"0");
704 sdict.insert(
"dice::network::mode",
"OFF");
707 sdict.insert(
"index::config::set_monitor_performance_values",
"true");
708 sdict.insert(
"index::service",
"rendering_and_compositing");
709 sdict.insert(
"index::cuda_debug_checks",
"false");
712 sdict.insert(
"index::app::components::application_layer::component_name_list",
713 "canvas_infrastructure image io data_analysis_and_processing");
714 sdict.insert(
"index::app::plugins::base_importer::enabled",
"true");
715 sdict.insert(
"index::app::plugins::legacy_importer::enabled",
"true");
719 distributed_heightfield_data.initialize(argc, argv, sdict);
720 check_success(distributed_heightfield_data.is_initialized());
723 const mi::Sint32 exit_code = distributed_heightfield_data.
launch();
724 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 ~Distributed_heightfield_data()
Distributed_heightfield_data()
int main(int argc, const char *argv[])
#define check_success(expr)