18#define USE_NVINDEX_ACCESS
19#include "utility/example_shared.h"
22#include <nv/index/icamera.h>
23#include <nv/index/iindex.h>
24#include <nv/index/iscene.h>
25#include <nv/index/isession.h>
26#include <nv/index/icolormap.h>
27#include <nv/index/isampling_rays.h>
28#include <nv/index/iindex_debug_configuration.h>
30#include <nv/index/app/index_connect_.h>
32#include "utility/app_rendering_context.h"
33#include "utility/canvas_utility.h"
34#include "utility/example_performance_logger.h"
46class Create_ray_sampling_index_connect:
47 public nv::index::app::Index_connect
50 Create_ray_sampling_index_connect()
57 virtual ~Create_ray_sampling_index_connect()
69 virtual bool initialize_networking(
70 mi::neuraylib::INetwork_configuration* network_configuration,
71 nv::index::app::String_dict& options) CPP11_OVERRIDE
76 const bool is_unittest = nv::index::app::get_bool(options.get(
"unittest"));
79 info_cout(
"NETWORK: disabled networking mode.", options);
80 network_configuration->set_mode(mi::neuraylib::INetwork_configuration:
:MODE_OFF);
84 return initialize_networking_as_default_udp(network_configuration, options);
90 mi::neuraylib::Tag m_session_tag;
92 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
94 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
96 std::string m_outfname;
119class Camera_ray_generator
123 Camera_ray_generator(
124 const nv::index::IScene* scene,
125 const nv::index::ICamera* camera,
126 const mi::math::Vector<mi::Uint32, 2>& resolution);
133 mi::math::Vector<mi::Float32, 3>& ray_origin,
134 mi::math::Vector<mi::Float32, 3>& ray_direction)
const;
136 const mi::math::Vector<mi::Uint32, 2>& resolution()
const {
143 mi::math::Vector<mi::Float32, 3> ray_origin;
144 mi::math::Vector<mi::Float32, 3> right;
145 mi::math::Vector<mi::Float32, 3> up;
146 mi::math::Vector<mi::Float32, 3> to;
149 mi::math::Vector<mi::Float32, 3> image_origin;
150 mi::math::Matrix<mi::Float32, 4, 4> object_to_world_inv;
155 mi::math::Vector<mi::Uint32, 2> m_resolution;
159mi::math::Matrix<mi::Float64, 4, 4> get_camera_matrix(
160 const nv::index::ICamera* camera,
161 const mi::math::Vector<mi::Float32, 3>& global_translate)
163 mi::math::Vector<mi::Float64, 3> eyepos(camera->get_eye_point());
164 eyepos -= mi::math::Vector<mi::Float64, 3>(global_translate);
165 mi::math::Vector<mi::Float64, 3> up_direction(camera->get_up_direction());
168 mi::math::Vector<mi::Float64, 3> zdir(camera->get_view_direction());
171 mi::math::Vector<mi::Float64, 3> xdir = mi::math::cross(up_direction, zdir);
173 mi::math::Vector<mi::Float64, 3> ydir = mi::math::cross(zdir, xdir);
176 mi::math::Matrix<mi::Float64, 4, 4> lookat_mat(
177 xdir.x, ydir.x, zdir.x, 0.,
178 xdir.y, ydir.y, zdir.y, 0.,
179 xdir.z, ydir.z, zdir.z, 0.,
181 -mi::math::dot(xdir, eyepos),
182 -mi::math::dot(ydir, eyepos),
183 -mi::math::dot(zdir, eyepos),
190Camera_ray_generator::Camera_ray_generator(
191 const nv::index::IScene* scene,
192 const nv::index::ICamera* camera,
193 const mi::math::Vector<mi::Uint32, 2>& resolution)
194 : m_resolution(resolution)
197 const bool is_persp_camera = nv::index::IPerspective_camera::compare_iid(camera->get_iid());
198 const bool is_ortho_camera = nv::index::IOrthographic_camera::compare_iid(camera->get_iid());
199 if (!is_persp_camera && !is_ortho_camera) {
203 m_params.orthographic = is_ortho_camera;
205 mi::Float32 focal_length = 1.f;
206 mi::Float32 aperture = 0.33f;
207 mi::Float32 aspect = 1.f;
209 if (is_persp_camera) {
210 mi::base::Handle<const nv::index::IPerspective_camera> p_camera;
211 p_camera = camera->get_interface<
const nv::index::IPerspective_camera>();
212 focal_length =
static_cast<mi::Float32
>(p_camera->get_focal());
213 aperture =
static_cast<mi::Float32
>(p_camera->get_aperture());
214 aspect =
static_cast<mi::Float32
>(p_camera->get_aspect());
216 if (is_ortho_camera) {
217 mi::base::Handle<const nv::index::IOrthographic_camera> o_camera;
218 o_camera = camera->get_interface<
const nv::index::IOrthographic_camera>();
220 aperture =
static_cast<mi::Float32
>(o_camera->get_aperture());
221 aspect =
static_cast<mi::Float32
>(o_camera->get_aspect());
223 if (focal_length <= 0.f) {
return; }
224 if (aperture <= 0.f) {
return; }
225 if (aspect <= 0.f) {
return; }
226 if ((resolution.x == 0) || (resolution.y == 0)) {
return; }
229 const mi::math::Matrix<mi::Float32, 4, 4> scene_xform = scene->get_transform_matrix();
230 const mi::math::Vector<mi::Float32, 3> scene_translation(scene_xform.wx, scene_xform.wy, scene_xform.wz);
231 const mi::math::Matrix<mi::Float64, 4, 4> world_to_camera = get_camera_matrix(camera, scene_translation);
232 mi::math::Matrix<mi::Float64, 4, 4> world_to_camera_inv = world_to_camera;
233 world_to_camera_inv.invert();
236 mi::math::Vector<mi::Float32, 3> origin(
237 static_cast<float>(world_to_camera_inv.wx),
238 static_cast<float>(world_to_camera_inv.wy),
239 static_cast<float>(world_to_camera_inv.wz));
242 m_params.right.x =
static_cast<float>(-world_to_camera_inv.xx);
243 m_params.right.y =
static_cast<float>(-world_to_camera_inv.xy);
244 m_params.right.z =
static_cast<float>(-world_to_camera_inv.xz);
245 m_params.right.normalize();
248 m_params.up.x =
static_cast<float>(-world_to_camera_inv.yx);
249 m_params.up.y =
static_cast<float>(-world_to_camera_inv.yy);
250 m_params.up.z =
static_cast<float>(-world_to_camera_inv.yz);
251 m_params.up.normalize();
254 m_params.to.x =
static_cast<float>(-world_to_camera_inv.zx);
255 m_params.to.y =
static_cast<float>(-world_to_camera_inv.zy);
256 m_params.to.z =
static_cast<float>(-world_to_camera_inv.zz);
257 m_params.to.normalize();
258 m_params.to *= focal_length;
262 mi::math::Matrix<mi::Float32, 4, 4> object_to_world = scene_xform;
263 object_to_world.wx = 0.f;
264 object_to_world.wy = 0.f;
265 object_to_world.wz = 0.f;
266 m_params.object_to_world_inv = object_to_world;
267 m_params.object_to_world_inv.invert();
269 m_params.ray_origin = mi::math::transform_point(m_params.object_to_world_inv, origin);
271 const mi::Float32 frustumwidth = aperture;
272 const mi::Float32 frustumheight = frustumwidth / aspect;
273 m_params.x_mult = frustumwidth /
static_cast<float>(resolution.x);
274 m_params.y_mult = frustumheight /
static_cast<float>(resolution.y);
275 m_params.image_origin =
276 (-0.5f * frustumwidth) * m_params.right +
277 (-0.5f * frustumheight) * m_params.up;
283bool Camera_ray_generator::compute_ray(
286 mi::math::Vector<mi::Float32, 3>& ray_origin,
287 mi::math::Vector<mi::Float32, 3>& ray_direction)
const
289 if (!m_valid)
return false;
292 const mi::math::Vector<mi::Float32, 3> x = m_params.right * (m_params.x_mult * raster_x);
293 const mi::math::Vector<mi::Float32, 3> y = m_params.up * (m_params.y_mult * raster_y);
295 const mi::math::Vector<mi::Float32, 3> pixel = m_params.image_origin + x + y;
297 using mi::math::transform_vector;
298 if (m_params.orthographic) {
301 ray_origin = m_params.ray_origin - transform_vector(m_params.object_to_world_inv, pixel);
302 ray_direction = transform_vector(m_params.object_to_world_inv, m_params.to);
306 ray_origin = m_params.ray_origin;
308 ray_direction = transform_vector(m_params.object_to_world_inv, m_params.to - pixel);
310 ray_direction.normalize();
318 Nvindex_access& nvindex_accessor,
319 std::map<std::string, std::string>& opt_map,
322 info_cout(std::string(
"NVIDIA IndeX version: ") + nvindex_accessor.get_interface()->get_version(), opt_map);
324 initialize_log_module(nvindex_accessor, opt_map);
331 mi::base::Handle<mi::neuraylib::IDebug_configuration> debug_configuration(
332 nvindex_accessor.get_interface()->get_api_component<mi::neuraylib::IDebug_configuration>());
334 debug_configuration->set_option(
"check_serializer_store=1");
337 mi::base::Handle<nv::index::IIndex_debug_configuration> index_debug_cfg(
338 nvindex_accessor.get_interface()->get_api_component<nv::index::IIndex_debug_configuration>());
340 if (
has_key(opt_map,
"cuda_rtc_print_kernel_info")) {
341 index_debug_cfg->set_option(
"cuda_rtc_print_kernel_info=1");
343 if (
has_key(opt_map,
"cuda_rtc_load_sources_from_file")) {
344 index_debug_cfg->set_option(
"cuda_rtc_load_sources_from_file=1");
346 if (
has_key(opt_map,
"cuda_rtc_debug_info")) {
347 index_debug_cfg->set_option(
"cuda_rtc_debug_info=1");
349 if (
has_key(opt_map,
"cuda_rtc_disable")) {
350 index_debug_cfg->set_option(
"cuda_rtc_disable=1");
352 if (nv::index::app::get_bool(opt_map[
"profile"]) ==
true) {
353 index_debug_cfg->set_option(
"performance_values_wait=1");
357 nvindex_accessor.start_service();
361void dump_text(
const std::string& filename,
const std::string& text)
363 if (filename.empty()) {
return; }
364 WARN_LOG <<
"Dumping user program '" << filename <<
"'";
365 std::ofstream fs(filename.c_str());
372void load_text(
const std::string& filename, std::string& text)
374 if (filename.empty()) {
return; }
375 WARN_LOG <<
"Loading user program '" << filename <<
"'";
376 std::ifstream fs(filename.c_str(), std::ios_base::binary);
378 fs.seekg(0, std::ios_base::end);
379 const size_t text_size =
static_cast<size_t>(fs.tellg());
381 std::vector<char> buf(text_size + 1,
'\0');
382 fs.read(buf.data(), text_size);
389nv::index::IColormap* create_colormap(nv::index::IScene* scene)
391 nv::index::IColormap* colormap = scene->create_attribute<nv::index::IColormap>();
392 std::vector<mi::math::Color_struct> colormap_entries;
394 colormap_entries.resize(256);
395 for(mi::Uint32 i=0; i<256; ++i)
397 colormap_entries[i].r = (255.f-
static_cast<mi::Float32
>(i))/255.f;
398 colormap_entries[i].g = (255.f-
static_cast<mi::Float32
>(255 - i))/255.f;
399 colormap_entries[i].b = 1.f;
400 colormap_entries[i].a = 0.5f;
404 colormap->set_domain_boundary_mode(nv::index::IColormap:
:CLAMP_TO_EDGE);
405 colormap->set_domain(0.2f, 1.0f);
408 colormap->set_colormap(&(colormap_entries[0]), colormap_entries.size());
416 const mi::math::Vector<mi::Float32, 3>& from,
417 const mi::math::Vector<mi::Float32, 3>& up,
418 const mi::math::Bbox< mi::Float32, 3>& bbox,
419 const mi::neuraylib::Tag& camera_tag,
420 const mi::neuraylib::Tag& scene_tag,
421 mi::neuraylib::IDice_transaction* dice_transaction)
427 WARN_LOG <<
"Un-initialized bounding box and not updating the camera settings.";
432 mi::base::Handle<nv::index::IPerspective_camera>
433 camera(dice_transaction->edit<nv::index::IPerspective_camera>(camera_tag));
436 mi::base::Handle<const nv::index::IScene> scene(dice_transaction->access<
const nv::index::IScene>(scene_tag));
440 const mi::math::Bbox< mi::Float32, 3>& global_roi_bbox = scene->get_clipped_bounding_box();
441 const mi::math::Matrix<mi::Float32, 4, 4>& transform_mat = scene->get_transform_matrix();
442 const mi::math::Vector<mi::Float32, 3> new_min(mi::math::transform_point(transform_mat, global_roi_bbox.min));
443 const mi::math::Vector<mi::Float32, 3> new_max(mi::math::transform_point(transform_mat, global_roi_bbox.max));
444 const mi::math::Bbox< mi::Float32, 3> transformed_bbox(new_min, new_max);
445 const mi::math::Vector<mi::Float32, 3>& center = transformed_bbox.center();
446 const mi::Float32 rad = mi::math::euclidean_distance(transformed_bbox.max, transformed_bbox.min) / 2.0f;
448 const mi::Float32 fov_rad_2 =
static_cast<mi::Float32
>(camera->get_fov_y_rad() / 2.0);
449 const mi::Float32 dist = rad /
static_cast<mi::Float32
>(tan(fov_rad_2));
451 const mi::Float32 clip_min = 0.1f * dist;
452 const mi::Float32 clip_max = 10.f * dist;
453 camera->set_clip_min(clip_min);
454 camera->set_clip_max(clip_max);
456 const mi::math::Vector<mi::Float32, 3> eyepos = -dist * from + center;
457 mi::math::Vector<mi::Float32, 3> viewdir = center - eyepos;
460 camera->set(eyepos, viewdir, up);
462 INFO_LOG <<
"view_all_box: " << eyepos << viewdir << up <<
" clip:" << clip_min <<
" " << clip_max;
472 App_rendering_context& arc,
473 const std::string& output_fname)
478 arc.m_image_canvas->set_rgba_file_name(output_fname.c_str());
482 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
483 arc.m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
486 arc.m_iindex_session->update(arc.m_session_tag, dice_transaction.get());
488 mi::base::Handle<nv::index::IFrame_results> frame_results(
489 arc.m_iindex_rendering->render(
491 arc.m_image_canvas.get(),
492 dice_transaction.get()));
495 dice_transaction->commit();
497 frame_results->retain();
498 return frame_results.get();
503void setup_app_context(App_rendering_context& arc, Nvindex_access& nvindex_accessor)
505 arc.m_database = nvindex_accessor.get_interface()->get_api_component<mi::neuraylib::IDatabase>();
508 arc.m_global_scope = arc.m_database->get_global_scope();
512 arc.m_iindex_session = nvindex_accessor.get_interface()->get_api_component<nv::index::IIndex_session>();
515 arc.m_iindex_rendering = nvindex_accessor.get_interface()->create_rendering_interface();
518 arc.m_icluster_configuration = nvindex_accessor.get_interface()->get_api_component<nv::index::ICluster_configuration>();
519 check_success(arc.m_icluster_configuration.is_valid_interface());
522 arc.m_image_canvas = nvindex_accessor.create_image_file_canvas();
542 case 1: scene_setup = &ivol_setup;
break;
543 case 2: scene_setup = &svol_setup;
break;
544 case 3: scene_setup = &hfield_setup;
break;
545 case 4: scene_setup = &lodhfield_setup;
break;
546 case 5: scene_setup = &trimesh_setup;
break;
547 case 6: scene_setup = &shapes_setup;
break;
548 case 7: scene_setup = &overlap_setup;
break;
554bool is_overlap_scene( std::map<std::string, std::string>& opt_map)
556 return opt_map[
"scene"] ==
"7";
570 std::map<std::string, std::string>& opt_map,
571 int argc,
char* argv[])
573 const std::string com_name(argv[0]);
574 opt_map[
"user_program_mode"] =
"2";
575 opt_map[
"user_values"] =
"1";
576 opt_map[
"scene"] =
"0";
577 opt_map[
"profile"] =
"0";
578 opt_map[
"run_sampling"] =
"1";
580 opt_map[
"dice::verbose"] =
"3";
581 opt_map[
"roi"] =
"0 0 0 0 0 0";
582 opt_map[
"outfname"] =
"frame_ray_sampling";
583 opt_map[
"verify_image_fname"] =
"";
584 opt_map[
"unittest"] =
"0";
585 opt_map[
"is_dump_comparison_image_when_failed"] =
"1";
586 opt_map[
"is_call_from_test"] =
"0";
587 opt_map[
"export_sample_file"] =
"";
588 opt_map[
"verify_sample_file"] =
"";
590 for (
unsigned int i = 0; i <
num_scenes; ++i) {
594 process_command_line(argc, argv, opt_map);
596 if (nv::index::app::get_bool(opt_map[
"unittest"]))
598 if (nv::index::app::get_bool(opt_map[
"is_call_from_test"]))
600 opt_map[
"is_dump_comparison_image_when_failed"] =
"0";
602 opt_map[
"outfname"] =
"";
603 opt_map[
"dice::verbose"] =
"2";
605 info_cout(std::string(
"running ") + com_name, opt_map);
606 info_cout(std::string(
"outfname = [") + opt_map[
"outfname"] +
607 "], verify_image_fname = [" + opt_map[
"verify_image_fname"] +
608 "], dice::verbose = " + opt_map[
"dice::verbose"], opt_map);
611 if (opt_map.find(
"h") != opt_map.end()) {
612 const char* indent =
" ";
614 <<
"info: Usage: " << com_name <<
" [option]\n"
616 <<
" Print this message\n\n";
619 << indent <<
"[-scene n] \n"
620 << indent <<
" Choose scene type (default: " << opt_map[
"scene"] <<
")\n"
621 << indent <<
" 0: regular volume ... removed\n"
622 << indent <<
" 1: irregular volume (ivol)\n"
623 << indent <<
" 2: sparse volume (svol)\n"
624 << indent <<
" 3: heightfield (hfield)\n"
625 << indent <<
" 4: lod heightfield (lodhfield)\n"
626 << indent <<
" 5: triangle mesh (tmesh)\n"
627 << indent <<
" 6: shapes (plane, sphere, cone, cylinder) \n"
628 << indent <<
" 7: overlap (overlapping volumes and surfaces) \n\n"
630 << indent <<
"[-user_program_mode n] \n"
631 << indent <<
" Enable user programs for scene elements (0:none, 1:only render, 2:with inquiry method)\n"
632 << indent <<
" (default: " << opt_map[
"user_program_mode"] <<
")\n"
633 << indent <<
"[-user_values bool] \n"
634 << indent <<
" Enable user values for picking, (default: " << opt_map[
"user_values"] <<
")\n"
635 << indent <<
"[-load_user_program FILENAME] \n"
636 << indent <<
" Load user program from file. \n"
637 << indent <<
"[-dump_user_program FILENAME] \n"
638 << indent <<
" Dump builtin user program to file. \n"
639 << indent <<
"[-profile bool]\n"
640 << indent <<
" Enable performance profiling (default:" << opt_map[
"profile"] <<
")\n"
641 << indent <<
"[-run_sampling n]\n"
642 << indent <<
" How to perform ray sampling 1:post-render, 2:pre-render, 3:pre+post-render\n"
643 << indent <<
" (default: " << opt_map[
"run_sampling"] <<
")\n"
644 << indent <<
"[-export_sample_file name] \n"
645 << indent <<
" Export file with sample values.\n"
646 << indent <<
"[-verify_sample_file name] \n"
647 << indent <<
" Verify sample values with file.\n"
650 for (
unsigned int i = 0; i <
num_scenes; ++i) {
656 << indent <<
"[-dice::verbose severity_level]\n"
657 << indent <<
" Verbosity level (3 is info.). (default: " + opt_map[
"dice::verbose"] <<
")\n\n"
658 << indent <<
"[-roi \"float float float float float float\"]\n"
659 << indent <<
" Bounding box representing the region of interest (roi).\n"
660 << indent <<
"[-outfname string]\n"
661 << indent <<
" Name of the output ppm image file. When empty, no image file will be written.\n"
662 << indent <<
" A frame number and the extension (.ppm) will be added.\n"
663 << indent <<
" (default: '" << opt_map[
"outfname"] <<
"')\n\n"
664 << indent <<
"[-verify_image_fname [image_fname]]\n"
665 << indent <<
" When image_fname exist, verify the rendering image.\n"
666 << indent <<
" (default: '" << opt_map[
"verify_image_fname"] <<
"')\n\n"
667 << indent <<
"[-unittest bool]\n"
668 << indent <<
" When true, unit test mode.\n"
669 << indent <<
" (default: " << opt_map[
"unittest"] <<
")\n"
674 int iscene = nv::index::app::get_sint32(opt_map[
"scene"]);
683 Nvindex_access& nvindex_accessor,
685 App_rendering_context& arc,
686 std::map<std::string, std::string>& opt_map)
688 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
689 arc.m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
691 mi::neuraylib::IDice_transaction* transaction = dice_transaction.get();
694 arc.m_session_tag = arc.m_iindex_session->create_session(transaction);
696 mi::base::Handle<const nv::index::ISession> session(
697 transaction->access<
const nv::index::ISession>(arc.m_session_tag));
701 mi::base::Handle<nv::index::IConfig_settings> config_settings(
702 transaction->edit<nv::index::IConfig_settings>(session->get_config()));
709 config_settings->set_parallel_rendering_and_compositing(
false);
716 mi::math::Bbox< mi::Float32, 3> roi_bbox = nv::index::app::get_bbox_from_string<mi::Float32,3>(std::string(opt_map[
"roi"]));
717 if (roi_bbox.empty() || roi_bbox.is_point()) {
718 roi_bbox = nv::index::app::get_bbox_from_string<mi::Float32,3>(scene_setup->
get_roi_string());
723 if (
has_key(opt_map,
"load_user_program")) {
728 nvindex_accessor.get_application_layer_interface(),
729 scene_info, roi_bbox, arc.m_session_tag, opt_map, transaction));
731 if (
has_key(opt_map,
"dump_user_program")) {
735 mi::neuraylib::Tag camera_tag = mi::neuraylib:
:NULL_TAG;
737 mi::base::Handle< nv::index::IScene > scene_edit(
738 dice_transaction->edit<nv::index::IScene>(session->get_scene()));
743 mi::base::Handle< nv::index::IPerspective_camera > cam(
744 scene_edit->create_camera<nv::index::IPerspective_camera>());
746 camera_tag = dice_transaction->store(cam.get());
751 const mi::math::Vector<mi::Uint32, 2> buffer_resolution(1024, 1024);
752 arc.m_image_canvas->set_resolution(buffer_resolution);
756 mi::base::Handle<nv::index::IScene> scene(
757 transaction->edit<nv::index::IScene>(session->get_scene()));
761 mi::base::Handle<nv::index::IColormap> colormap(create_colormap(scene.get()));
765 const mi::neuraylib::Tag colormap_tag = transaction->store_for_reference_counting(
766 colormap.get(), mi::neuraylib:
:NULL_TAG,
"colormap");
768 scene->prepend(colormap_tag, transaction);
773 scene->set_clipped_bounding_box(roi_bbox);
779 const mi::math::Matrix<mi::Float32, 4, 4> transform_mat(
785 scene->set_transform_matrix(transform_mat);
789 scene->set_camera(camera_tag);
793 const mi::math::Vector<mi::Float32, 3> from(0.0f, 0.0f, 1.0f);
794 const mi::math::Vector<mi::Float32, 3> up(0.0f, 1.0f, 0.0f);
795 view_all_bbox(from, up, roi_bbox, camera_tag, session->get_scene(), transaction);
797 transaction->commit();
802void handle_errors(
const nv::index::IError_set* err_set)
804 std::ostringstream os;
805 const mi::Uint32 nb_err = err_set->get_nb_errors();
806 for (mi::Uint32 e = 0; e < nb_err; ++e)
808 if (e != 0) os <<
'\n';
809 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
810 os << err->get_error_string();
813 ERROR_LOG <<
"IIndex_rendering rendering call failed with the following error(s): " <<
'\n'
820 App_rendering_context& arc,
821 std::map<std::string, std::string>& opt_map)
824 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
825 arc.m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
829 mi::base::Handle<const nv::index::ISession> session(
830 dice_transaction->access<nv::index::ISession
const>(arc.m_session_tag));
833 mi::base::Handle<nv::index::IConfig_settings> edit_config_settings(
834 dice_transaction->edit<nv::index::IConfig_settings>(session->get_config()));
838 const bool do_profiling = nv::index::app::get_bool(opt_map[
"profile"]);
839 edit_config_settings->set_monitor_performance_values(do_profiling);
841 dice_transaction->commit();
847 const nv::index::IPerformance_values* performance_values,
848 std::map<std::string, std::string>& opt_map,
849 const char* info =
"")
851 if (!performance_values)
return;
852 if (nv::index::app::get_bool(opt_map[
"profile"]) ==
false) {
856 Performance_table_logger perf_logger;
858 char const*
const time_keys[] = {
860 "time_rendering_volume",
863 "time_rendering_only",
867 "time_rendering_total_sum",
868 "time_compositing_stage",
871 "time_total_rendering",
874 "time_complete_frame",
880 char const*
const value_keys[] = {
907 perf_logger.append_keys(time_keys);
908 perf_logger.append_keys(value_keys);
910 INFO_LOG << info <<
" " << perf_logger.get_table(performance_values);
913void print_sampling_performance(
914 const nv::index::IRay_sampling_result* smpl_result,
915 std::map<std::string, std::string>& opt_map)
919 const mi::base::Handle<const nv::index::IPerformance_values> performance_values(
920 smpl_result->get_performance_values());
927 const nv::index::IFrame_results* frame_results,
928 std::map<std::string, std::string>& opt_map)
931 const mi::base::Handle<const nv::index::IPerformance_values> performance_values(
932 frame_results->get_performance_values());
940struct Print_one {
void print(std::ostream& os,
const T& item) { os << item; } };
943struct Print_one<mi::math::Color_struct> {
944 void print(std::ostream& os,
const mi::math::Color_struct& c) {
945 os <<
"(" << c.r <<
" " << c.g <<
" " << c.b <<
" " << c.a <<
")";
952 Printer() : item_sep(
" ") {}
954 std::string item_sep;
958 void print_array(std::ostream& os,
const T* items, mi::Uint32 nb_items)
const {
960 for (mi::Uint32 i = 0; i < nb_items; ++i) {
961 p.print(os, items[i]); os << item_sep;
967 void print(std::ostream& os,
const std::vector<T>& vec)
const {
968 this->print_array(os, vec.data(),
static_cast<mi::Uint32
>(vec.size()));
972 void print_masked(std::ostream& os,
const T* items, mi::Uint32 nb_items,
973 const mi::Uint32* masks,
const mi::Uint32 mask)
const
976 for (mi::Uint32 i = 0; i < nb_items; ++i) {
977 if (masks[i] & mask) {
978 p.print(os, items[i]);
989 void print_masked(std::ostream& os, std::vector<T>& vec,
990 const std::vector<mi::Uint32> masks,
const mi::Uint32 mask)
const
992 this->print_masked(os, vec.data(),
static_cast<mi::Uint32
>(vec.size()),
1003inline void make_camera_ray(
1004 nv::index::IRay_sampling_query::Ray& ray,
1005 const Camera_ray_generator& camera_ray_gen,
1006 float raster_x,
float raster_y)
1008 mi::math::Vector<mi::Float32, 3> origin, direction;
1009 camera_ray_gen.compute_ray(raster_x, raster_y, origin, direction);
1010 ray.origin = origin;
1011 ray.direction = direction;
1013 ray.range.y = 1.0e30f;
1016inline float pixel_center_adjusted(
unsigned int v) {
return float(v) + 0.5f; }
1021void setup_sample_rays(
1022 const Camera_ray_generator& ray_gen,
1023 nv::index::IRay_sampling_query::Ray* rays,
1026 float center_x =
static_cast<float>(pixel_center_adjusted(ray_gen.resolution().x / 2));
1027 float center_y =
static_cast<float>(pixel_center_adjusted(ray_gen.resolution().y / 2));
1029 for (mi::Uint32 i=0; i < nb_rays; ++i) {
1030 float x = center_x + float(i);
1031 float y = center_y + float(i/4);
1032 make_camera_ray(rays[i], ray_gen, x, y);
1039mi::base::Handle<const nv::index::IRay_sampling_result>
1040perform_ray_sampling(
1041 App_rendering_context& arc,
1042 nv::index::IIndex* nvindex,
1043 std::map<std::string, std::string>& opt_map)
1046 mi::base::Handle<mi::neuraylib::IDice_transaction> transaction(
1047 arc.m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
1050 mi::base::Handle<const nv::index::ISession> session(
1051 transaction->access<
const nv::index::ISession>(arc.m_session_tag));
1054 mi::base::Handle<const nv::index::IScene> scene(
1055 transaction->access<
const nv::index::IScene>(session->get_scene()));
1058 mi::base::Handle<const nv::index::ICamera> camera(
1059 transaction->access<
const nv::index::ICamera>(scene->get_camera()));
1062 Camera_ray_generator ray_gen(
1065 arc.m_image_canvas->get_resolution());
1069 arc.m_iindex_session->update(arc.m_session_tag, transaction.get());
1073 mi::base::Handle<nv::index::IRay_sampling>
ray_sampling(
1074 nvindex->get_api_component<nv::index::IRay_sampling>());
1078 const bool enable_user_values =
1079 nv::index::app::get_bool(opt_map[
"user_values"]) &&
1080 (nv::index::app::get_sint32(opt_map[
"user_program_mode"]) >= 2);
1081 mi::base::Handle<nv::index::IRay_sampling_value_format> user_value_format;
1082 if (enable_user_values) {
1087 user_value_format =
ray_sampling->create_sampling_value_format();
1089 const mi::Uint32 nb_values = 3;
1090 const mi::Uint32 value_sizes[nb_values] = {
1091 static_cast<mi::Uint32
>(
sizeof(mi::Float32)),
1092 static_cast<mi::Uint32
>(
sizeof(mi::Sint32)),
1093 static_cast<mi::Uint32
>(
sizeof(mi::math::Vector<mi::Float32, 3>)),
1095 user_value_format->set_value_sizes(value_sizes, nb_values);
1099 mi::base::Handle<nv::index::IRay_sampling_query> ray_query(
ray_sampling->create_sampling_query());
1104 const mi::Uint32 max_samples = 1000;
1105 const mi::Uint32 nb_rays = 1;
1106 nv::index::IRay_sampling_query::Ray rays[nb_rays];
1109 if (is_overlap_scene(opt_map)) {
1111 make_camera_ray(rays[0], ray_gen, 313, 1024 - 444);
1114 setup_sample_rays(ray_gen, rays, nb_rays);
1117 ray_query->set_rays(rays, nb_rays);
1118 ray_query->set_max_samples(max_samples);
1122 mi::base::Handle<const nv::index::IRay_sampling_result> smpl_result;
1125 user_value_format.get(),
1126 arc.m_iindex_rendering.get(),
1130 transaction->commit();
1139void print_sampling_diagnostics(
1140 const nv::index::IRay_sampling_result* smpl_result,
1141 mi::neuraylib::IDice_transaction* dice_transaction)
1144 if (!smpl_result->is_valid()) {
1145 ERROR_LOG <<
"Invalid ray sampling result.";
1149 mi::base::Handle<const nv::index::IRay_sampling_query> query(smpl_result->get_query());
1150 mi::base::Handle<const nv::index::IRay_sampling_value_format> value_format(smpl_result->get_value_format());
1153 if (query->get_nb_rays() < 1) {
1157 const mi::Uint32 ray_idx = 0;
1158 const mi::Uint32 nb_samples = smpl_result->get_nb_samples(ray_idx);
1159 std::ostringstream ss;
1160 ss <<
"Ray sampling - got " << nb_samples <<
" samples.";
1162 if (nb_samples == 0) {
1163 INFO_LOG << ss.str();
1168 const mi::Uint32 nb_first_samples = std::min(nb_samples, 15u);
1169 nv::index::IRay_sampling_result::Sample_range srange;
1170 srange.first_sample = 0;
1171 srange.nb_samples = nb_first_samples;
1172 srange.ray_index = ray_idx;
1175 std::vector<mi::Float32> distances(nb_first_samples);
1176 check_success(smpl_result->get_distances(srange, distances.data()));
1178 std::vector<mi::math::Color_struct> colors(nb_first_samples);
1179 check_success(smpl_result->get_colors(srange, colors.data()));
1181 std::vector<mi::Uint32> object_ids(nb_first_samples);
1182 check_success(smpl_result->get_object_ids(srange, object_ids.data()));
1186 printer.postfix = nb_first_samples < nb_samples ?
" ..." :
"";
1188 ss <<
"\ndistances: \n " << std::setprecision(4);
1189 printer.print(ss, distances);
1191 ss <<
"\ncolors: \n " << std::setprecision(3);
1192 printer.item_sep =
"\n ";
1193 printer.print(ss, colors);
1195 ss <<
"\nobject ids: \n ";
1196 printer.item_sep =
" ";
1197 printer.print(ss, object_ids);
1201 ss <<
"\nobject infos: #" << smpl_result->get_nb_object_infos() <<
"\n";
1204 std::vector<mi::Uint32> all_obj_ids = object_ids;
1205 std::sort(all_obj_ids.begin(), all_obj_ids.end());
1206 all_obj_ids.resize(std::distance(all_obj_ids.begin(),
1207 std::unique(all_obj_ids.begin(), all_obj_ids.end())));
1208 for (std::vector<mi::Uint32>::const_iterator it = all_obj_ids.begin();
1209 it != all_obj_ids.end(); ++it)
1211 ss <<
" [" << *it <<
"]: ";
1212 mi::base::Handle<const nv::index::IRay_sampling_object_info> obj_info(
1213 smpl_result->get_object_info(*it));
1214 if (!obj_info.is_valid_interface()) {
1218 mi::neuraylib::Tag tag = obj_info->get_scene_element();
1219 ss <<
"tag: " << tag;
1220 if (
const char* name = dice_transaction->tag_to_name(tag)) {
1221 ss <<
" ('" << name <<
"')";
1223 mi::base::Handle<const nv::index::IScene_path> scene_path(
1224 obj_info->get_scene_path());
1225 if (scene_path.is_valid_interface()) {
1226 ss <<
" scene_path: ";
1227 for (mi::Uint32 si = 0, nb = scene_path->get_length(); si < nb; ++si) {
1228 ss << scene_path->get_node(si) <<
" ";
1237 if (value_format.is_valid_interface()) {
1239 check_success(value_format->get_value_size(0) ==
static_cast<mi::Uint32
>(
sizeof(
float)));
1241 std::vector<mi::Float32> values1(nb_first_samples);
1242 std::vector<mi::Sint32> values2(nb_first_samples);
1243 std::vector<mi::math::Vector<mi::Float32, 3> > values3(nb_first_samples);
1244 std::vector<mi::Uint32> value_masks(nb_first_samples);
1245 check_success(smpl_result->get_user_value_masks(srange, value_masks.data()));
1246 check_success(smpl_result->get_user_values(srange, 0 , values1.data()));
1247 check_success(smpl_result->get_user_values(srange, 1 , values2.data()));
1248 check_success(smpl_result->get_user_values(srange, 2 , values3.data()));
1249 ss <<
"\nuser value masks: \n ";
1250 printer.item_sep =
" ";
1251 printer.print(ss, value_masks);
1253 ss <<
"\nuser values1: \n ";
1254 printer.item_sep =
"\n ";
1255 printer.print_masked(ss, values1, value_masks, 1u << 0);
1256 ss <<
"\nuser values2: \n ";
1257 printer.item_sep =
" ";
1258 printer.print_masked(ss, values2, value_masks, 1u << 1);
1259 ss <<
"\nuser values3: \n ";
1260 printer.item_sep =
"\n ";
1261 printer.print_masked(ss, values3, value_masks, 1u << 2);
1264 INFO_LOG << ss.str();
1270void determine_first_opaque_sample(
const nv::index::IRay_sampling_result* smpl_result)
1272 const char* info =
" Determine first opaque sample:\n ";
1275 if (!smpl_result->is_valid()) {
1276 ERROR_LOG << info <<
"Invalid ray sampling result.\n";
1280 mi::base::Handle<const nv::index::IRay_sampling_query> query(smpl_result->get_query());
1281 mi::base::Handle<const nv::index::IRay_sampling_value_format> value_format(smpl_result->get_value_format());
1284 if (query->get_nb_rays() < 1) {
1285 ERROR_LOG << info <<
"No sample ray.\n";
1289 const mi::Uint32 ray_idx = 0;
1290 const mi::Uint32 nb_samples = smpl_result->get_nb_samples(ray_idx);
1292 if (nb_samples == 0) {
1293 INFO_LOG << info <<
"No sample found.\n";
1297 nv::index::IRay_sampling_result::Sample_range srange;
1298 srange.first_sample = 0;
1299 srange.nb_samples = nb_samples;
1300 srange.ray_index = ray_idx;
1302 std::vector<mi::math::Color_struct> colors(nb_samples);
1303 check_success(smpl_result->get_colors(srange, colors.data()));
1305 mi::Uint32 opaque_idx = nb_samples;
1306 for (mi::Uint32 i = 0; i < nb_samples; ++i) {
1307 if (colors[i].a >= 0.99f) {
1312 if (opaque_idx == nb_samples) {
1313 INFO_LOG << info <<
"No opaque color was found in samples.\n";
1317 srange.first_sample = opaque_idx;
1318 srange.nb_samples = 1;
1320 const mi::math::Color color = colors[opaque_idx];
1322 mi::Float32 distance = 0.f;
1323 check_success(smpl_result->get_distances(srange, &distance));
1324 mi::Uint32 obj_id = 0;
1325 check_success(smpl_result->get_object_ids(srange, &obj_id));
1327 mi::base::Handle<const nv::index::IRay_sampling_object_info>
1328 obj_info(smpl_result->get_object_info(obj_id));
1329 if (!obj_info.is_valid_interface())
1331 ERROR_LOG << info <<
"The scene element id " << obj_id <<
" does not refer to a valid scene element tag.\n";
1335 const mi::neuraylib::Tag& scene_element_tag = obj_info->get_scene_element();
1337 INFO_LOG << info <<
"The first opaque color value is at sample " << opaque_idx <<
" with color " << color
1338 <<
"\n and extracted from the scene element tag id " << scene_element_tag.id <<
"."
1339 <<
"\n The distance of the sample from the camera is " << distance <<
".\n";
1347mi::Float32 get_ray_segment_length(
1349 const std::vector<mi::Float32>& distances,
1350 const std::vector<mi::Uint32>& object_ids)
1352 const mi::Uint32 nb_samples =
static_cast<mi::Uint32
>(distances.size());
1353 if (nb_samples <= 1 || isample >= nb_samples) {
1356 const mi::Uint32 obj_id = object_ids[isample];
1359 mi::Uint32 inext = isample + 1;
1360 if (inext < nb_samples && object_ids[inext] == obj_id) {
1361 return distances[inext] - distances[isample];
1365 mi::Uint32 iprev = isample - 1;
1366 if (object_ids[iprev] == obj_id) {
1367 return distances[isample] - distances[iprev];
1375mi::Float32 opacity_correction(
1377 mi::Float32 sampling_ratio)
1379 if (sampling_ratio < 1.0e-6f) sampling_ratio = 1.0e-6f;
1380 return 1.f - powf(1.f - alpha, sampling_ratio);
1385mi::Float32 opacity_corrected_alpha(
1387 const mi::Float32 alpha,
1388 const std::vector<mi::Float32>& distances,
1389 const std::vector<mi::Uint32>& object_ids)
1391 mi::Float32 seglen = get_ray_segment_length(isample, distances, object_ids);
1392 if (seglen == 0.f)
return alpha;
1394 const mi::Float32 ref_seg_len = 1.f;
1395 return opacity_correction(alpha, seglen / ref_seg_len);
1398void determine_accumulated_alpha_value(
1399 mi::Float32 threshold,
1400 const nv::index::IRay_sampling_result* smpl_result)
1402 const char* info =
" Determine accumulated alpha value:\n ";
1405 if (!smpl_result->is_valid()) {
1406 ERROR_LOG << info <<
"Invalid ray sampling result.\n";
1410 mi::base::Handle<const nv::index::IRay_sampling_query> query(smpl_result->get_query());
1411 mi::base::Handle<const nv::index::IRay_sampling_value_format> value_format(smpl_result->get_value_format());
1414 if (query->get_nb_rays() < 1) {
1415 ERROR_LOG << info <<
"No sample ray.\n";
1419 const mi::Uint32 ray_idx = 0;
1420 const mi::Uint32 nb_samples = smpl_result->get_nb_samples(ray_idx);
1422 if (nb_samples == 0) {
1423 INFO_LOG << info <<
"No sample found.\n";
1427 nv::index::IRay_sampling_result::Sample_range srange;
1428 srange.first_sample = 0;
1429 srange.nb_samples = nb_samples;
1430 srange.ray_index = ray_idx;
1432 std::vector<mi::Float32> distances(nb_samples);
1433 check_success(smpl_result->get_distances(srange, distances.data()));
1435 std::vector<mi::math::Color_struct> colors(nb_samples);
1436 check_success(smpl_result->get_colors(srange, colors.data()));
1438 std::vector<mi::Uint32> object_ids(nb_samples);
1439 check_success(smpl_result->get_object_ids(srange, object_ids.data()));
1441 mi::math::Color dst(0.f);
1442 mi::Uint32 thresh_idx = nb_samples;
1443 for (mi::Uint32 i = 0; i < nb_samples; ++i)
1445 const mi::math::Color& src = colors[i];
1446 const mi::Float32 src_alpha = opacity_corrected_alpha(i, src.a, distances, object_ids);
1448 const mi::Float32 da_sa = (1.0f - dst.a) * src_alpha;
1449 dst.r = mi::math::saturate(dst.r + da_sa * src.r);
1450 dst.g = mi::math::saturate(dst.g + da_sa * src.g);
1451 dst.b = mi::math::saturate(dst.b + da_sa * src.b);
1452 dst.a = mi::math::saturate(dst.a + da_sa);
1454 if (dst.a >= threshold)
1461 if (thresh_idx == nb_samples) {
1462 INFO_LOG << info <<
"The accumulated color's alpha did not reach the given threshold "
1463 << threshold <<
" when determining the accumulated alpha along the given ray sampling.\n";
1467 const mi::math::Color accumulated_color = dst;
1469 srange.first_sample = thresh_idx;
1470 srange.nb_samples = 1;
1471 mi::Float32 distance = 0.f;
1472 check_success(smpl_result->get_distances(srange, &distance));
1473 mi::Uint32 obj_id = 0;
1474 check_success(smpl_result->get_object_ids(srange, &obj_id));
1476 mi::base::Handle<const nv::index::IRay_sampling_object_info> obj_info(smpl_result->get_object_info(obj_id));
1477 if (!obj_info.is_valid_interface()) {
1478 ERROR_LOG << info <<
"The scene element id " << obj_id <<
" does not refer to a valid scene element tag.";
1481 const mi::neuraylib::Tag_struct& scene_element_tag = obj_info->get_scene_element();
1482 INFO_LOG << info <<
"Based on an alpha threshold of " << threshold
1483 <<
" the accumulated color is " << accumulated_color <<
"."
1484 <<
"\n The threshold has been reached at sample " << thresh_idx
1485 <<
"\n when sampling the scene element with tag id " << scene_element_tag.id
1486 <<
"\n at a distance of " << distance <<
" from the camera.\n";
1494void print_sampling_info(
1495 const mi::base::Handle<const nv::index::IRay_sampling_result>& smpl_result,
1496 App_rendering_context& arc,
1497 std::map<std::string, std::string>& opt_map)
1499 mi::base::Handle<mi::neuraylib::IDice_transaction> transaction(
1500 arc.m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
1504 print_sampling_diagnostics(smpl_result.get(), transaction.get());
1506 if (!is_overlap_scene(opt_map)) {
1507 determine_first_opaque_sample(smpl_result.get());
1509 determine_accumulated_alpha_value(0.95f, smpl_result.get());
1511 print_sampling_performance(smpl_result.get(), opt_map);
1514 transaction->commit();
1529 const float magnitude = std::max(fabsf(a), fabsf(b));
1530 return fabsf(a - b) <= (magnitude * rel_eps);
1540 std::vector<mi::math::Vector<mi::Float32, 3> >
values3;
1543 void resize(mi::Uint32 new_size,
bool user_values)
1548 const mi::Uint32 user_size = user_values ? new_size : 0;
1557 void write(std::ostream& os,
const T& item) { os << item; }
1558 void read(std::istream& is, T& item) { is >> item; }
1562 void write(std::ostream& os,
const mi::math::Color_struct& c) {
1563 os << c.r <<
" " << c.g <<
" " << c.b <<
" " << c.a <<
" ";
1565 void read(std::istream& is, mi::math::Color_struct& c) {
1566 is >> c.r >> c.g >> c.b >> c.a;
1570template<
typename VE, mi::Size VDIM>
struct Stream_one< mi::math::Vector<VE, VDIM> > {
1571 void write(std::ostream& os,
const mi::math::Vector<VE, VDIM>& v) {
1572 for (mi::Size i = 0; i < VDIM; ++i) { os << v[i] <<
" "; }
1574 void read(std::istream& is, mi::math::Vector<VE, VDIM>& v) {
1575 for (mi::Size i = 0; i < VDIM; ++i) { is >> v[i]; }
1581 bool verify(
const T& a,
const T& b)
const {
return a == b; }
1588 bool verify(
const mi::math::Color_struct& a,
const mi::math::Color_struct& b)
const {
1590 if (!ver.
verify(a.r, b.r))
return false;
1591 if (!ver.
verify(a.g, b.g))
return false;
1592 if (!ver.
verify(a.b, b.b))
return false;
1593 if (!ver.
verify(a.a, b.a))
return false;
1597template<
typename VE, mi::Size VDIM>
struct Verify_one< mi::math::Vector<VE, VDIM> > {
1598 bool verify(
const mi::math::Vector<VE, VDIM>& a,
const mi::math::Vector<VE, VDIM>& b)
const {
1600 for (mi::Size i = 0; i < VDIM; ++i) {
1601 if (!ver.
verify(a[i], b[i]))
return false;
1607template<
typename T>
void write_array(std::ostream& os,
const std::vector<T>& v)
1609 typedef typename std::vector<T>::size_type sz_type;
1610 const sz_type nb = v.size();
1613 for (sz_type i = 0; i < nb; ++i) {
1619template<
typename T>
void read_array(std::istream& is, std::vector<T>& v)
1621 typedef typename std::vector<T>::size_type sz_type;
1626 for (sz_type i = 0; i < nb; ++i) {
1631template<
typename T>
bool verify_array(
const std::vector<T>& v,
const std::vector<T>& ref_v)
1633 typedef typename std::vector<T>::size_type sz_type;
1634 const sz_type nb = v.size();
1635 if (nb != ref_v.size())
return false;
1638 for (sz_type i = 0; i < nb; ++i) {
1639 if (!ver.
verify(v[i], ref_v[i])) {
1680template <
typename T>
1682 const nv::index::IRay_sampling_result* smpl_result,
1683 const nv::index::IRay_sampling_result::Sample_range& srange,
1684 mi::Uint32 user_value_index,
1685 const std::vector<mi::Uint32>& value_masks,
1686 std::vector<T>& values,
1687 const T& default_value)
1689 smpl_result->get_user_values(srange, user_value_index, values.data());
1690 const mi::Uint32 mask = 1u << user_value_index;
1691 for (mi::Uint32 i = 0; i < srange.nb_samples; ++i) {
1692 if ((value_masks[i] & mask) == 0) {
1693 values[i] = default_value;
1699 const nv::index::IRay_sampling_result* smpl_result,
1700 const nv::index::IRay_sampling_result::Sample_range& srange,
1701 bool has_user_values,
1704 smpl_data.
resize(srange.nb_samples, has_user_values);
1706 smpl_result->get_distances(srange, smpl_data.
distances.data());
1707 smpl_result->get_colors(srange, smpl_data.
colors.data());
1710 if (has_user_values) {
1711 smpl_result->get_user_value_masks(srange, smpl_data.
value_masks.data());
1736 mi::Uint32 max_nb_samples,
1737 const nv::index::IRay_sampling_result* smpl_result)
1739 if (!smpl_result->is_valid()) {
1743 mi::base::Handle<const nv::index::IRay_sampling_query> query(smpl_result->get_query());
1744 mi::base::Handle<const nv::index::IRay_sampling_value_format> value_format(smpl_result->get_value_format());
1746 if (!query.is_valid_interface()) {
1749 const mi::Uint32 nb_rays = query->get_nb_rays();
1754 os << nb_rays <<
'\n';
1757 const bool has_user_values = value_format.is_valid_interface();
1759 for (mi::Uint32 ray_idx = 0; ray_idx < nb_rays; ++ray_idx)
1761 const mi::Uint32 nb_samples = smpl_result->get_nb_samples(ray_idx);
1762 const mi::Uint32 nb_first_samples = std::min(nb_samples, max_nb_samples);
1764 os << ray_idx <<
" " << nb_first_samples <<
" " << has_user_values <<
'\n';
1766 if (nb_samples == 0) {
1770 nv::index::IRay_sampling_result::Sample_range srange;
1771 srange.first_sample = 0;
1772 srange.nb_samples = nb_first_samples;
1773 srange.ray_index = ray_idx;
1784 std::vector<Sampling_data>& smpl_data)
1786 mi::Uint32 nb_rays = 0;
1788 smpl_data.resize(nb_rays);
1790 for (mi::Uint32 ray_idx = 0; ray_idx < nb_rays; ++ray_idx)
1792 mi::Uint32 in_ray_idx = 0;
1793 mi::Uint32 nb_values = 0;
1794 int has_user_values = 0;
1795 is >> in_ray_idx >> nb_values >> has_user_values;
1796 if (nb_values == 0) {
1799 smpl_data[ray_idx].resize(nb_values, has_user_values != 0);
1806 const std::string& basename,
1807 std::map<std::string, std::string>& opt_map,
1808 const std::string& info)
1810 const int user_prg = nv::index::app::get_sint32(opt_map[
"user_program_mode"]);
1812 std::string filename = basename;
1813 if (!filename.empty()) {
1814 filename.append(
"__");
1815 filename.append(opt_map[
"scene"]);
1816 filename.append(
"_");
1817 filename.append(opt_map[
"user_program_mode"]);
1818 if (user_prg >= 2) {
1819 filename.append(
"_");
1820 filename.append(opt_map[
"user_values"]);
1822 filename.append(
"_");
1823 filename.append(info);
1824 filename.append(
".samples");
1830 const nv::index::IRay_sampling_result* smpl_result,
1831 std::map<std::string, std::string>& opt_map,
1832 const std::string& basename,
1833 const std::string& info)
1836 std::ofstream export_file(filename.c_str(), std::ios::out | std::ios::trunc);
1842 const nv::index::IRay_sampling_result* smpl_result,
1843 std::map<std::string, std::string>& opt_map,
1844 const std::string& basename,
1845 const std::string& info)
1847 std::vector<Sampling_data> ref_smpl_data;
1850 std::ifstream import_file(filename.c_str());
1852 if (ref_smpl_data.empty()) {
1857 if (!smpl_result->is_valid()) {
1861 mi::base::Handle<const nv::index::IRay_sampling_query> query(smpl_result->get_query());
1862 mi::base::Handle<const nv::index::IRay_sampling_value_format> value_format(smpl_result->get_value_format());
1864 if (!query.is_valid_interface()) {
1867 const mi::Uint32 nb_rays = query->get_nb_rays();
1871 if (nb_rays !=
static_cast<mi::Uint32
>(ref_smpl_data.size())) {
1876 const bool has_user_values = value_format.is_valid_interface();
1878 for (mi::Uint32 ray_idx = 0; ray_idx < nb_rays; ++ray_idx)
1882 const mi::Uint32 nb_samples = smpl_result->get_nb_samples(ray_idx);
1883 const mi::Uint32 nb_ref_samples =
static_cast<mi::Uint32
>(ref_samples.
distances.size());
1885 if (nb_samples != nb_ref_samples)
return 105;
1887 const mi::Uint32 nb_first_samples = std::min(nb_samples, nb_ref_samples);
1888 if (nb_first_samples == 0)
continue;
1890 nv::index::IRay_sampling_result::Sample_range srange;
1891 srange.first_sample = 0;
1892 srange.nb_samples = nb_first_samples;
1893 srange.ray_index = ray_idx;
1907 const nv::index::IRay_sampling_result* smpl_result,
1908 std::map<std::string, std::string>& opt_map,
1909 const std::string& info)
1912 if (!opt_map[
"export_sample_file"].empty()) {
1915 if (!opt_map[
"verify_sample_file"].empty()) {
1916 std::string ref_filename = opt_map[
"verify_sample_file"];
1919 ERROR_LOG <<
"Verification failed (" << info <<
"): " << code;
1922 INFO_LOG <<
"Verification succeeded (" << info <<
")";
1936 std::map<std::string, std::string> opt_map;
1941 const std::string comp_dso_prefix =
"libnvindex_application_layer_";
1942 const std::string plug_dso_prefix =
"libnvindex_plugin_";
1943 Nvindex_access nvindex_accessor;
1945 check_success(nvindex_accessor.load_application_layer_library());
1946 check_success(nvindex_accessor.load_application_layer_component((comp_dso_prefix +
"canvas_infrastructure").c_str()));
1947 check_success(nvindex_accessor.load_application_layer_component((comp_dso_prefix +
"data_analysis_and_processing").c_str()));
1948 check_success(nvindex_accessor.load_application_layer_component((comp_dso_prefix +
"image").c_str()));
1949 check_success(nvindex_accessor.load_application_layer_component((comp_dso_prefix +
"io").c_str()));
1950 check_success(nvindex_accessor.load_application_layer_plugin( (plug_dso_prefix +
"base_importer"). c_str()));
1951 check_success(nvindex_accessor.load_application_layer_plugin( (plug_dso_prefix +
"legacy_importer").c_str()));
1954 if (!nvindex_accessor.is_initialized())
1956 info_cout(
"Fatal error! Initialization of the IndeX library failed.", opt_map);
1960 mi::Sint32 exit_code = 0;
1962 const char* sep_line =
"----------------------------------------------------------------------------";
1964 App_rendering_context arc;
1970 INFO_LOG <<
"\n" << sep_line <<
"\n Ray Sampling Example - Scene " << scene_setup->
name() <<
"\n" << sep_line;
1974 setup_scene(nvindex_accessor, scene_setup, arc, opt_map);
1979 const mi::Uint32 ray_sampling_mode = nv::index::app::get_uint32(opt_map[
"run_sampling"]);
1982 if (ray_sampling_mode >= 2)
1984 mi::base::Handle<const nv::index::IRay_sampling_result> smpl_result =
1985 perform_ray_sampling(arc, nvindex_accessor.get_interface().get(), opt_map);
1986 INFO_LOG << sep_line;
1987 print_sampling_info(smpl_result, arc, opt_map);
1998 const mi::Sint32 frame_idx = 0;
1999 const std::string fname = get_output_file_name(opt_map[
"outfname"], frame_idx);
2002 INFO_LOG << sep_line;
2003 INFO_LOG <<
"Rendering one frame \n";
2004 mi::base::Handle<const nv::index::IFrame_results> frame_results(
2008 mi::base::Handle<const nv::index::IError_set> err_set(frame_results->get_error_set());
2009 if (err_set->any_errors())
2011 handle_errors(err_set.get());
2018 if (!(verify_canvas_result(nvindex_accessor.get_application_layer_interface(),
2019 arc.m_image_canvas.get(), opt_map[
"verify_image_fname"], opt_map)))
2026 if (ray_sampling_mode == 1 || ray_sampling_mode == 3)
2028 mi::base::Handle<const nv::index::IRay_sampling_result> smpl_result =
2029 perform_ray_sampling(arc, nvindex_accessor.get_interface().get(), opt_map);
2030 INFO_LOG << sep_line;
2031 print_sampling_info(smpl_result, arc, opt_map);
2040 nvindex_accessor.shutdown();
virtual float get_scene_scaling() const
virtual void register_classes(nv::index::IIndex *) const
virtual bool create_scene(nv::index::app::IApplication_layer *app_layer, Scene_info &scene_info, const mi::math::Bbox< mi::Float32, 3 > &roi_bbox, const mi::neuraylib::Tag &session_tag, std::map< std::string, std::string > &opt_map, mi::neuraylib::IDice_transaction *transaction) const =0
virtual void setup_camera(const mi::neuraylib::Tag &camera_tag, mi::neuraylib::IDice_transaction *transaction) const =0
virtual void adjust_configuration(nv::index::IConfig_settings *config_settings, std::map< std::string, std::string > &opt_map) const
virtual const char * get_roi_string() const =0
virtual const char * name() const =0
virtual void usage_info(Usage_helper &) const
virtual void add_arguments(Option_map &opt_map) const
void get_sample_data(const nv::index::IRay_sampling_result *smpl_result, const nv::index::IRay_sampling_result::Sample_range &srange, bool has_user_values, Sampling_data &smpl_data)
std::string make_sample_filename(const std::string &basename, std::map< std::string, std::string > &opt_map, const std::string &info)
int verify_sample_data(const Sampling_data &smpl_data, const Sampling_data &ref_smpl_data)
void export_sampling_result(std::ostream &os, mi::Uint32 max_nb_samples, const nv::index::IRay_sampling_result *smpl_result)
void export_sample_file(const nv::index::IRay_sampling_result *smpl_result, std::map< std::string, std::string > &opt_map, const std::string &basename, const std::string &info)
void write_array(std::ostream &os, const std::vector<T> &v)
bool equal_float_relative(float a, float b, const float rel_eps=1.0e-4f)
void write_sampling_data(std::ostream &os, const Sampling_data &smpl_data)
int verify_sample_file(const nv::index::IRay_sampling_result *smpl_result, std::map< std::string, std::string > &opt_map, const std::string &basename, const std::string &info)
void read_sampling_data(std::istream &is, Sampling_data &smpl_data)
void get_masked_user_value(const nv::index::IRay_sampling_result *smpl_result, const nv::index::IRay_sampling_result::Sample_range &srange, mi::Uint32 user_value_index, const std::vector< mi::Uint32 > &value_masks, std::vector<T> &values, const T &default_value)
bool verify_array(const std::vector<T> &v, const std::vector<T> &ref_v)
void import_sampling_result(std::istream &is, std::vector<Sampling_data> &smpl_data)
int handle_verification(const nv::index::IRay_sampling_result *smpl_result, std::map< std::string, std::string > &opt_map, const std::string &info)
void read_array(std::istream &is, std::vector<T> &v)
void setup_app_context(App_rendering_context &arc, Nvindex_access &nvindex_accessor)
void start_nvindex_service(Nvindex_access &nvindex_accessor, const Option_map &opt_map, const xac_compute::IXac_compute_scene_setup *scene_setup)
void dump_text(const std::string &filename, const std::string &text)
static const int num_scenes
bool has_key(const Option_map &opt_map, const std::string &key)
const IXac_compute_scene_setup * handle_arguments(Option_map &opt_map, int argc, char *argv[])
void setup_scene(Nvindex_access &nvindex_accessor, const xac_compute::IXac_compute_scene_setup *scene_setup, Compute_launch_info &info, App_rendering_context &arc, const Option_map &opt_map)
static void view_all_bbox(const Vec3f &from, const Vec3f &up, const Bbox3f &bbox, mi::neuraylib::Tag camera_tag, mi::neuraylib::Tag scene_tag, mi::neuraylib::IDice_transaction *dice_transaction)
nv::index::IFrame_results * render_frame(App_rendering_context &arc, const std::string &output_fname)
void load_text(const std::string &filename, std::string &text)
const IXac_compute_scene_setup * get_scene_setup(int i)
void print_performance(const nv::index::IPerformance_values *performance_values, const Option_map &opt_map, const char *info)
void setup_performance_monitoring(App_rendering_context &arc, const Option_map &opt_map)
int main(int argc, char *argv[])
Irregular volume setup for ray sampling example.
Sparse volume setup for ray sampling example.
#define check_success(expr)
std::string rtc_program_source
void resize(mi::Uint32 new_size, bool user_values)
std::vector< mi::Uint32 > object_ids
std::vector< mi::math::Color_struct > colors
std::vector< mi::Float32 > distances
std::vector< mi::Uint32 > value_masks
std::vector< mi::Sint32 > values2
std::vector< mi::Float32 > values1
std::vector< mi::math::Vector< mi::Float32, 3 > > values3
void read(std::istream &is, mi::math::Color_struct &c)
void write(std::ostream &os, const mi::math::Color_struct &c)
void write(std::ostream &os, const mi::math::Vector<VE, VDIM> &v)
void read(std::istream &is, mi::math::Vector<VE, VDIM> &v)
void read(std::istream &is, T &item)
void write(std::ostream &os, const T &item)
bool verify(const float &a, const float &b) const
bool verify(const mi::math::Color_struct &a, const mi::math::Color_struct &b) const
bool verify(const mi::math::Vector<VE, VDIM> &a, const mi::math::Vector<VE, VDIM> &b) const
bool verify(const T &a, const T &b) const