NVIDIA Index example code nvidia_logo_transpbg.gif Up
create_icons.cpp
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright 2023 NVIDIA Corporation. All rights reserved.
3 *****************************************************************************/
6
7#include <iostream>
8#include <sstream>
9
10// Include code shared by all examples
11#include "utility/example_shared.h"
12
13#include <nv/index/icamera.h>
14#include <nv/index/iindex.h>
15#include <nv/index/iicon.h>
16#include <nv/index/isession.h>
17#include <nv/index/iscene.h>
18#include <nv/index/iscene_group.h>
19#include <nv/index/itexture.h>
20
21#include <nv/index/app/iimage_importer.h>
22#include <nv/index/app/index_connect.h>
23#include <nv/index/app/string_dict.h>
24#include <nv/index/app/time_functions.h>
25
26#include "utility/canvas_utility.h"
27
28//----------------------------------------------------------------------
30 public nv::index::app::Index_connect
31{
32public:
34 :
35 Index_connect(),
36 m_outfname()
37 {
38 // INFO_LOG << "DEBUG: Create_icons() ctor";
39 }
40
41 virtual ~Create_icons()
42 {
43 // Note: Index_connect::~Index_connect() will be called after here.
44 // INFO_LOG << "DEBUG: ~Create_icons() dtor";
45 }
46
47 // launch application
48 mi::Sint32 launch();
49
50protected:
51 virtual bool evaluate_options(nv::index::app::String_dict& options) CPP11_OVERRIDE;
53 mi::neuraylib::INetwork_configuration* network_configuration,
54 nv::index::app::String_dict& options) CPP11_OVERRIDE
55 {
56 check_success(network_configuration != 0);
57
58 check_success(options.is_defined("unittest"));
59 const bool is_unittest = nv::index::app::get_bool(options.get("unittest"));
60 if (is_unittest)
61 {
62 info_cout("NETWORK: disabled networking mode.", options);
63 network_configuration->set_mode(mi::neuraylib::INetwork_configuration::MODE_OFF);
64 return true;
65 }
66
67 return initialize_networking_as_default_udp(network_configuration, options);
68 }
69
70private:
71 // create the scene
72 mi::neuraylib::Tag create_scene(
73 nv::index::IScene* scene_edit,
74 mi::neuraylib::IDice_transaction* dice_transaction);
75
76 void move_scene(
77 mi::neuraylib::Tag group_node_tag,
78 mi::Uint32 frame_id,
79 mi::neuraylib::IDice_transaction* dice_transaction);
80
81 void setup_camera(nv::index::IPerspective_camera* cam);
82
83 nv::index::IFrame_results* render_frame(
84 const std::string& output_fname);
85
86 // This session tag
87 mi::neuraylib::Tag m_session_tag;
88 // NVIDIA IndeX cluster configuration
89 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
90 // Application layer image file canvas (a render target)
91 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
92 // Create_icons options
93 std::string m_outfname;
94 bool m_is_unittest;
95 std::string m_iconfile;
96 std::string m_verify_image_fname_sequence;
97 std::string m_verify_image_fname;
98};
99
100//----------------------------------------------------------------------
102{
103 m_cluster_configuration = get_index_interface()->get_api_component<nv::index::ICluster_configuration>();
104 check_success(m_cluster_configuration.is_valid_interface());
105
106 // create image canvas in application_layer
107 m_image_file_canvas = create_image_file_canvas(get_application_layer_interface());
108 check_success(m_image_file_canvas.is_valid_interface());
109
110 // Verifying that local host has joined
111 // This may fail when there is a license problem.
112 check_success(is_local_host_joined(m_cluster_configuration.get()));
113
114 mi::neuraylib::Tag group_node = mi::neuraylib::NULL_TAG;
115 mi::neuraylib::Tag camera_tag = mi::neuraylib::NULL_TAG;
116
117 mi::Sint32 exit_code = 0;
118 {
119 // Obtain a DiCE transaction
120 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(create_transaction());
121 check_success(dice_transaction.is_valid_interface());
122 {
123 // Setup session information
124 m_session_tag = m_index_session->create_session(dice_transaction.get());
125 check_success(m_session_tag.is_valid());
126 mi::base::Handle<const nv::index::ISession> session(
127 dice_transaction->access<const nv::index::ISession>(m_session_tag));
128 check_success(session.is_valid_interface());
129 mi::base::Handle< nv::index::IScene > scene_edit(
130 dice_transaction->edit< nv::index::IScene >(session->get_scene()));
131 check_success(scene_edit.is_valid_interface());
132
133 // Scene setup
134 group_node = create_scene(scene_edit.get(), dice_transaction.get());
135 check_success(group_node.is_valid());
136
137 // Create a camera
138 mi::base::Handle< nv::index::IPerspective_camera > cam(
139 scene_edit->create_camera<nv::index::IPerspective_camera>());
140 check_success(cam.is_valid_interface());
141 setup_camera(cam.get());
142
143 camera_tag = dice_transaction->store(cam.get());
144 check_success(camera_tag.is_valid());
145
146 const mi::math::Vector<mi::Uint32, 2> buffer_resolution(512, 512);
147 m_image_file_canvas->set_resolution(buffer_resolution);
148
149 // Set up the region of interest
150 const mi::math::Bbox_struct<mi::Float32, 3> xyz_roi_st = {
151 { 0.0f, 0.0f, 0.0f, },
152 { 500.0f, 500.0f, 500.0f, },
153 };
154
155 // set the region of interest
156 const mi::math::Bbox< mi::Float32, 3 > xyz_roi(xyz_roi_st);
157 check_success(xyz_roi.is_volume());
158 scene_edit->set_clipped_bounding_box(xyz_roi_st);
159
160 // Set the scene global transformation matrix.
161 // only change the coordinate system
162 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(
163 1.0f, 0.0f, 0.0f, 0.0f,
164 0.0f, 1.0f, 0.0f, 0.0f,
165 0.0f, 0.0f, -1.0f, 0.0f,
166 0.0f, 0.0f, 0.0f, 1.0f
167 );
168 scene_edit->set_transform_matrix(transform_mat);
169
170 // Set the current camera to the scene.
171 check_success(camera_tag.is_valid());
172 scene_edit->set_camera(camera_tag);
173 }
174 dice_transaction->commit();
175 }
176
177 // Rendering
178 {
179 const std::string fname = get_output_file_name(m_outfname, 0);
180 mi::base::Handle<nv::index::IFrame_results> frame_results(render_frame(fname));
181 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
182 if (err_set->any_errors())
183 {
184 std::ostringstream os;
185 const mi::Uint32 nb_err = err_set->get_nb_errors();
186 for (mi::Uint32 e = 0; e < nb_err; ++e)
187 {
188 if (e != 0) os << '\n';
189 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
190 os << err->get_error_string();
191 }
192
193 ERROR_LOG << "IIndex_rendering rendering call failed with the following error(s): " << '\n'
194 << os.str();
195 }
196
197 // verify the generated frame
198 if (!(verify_canvas_result(get_application_layer_interface(),
199 m_image_file_canvas.get(), m_verify_image_fname, get_options())))
200 {
201 exit_code = 1;
202 }
203 }
204
205 // Render a few more frames
206 for (mi::Uint32 i = 1; i < 20; ++i)
207 {
208 // Move some scene elements
209 {
210 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(create_transaction());
211 check_success(dice_transaction.is_valid_interface());
212 {
213 move_scene(group_node, i, dice_transaction.get());
214 }
215 dice_transaction->commit();
216 }
217
218 const std::string fname = get_output_file_name(m_outfname, i);
219 mi::base::Handle<nv::index::IFrame_results> frame_results(render_frame(fname));
220 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
221 if (err_set->any_errors())
222 {
223 std::ostringstream os;
224 const mi::Uint32 nb_err = err_set->get_nb_errors();
225 for (mi::Uint32 e = 0; e < nb_err; ++e)
226 {
227 if (e != 0) os << '\n';
228 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
229 os << err->get_error_string();
230 }
231
232 ERROR_LOG << "IIndex_rendering rendering call failed with the following error(s): " << '\n'
233 << os.str();
234 }
235
236 // verify the generated frame
237 const std::string verify_image_fname = get_output_file_name(m_verify_image_fname_sequence, i);
238 if (!(verify_canvas_result(get_application_layer_interface(),
239 m_image_file_canvas.get(), verify_image_fname, get_options())))
240 {
241 exit_code = 1;
242 }
243 }
244
245 return exit_code;
246}
247
248//----------------------------------------------------------------------
249bool Create_icons::evaluate_options(nv::index::app::String_dict& sdict)
250{
251 const std::string com_name = sdict.get("command:", "<unknown_command>");
252 m_is_unittest = nv::index::app::get_bool(sdict.get("unittest", "false"));
253
254 if (m_is_unittest)
255 {
256 if (nv::index::app::get_bool(sdict.get("is_call_from_test", "false")))
257 {
258 sdict.insert("is_dump_comparison_image_when_failed", "0");
259 }
260 sdict.insert("outfname", ""); // turn off file output in the unit test mode
261 sdict.insert("dice::verbose", "2");
262 sdict.insert("verify_image_fname_sequence", ""); // disable this in unit test
263 }
264
265 // Set own options
266 m_outfname = sdict.get("outfname", "");
267 m_iconfile = sdict.get("iconfile", "");
268 m_verify_image_fname_sequence = sdict.get("verify_image_fname_sequence", "");
269 if (m_is_unittest)
270 {
271 m_verify_image_fname = sdict.get("verify_image_fname", "");
272 }
273 else
274 {
275 if (!sdict.get("verify_image_fname_sequence", "").empty())
276 {
277 m_verify_image_fname = m_verify_image_fname_sequence + "000.ppm";
278 }
279 }
280
281 info_cout(std::string("running ") + com_name, sdict);
282 info_cout("outfname = [" + m_outfname +
283 "], iconfile = [" + m_iconfile +
284 "], verify_image_fname_sequence = [" + m_verify_image_fname_sequence +
285 "], verify_image_fname = [" + m_verify_image_fname +
286 "], dice::verbose = " + sdict.get("dice::verbose"), sdict);
287
288 // print help and exit if -h
289 if (sdict.is_defined("h"))
290 {
291 std::cout
292 << "info: Usage: " << com_name << " [option]\n"
293 << "Option: [-h]\n"
294 << " printout this message\n"
295 << " [-dice::verbose severity_level]\n"
296 << " verbose severity level (3 is info.). (default: " + sdict.get("dice::verbose")
297 << ")\n"
298 << " [-outfname string]\n"
299 << " output ppm file base name. When empty, no output.\n"
300 << " A frame number and extension (.ppm) will be added.\n"
301 << " (default: [" << m_outfname << "])\n"
302
303 << " [-iconfile ICON_FPATH]\n"
304 << " Specify an icon file. (default: ["
305 << m_iconfile << "])\n"
306
307 << " [-verify_image_fname_sequence [image_fname_base]]\n"
308 << " when image_fname_base exist, verify the rendering image sequence. (default: ["
309 << m_verify_image_fname_sequence << "])\n"
310 << " This is for non-unit test mode.\n"
311
312 << " [-verify_image_fname [image_fname]]\n"
313 << " when image_fname exist, verify the rendering image. (default: ["
314 << m_verify_image_fname << "])\n"
315 << " This is for unit test mode.\n"
316
317 << " [-unittest bool]\n"
318 << " when true, unit test mod. "
319 << "(default: " << m_is_unittest << ")"
320 << std::endl;
321 exit(1);
322 }
323
324 return true;
325}
326
327//----------------------------------------------------------------------
328mi::neuraylib::Tag Create_icons::create_scene(
329 nv::index::IScene* scene_edit,
330 mi::neuraylib::IDice_transaction* dice_transaction)
331{
332 check_success(scene_edit != 0);
333 check_success(dice_transaction != 0);
334
335 // Create the main scene group which will contain all shapes
336 mi::base::Handle<nv::index::ITransformed_scene_group> group_node(
337 scene_edit->create_scene_group<nv::index::ITransformed_scene_group>());
338 check_success(group_node.is_valid_interface());
339
340 // Set up the transformation matrix
341 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(1.f);
342 // Add a translation
343 transform_mat.translate(mi::math::Vector<mi::Float32, 3>(5.0f, 0.0f, 0.0f));
344 group_node->set_transform(transform_mat);
345
346 // Create a texture attribute
347 mi::math::Vector<mi::Sint32, 2> tex_resolution(0, 0);
348 {
349 mi::base::Handle<nv::index::ITexture> texture(scene_edit->create_attribute<nv::index::ITexture>());
350 check_success(texture.is_valid_interface());
351 check_success(!m_iconfile.empty());
352
353 // Load the texture from a file
354 mi::base::Handle<nv::index::app::image::IImage_importer> image_importer(
355 get_application_layer_interface()->get_api_component<nv::index::app::image::IImage_importer>());
356 check_success(image_importer.is_valid_interface());
357 mi::base::Handle<mi::neuraylib::ICanvas> canvas(
358 image_importer->create_canvas_from_file(m_iconfile.c_str()));
359 check_success(canvas.is_valid_interface());
360 tex_resolution.x = static_cast<mi::Sint32>(canvas->get_resolution_x());
361 tex_resolution.y = static_cast<mi::Sint32>(canvas->get_resolution_y());
362
363 // Copy the pixel data
364 check_success(texture->set_pixel_data(
365 canvas.get(),
366 nv::index::ITexture::RGBA_FLOAT32));
367
368 mi::neuraylib::Tag texture_tag = dice_transaction->store_for_reference_counting(texture.get());
369 check_success(texture_tag.is_valid());
370 group_node->append(texture_tag, dice_transaction);
371 }
372
373 // Icon
374 {
375 mi::base::Handle<nv::index::IIcon_2D> icon(scene_edit->create_shape<nv::index::IIcon_2D>());
376 check_success(icon.is_valid_interface());
377
378 const mi::math::Vector<mi::Float32, 3> position(0.f, 0.f, 0.f);
379 const mi::math::Vector<mi::Float32, 2> right(1.f, 0.f);
380 const mi::math::Vector<mi::Float32, 2> up(0.f, 1.f);
381 const mi::Float32 width = 50.0f;
382 const mi::Float32 height = width * (static_cast<mi::Float32>(tex_resolution.x) / static_cast<mi::Float32>(tex_resolution.y));
383 icon->set_geometry(position, right, up, width, height);
384
385 mi::neuraylib::Tag icon_tag = dice_transaction->store_for_reference_counting(icon.get());
386 check_success(icon_tag.is_valid());
387 group_node->append(icon_tag, dice_transaction);
388 }
389
390 {
391 mi::base::Handle<nv::index::IIcon_3D> icon(scene_edit->create_shape<nv::index::IIcon_3D>());
392 check_success(icon.is_valid_interface());
393
394 const mi::math::Vector<mi::Float32, 3> position(50.f, 50.f, 50.f);
395 const mi::math::Vector<mi::Float32, 3> right(2.f, 0.f, 1.0f);
396 const mi::math::Vector<mi::Float32, 3> up(0.f, 2.f, 0.f);
397 const mi::Float32 width = 100.0f;
398 const mi::Float32 height = width * (static_cast<mi::Float32>(tex_resolution.x) / static_cast<mi::Float32>(tex_resolution.y));
399 icon->set_geometry(position, right, up, width, height);
400
401 mi::neuraylib::Tag icon_tag = dice_transaction->store_for_reference_counting(icon.get());
402 check_success(icon_tag.is_valid());
403 group_node->append(icon_tag, dice_transaction);
404 }
405
406 // Append the scene group to the scene
407 mi::neuraylib::Tag group_node_tag = dice_transaction->store_for_reference_counting(group_node.get());
408 check_success(group_node_tag.is_valid());
409 scene_edit->append(group_node_tag, dice_transaction);
410
411 INFO_LOG << "Hierachical scene description creation complete.";
412 return group_node_tag;
413}
414
415//----------------------------------------------------------------------
416void Create_icons::move_scene(
417 mi::neuraylib::Tag group_node_tag,
418 mi::Uint32 frame_id,
419 mi::neuraylib::IDice_transaction* dice_transaction)
420{
421 mi::base::Handle<nv::index::ITransformed_scene_group> group_node(
422 dice_transaction->edit<nv::index::ITransformed_scene_group>(group_node_tag));
423 check_success(group_node.is_valid_interface());
424
425 // Set up the transformation matrix
426 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(1.f);
427 // Add a translation
428 transform_mat.translate(mi::math::Vector<mi::Float32, 3>(5.f, 0.f, frame_id * 10.f));
429 group_node->set_transform(transform_mat);
430}
431
432//----------------------------------------------------------------------
433void Create_icons::setup_camera(
434 nv::index::IPerspective_camera* cam)
435{
436 check_success(cam != 0);
437
438 // Set the camera parameters to see the whole scene.
439 const mi::math::Vector<mi::Float32, 3> from(100.0f, 254.0f, 550.0f);
440 const mi::math::Vector<mi::Float32, 3> to (255.0f, 255.0f, -255.0f);
441 const mi::math::Vector<mi::Float32, 3> up ( 0.0f, 1.0f, 0.0f);
442 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
443 viewdir.normalize();
444
445 cam->set(from, viewdir, up);
446 cam->set_aperture(0.033f);
447 cam->set_aspect(1.0f);
448 cam->set_focal(0.03f);
449 cam->set_clip_min(10.0f);
450 cam->set_clip_max(5000.0f);
451}
452
453//----------------------------------------------------------------------
454nv::index::IFrame_results* Create_icons::render_frame(
455 const std::string& output_fname)
456{
457 check_success(m_index_rendering.is_valid_interface());
458
459 // set output filename, empty string is valid
460 m_image_file_canvas->set_rgba_file_name(output_fname.c_str());
461
462 check_success(m_session_tag.is_valid());
463
464 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(create_transaction());
465 check_success(dice_transaction.is_valid_interface());
466
467 m_index_session->update(m_session_tag, dice_transaction.get());
468
469 mi::base::Handle<nv::index::IFrame_results> frame_results(
470 m_index_rendering->render(
471 m_session_tag,
472 m_image_file_canvas.get(),
473 dice_transaction.get()));
474 check_success(frame_results.is_valid_interface());
475
476 dice_transaction->commit();
477
478 frame_results->retain();
479 return frame_results.get();
480}
481
482//----------------------------------------------------------------------
483int main(int argc, const char* argv[])
484{
485 nv::index::app::String_dict sdict;
486
487 // Application (Create_icon) settings
488 sdict.insert("dice::verbose", "3"); // log level
489 sdict.insert("outfname", "frame_create_icons"); // output file base name
490 sdict.insert("iconfile", "../create_icons/nvidia_logo.ppm"); // icon file
491 sdict.insert("verify_image_fname_sequence", ""); // for non-unit test
492 sdict.insert("verify_image_fname", ""); // for unit test
493 sdict.insert("unittest", "0"); // default mode
494 sdict.insert("is_dump_comparison_image_when_failed", "1"); // default: dump images when failed.
495 sdict.insert("is_call_from_test", "0"); // default: not call from make check.
496
497 // DiCE settings
498 sdict.insert("dice::network::mode", "OFF");
499
500 // IndeX settings
501 sdict.insert("index::config::set_monitor_performance_values", "true");
502 sdict.insert("index::service", "rendering_and_compositing");
503 sdict.insert("index::cuda_debug_checks", "false");
504
505 // Application_layer settings
506 sdict.insert("index::app::components::application_layer::component_name_list",
507 "canvas_infrastructure image io");
508
509 // Initialize application
510 Create_icons create_icon;
511 create_icon.initialize(argc, argv, sdict);
512 check_success(create_icon.is_initialized());
513
514 // launch the application. creating the scene and rendering.
515 const mi::Sint32 exit_code = create_icon.launch();
516 INFO_LOG << "Shutting down ...";
517
518 return exit_code;
519}
virtual bool initialize_networking(mi::neuraylib::INetwork_configuration *network_configuration, nv::index::app::String_dict &options) CPP11_OVERRIDE
mi::Sint32 launch()
virtual bool evaluate_options(nv::index::app::String_dict &options) CPP11_OVERRIDE
virtual ~Create_icons()
int main(int argc, const char *argv[])
#define check_success(expr)