NVIDIA Index example code nvidia_logo_transpbg.gif Up
create_line_styles.cpp
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright 2023 NVIDIA Corporation. All rights reserved.
3 *****************************************************************************/
6
7#include <mi/dice.h>
8
9// Include code shared by all examples.
10#include "utility/example_shared.h"
11
12#include <nv/index/icamera.h>
13#include <nv/index/icolormap.h>
14#include <nv/index/iconfig_settings.h>
15#include <nv/index/iindex.h>
16#include <nv/index/iline_set.h>
17#include <nv/index/iscene.h>
18#include <nv/index/iscene_group.h>
19#include <nv/index/isession.h>
20
21#include <nv/index/app/index_connect.h>
22#include <nv/index/app/string_dict.h>
23
24#include "utility/app_rendering_context.h"
25#include "utility/canvas_utility.h"
26
27#include <iostream>
28#include <sstream>
29
30//----------------------------------------------------------------------
32 public nv::index::app::Index_connect
33{
34public:
36 {
37 mi::Uint32 num_points;
38 mi::Uint32 line_style;
39 mi::Uint32 caps_style;
40 };
41
42
44 :
45 Index_connect()
46 {
47 // INFO_LOG << "DEBUG: Create_line_style() ctor";
48 }
49
51 {
52 // Note: Index_connect::~Index_connect() will be called after here.
53 // INFO_LOG << "DEBUG: ~Create_line_style() dtor";
54 }
55
56 // launch application
57 mi::Sint32 launch();
58
59protected:
60 virtual bool evaluate_options(nv::index::app::String_dict& sdict) CPP11_OVERRIDE;
61 // override
63 mi::neuraylib::INetwork_configuration* network_configuration,
64 nv::index::app::String_dict& options) CPP11_OVERRIDE
65 {
66 check_success(network_configuration != 0);
67
68 check_success(options.is_defined("unittest"));
69 const bool is_unittest = nv::index::app::get_bool(options.get("unittest"));
70 if (is_unittest)
71 {
72 info_cout("NETWORK: disabled networking mode.", options);
73 network_configuration->set_mode(mi::neuraylib::INetwork_configuration::MODE_OFF);
74 return true;
75 }
76
77 return initialize_networking_as_default_udp(network_configuration, options);
78 }
79
80private:
81 mi::Float32 random(mi::Float32 min, mi::Float32 max) const;
82 mi::math::Color_struct jetmap(mi::Float32 v, mi::Float32 vmin, mi::Float32 vmax) const;
83
84 // Create scene.
85 // \param[in] params line parameters
86 // \param[in] scene_edit IScene for the scene edit.
87 // \param[in] dice_transaction dice transaction
88 // \return true when success
89 bool create_scene(
90 const Line_test_params& params,
91 nv::index::IScene* scene_edit,
92 mi::neuraylib::IDice_transaction* dice_transaction);
93
94 // setup camera to see this example scene
95 // \param[in] cam a camera
96 void setup_camera(
97 nv::index::IPerspective_camera* cam) const;
98
99 // render a frame
100 // \param[in] output_fname output rendering image filename
101 // \return performance values
102 nv::index::IFrame_results* render_frame(
103 const std::string& output_fname) const;
104
105 // This session tag
106 mi::neuraylib::Tag m_session_tag;
107 // NVIDIA IndeX cluster configuration
108 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
109 // Application layer image file canvas (a render target)
110 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
111 // Create_line_style options
112 std::string m_outfname;
113 bool m_is_unittest;
114 std::string m_verify_image_fname;
115 Line_test_params m_line_params;
116};
117
118//----------------------------------------------------------------------
120{
121 mi::Sint32 exit_code = 0;
122
123 // Get DiCE database components
124 {
125 m_cluster_configuration =
126 get_index_interface()->get_api_component<nv::index::ICluster_configuration>();
127 check_success(m_cluster_configuration.is_valid_interface());
128
129 // create image canvas in application_layer
130 m_image_file_canvas = create_image_file_canvas(get_application_layer_interface());
131 check_success(m_image_file_canvas.is_valid_interface());
132
133 // Verifying that local host has joined
134 // This may fail when there is a license problem.
135 check_success(is_local_host_joined(m_cluster_configuration.get()));
136
137 {
138 // DiCE database access
139 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
140 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
141 check_success(dice_transaction.is_valid_interface());
142 {
143 // Setup session information
144 m_session_tag = m_index_session->create_session(dice_transaction.get());
145 check_success(m_session_tag.is_valid());
146 mi::base::Handle< nv::index::ISession const > session(
147 dice_transaction->access< nv::index::ISession const >(
148 m_session_tag));
149 check_success(session.is_valid_interface());
150
151 mi::base::Handle< nv::index::IScene > scene_edit(
152 dice_transaction->edit< nv::index::IScene >(session->get_scene()));
153 check_success(scene_edit.is_valid_interface());
154
155 //----------------------------------------------------------------------
156 // Scene setup: hierarchical scene description root node,
157 // scene parameters, camera.
158 //----------------------------------------------------------------------
159 // create a hierarchical scene description
160 check_success(create_scene(m_line_params, scene_edit.get(), dice_transaction.get()));
161
162 // Create and edit a camera. Data distribution is based on
163 // the camera. (Because only visible massive data are considered)
164 mi::base::Handle< nv::index::IPerspective_camera > cam(
165 scene_edit->create_camera<nv::index::IPerspective_camera>());
166 check_success(cam.is_valid_interface());
167 setup_camera(cam.get());
168 const mi::neuraylib::Tag camera_tag = dice_transaction->store(cam.get());
169 check_success(camera_tag.is_valid());
170
171 const mi::math::Vector<mi::Uint32, 2> buffer_resolution(1024, 1024);
172 m_image_file_canvas->set_resolution(buffer_resolution);
173
174 // Set up the scene
175 const mi::math::Bbox_struct< mi::Float32, 3 > xyz_roi_st = {
176 { 0.0f, 0.0f, 0.0f, },
177 { 650.0f, 650.0f, 650.0f, },
178 };
179
180 // set the region of interest
181 const mi::math::Bbox< mi::Float32, 3 > xyz_roi(xyz_roi_st);
182 check_success(xyz_roi.is_volume());
183 scene_edit->set_clipped_bounding_box(xyz_roi_st);
184
185 // Set the scene global transformation matrix.
186 // only change the coordinate system
187 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(
188 1.0f, 0.0f, 0.0f, 0.0f,
189 0.0f, 1.0f, 0.0f, 0.0f,
190 0.0f, 0.0f, -1.0f, 0.0f,
191 0.0f, 0.0f, 0.0f, 1.0f
192 );
193
194 scene_edit->set_transform_matrix(transform_mat);
195
196 INFO_LOG << "transformed: " << scene_edit->get_transform_matrix();
197
198 // Set the current camera to the scene.
199 check_success(camera_tag.is_valid());
200 scene_edit->set_camera(camera_tag);
201 }
202 dice_transaction->commit();
203 }
204
205 // Rendering
206 {
207 // Render a frame and save the rendered image to a file.
208 const mi::Sint32 frame_idx = 0;
209 const std::string fname = get_output_file_name(m_outfname, frame_idx);
210 mi::base::Handle<nv::index::IFrame_results> frame_results(render_frame(fname));
211 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
212 if (err_set->any_errors())
213 {
214 std::ostringstream os;
215 const mi::Uint32 nb_err = err_set->get_nb_errors();
216 for (mi::Uint32 e = 0; e < nb_err; ++e)
217 {
218 if (e != 0) os << '\n';
219 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
220 os << err->get_error_string();
221 }
222
223 ERROR_LOG << "IIndex_rendering rendering call failed with the following error(s): " << '\n'
224 << os.str();
225 exit_code = 1;
226 }
227
228 // verify the generated frame
229 if (!(verify_canvas_result(get_application_layer_interface(),
230 m_image_file_canvas.get(), m_verify_image_fname, get_options())))
231 {
232 exit_code = 1;
233 }
234 }
235 }
236
237 return exit_code;
238}
239
240//----------------------------------------------------------------------
241bool Create_line_style::evaluate_options(nv::index::app::String_dict& sdict)
242{
243 const std::string com_name = sdict.get("command:", "<unknown_command>");
244 m_is_unittest = nv::index::app::get_bool(sdict.get("unittest", "false"));
245
246 if (m_is_unittest)
247 {
248 if (nv::index::app::get_bool(sdict.get("is_call_from_test", "false")))
249 {
250 sdict.insert("is_dump_comparison_image_when_failed", "0");
251 }
252 sdict.insert("outfname", ""); // turn off file output in the unit test mode
253 sdict.insert("dice::verbose", "2");
254 }
255
256 m_outfname = sdict.get("outfname");
257 m_verify_image_fname = sdict.get("verify_image_fname");
258 m_line_params.num_points = nv::index::app::get_uint32(sdict.get("num_points"));
259 m_line_params.line_style = nv::index::app::get_uint32(sdict.get("line_style"));
260 m_line_params.caps_style = nv::index::app::get_uint32(sdict.get("caps_style"));
261
262 info_cout(std::string("running ") + com_name, sdict);
263 info_cout(std::string("outfname = [") + m_outfname +
264 "], verify_image_fname = [" + m_verify_image_fname +
265 "], dice::verbose = " + sdict.get("dice::verbose"), sdict);
266
267 // print help and exit if -h
268 if(sdict.is_defined("h"))
269 {
270 std::cout
271 << "info: Usage: " << com_name << " [option]\n"
272 << "Option: [-h]\n"
273 << " printout this message\n"
274 << " [-dice::verbose severity_level]\n"
275 << " verbose severity level (3 is info.). (default: " + sdict.get("dice::verbose")
276 << ")\n"
277
278 << " [-num_points int]\n"
279 << " number of points used for every shape in the test."
280 << "(default: " << m_line_params.num_points << ")\n"
281
282 << " [-line_style int]\n"
283 << " set the line dash pattern (0-9)."
284 << "(default: " << m_line_params.line_style << ")\n"
285
286 << " [-caps_style int]\n"
287 << " set the cap style (0-2)."
288 << "(default: " << m_line_params.caps_style << ")\n"
289
290 << " [-outfname string]\n"
291 << " output ppm file base name. When empty, no output.\n"
292 << " A frame number and extension (.ppm) will be added.\n"
293 << " (default: [" << m_outfname << "])\n"
294 << " [-verify_image_fname [image_fname]]\n"
295 << " when image_fname exist, verify the rendering image. (default: ["
296 << m_verify_image_fname << "])\n"
297
298 << " [-unittest bool]\n"
299 << " when true, unit test mode (create smaller volume). "
300 << "(default: " << m_is_unittest << ")"
301 << std::endl;
302 exit(1);
303 }
304 return true;
305}
306
307//----------------------------------------------------------------------
308mi::Float32 Create_line_style::random(mi::Float32 min, mi::Float32 max) const
309{
310 mi::Float32 t = rand()/(1.f + RAND_MAX);
311
312 return (min + (max - min)*t);
313}
314
315//----------------------------------------------------------------------
316mi::math::Color_struct Create_line_style::jetmap(mi::Float32 v, mi::Float32 vmin, mi::Float32 vmax) const
317{
318 mi::math::Color_struct c = {1.0f, 1.0f, 1.0f, 1.0f};
319 mi::Float32 dv;
320
321 if (v < vmin)
322 v = vmin;
323 if (v > vmax)
324 v = vmax;
325 dv = vmax - vmin;
326
327 if (v < (vmin + 0.25f * dv))
328 {
329 c.r = 0.f;
330 c.g = 4.f * (v - vmin) / dv;
331 }
332 else if (v < (vmin + 0.5f * dv))
333 {
334 c.r = 0.f;
335 c.b = 1.f + 4.f * (vmin + 0.25f * dv - v) / dv;
336 }
337 else if (v < (vmin + 0.75f * dv))
338 {
339 c.r = 4.f * (v - vmin - 0.5f * dv) / dv;
340 c.b = 0.f;
341 }
342 else
343 {
344 c.g = 1.f + 4.f * (vmin + 0.75f * dv - v) / dv;
345 c.b = 0.f;
346 }
347
348 return(c);
349}
350
351//----------------------------------------------------------------------
352bool Create_line_style::create_scene(
353 const Line_test_params& params,
354 nv::index::IScene* scene_edit,
355 mi::neuraylib::IDice_transaction* dice_transaction)
356{
357 check_success(scene_edit != 0);
358 check_success(dice_transaction != 0);
359
360 const mi::Float32 PI_f = static_cast<mi::Float32>(M_PI); // pi of Float32
361
362 // Set up the transformation matrix, define a translation and create and store the scene group
363 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(1.f);
364 transform_mat.translate(mi::math::Vector<mi::Float32, 3>(240.f, 300.f, 0.f));
365 mi::base::Handle<nv::index::ITransformed_scene_group> group_node(
366 scene_edit->create_scene_group<nv::index::ITransformed_scene_group>());
367 check_success(group_node.is_valid_interface());
368 group_node->set_transform(transform_mat);
369
370 // set up line style
371 nv::index::ILine_set::Line_style line_style = (nv::index::ILine_set::Line_style)params.line_style;
372
373 // set up cap style
374 nv::index::ILine_set::Cap_style cap_style = (nv::index::ILine_set::Cap_style)params.caps_style;
375
376 mi::Uint32 num_points = params.num_points;
377 mi::Float32 min_width = 1.5f, max_width = 10.f;
378
379 // set up color per vertice
380 std::vector<mi::math::Color_struct> colors;
381 colors.resize(num_points);
382 for(mi::Uint32 i=0; i<num_points; i++)
383 colors[i] = jetmap((mi::Float32)i/(mi::Float32)(num_points-1), 0.f, 1.f);
384
385 { //creating a line-set in segments mode
386 mi::math::Bbox< mi::Float32, 3 > bbox;
387 bbox.min.x = -200.f;
388 bbox.min.y = 330.f;
389 bbox.min.z = -150.f;
390 bbox.max.x = 210.f;
391 bbox.max.y = 150.f;
392 bbox.max.z = 150.f;
393
394 mi::Uint32 num_segments = num_points-1;
395 std::vector< mi::math::Vector_struct<mi::Float32, 3> > segment_points;
396 segment_points.resize(num_segments*2);
397 std::vector<mi::Float32> widths;
398 widths.resize(num_segments);
399
400 srand(39377);
401 for(mi::Uint32 i=0; i<num_segments; i++)
402 {
403 segment_points[2*i].x = random(bbox.min.x, bbox.max.x);
404 segment_points[2*i].y = random(bbox.min.y, bbox.max.y);
405 segment_points[2*i].z = random(bbox.min.z, bbox.max.z);
406
407 segment_points[2*i+1].x = random(bbox.min.x, bbox.max.x);
408 segment_points[2*i+1].y = random(bbox.min.y, bbox.max.y);
409 segment_points[2*i+1].z = random(bbox.min.z, bbox.max.z);
410
411 mi::Float32 t = random(0.f, 1.f);
412 widths[i] = min_width + (max_width - min_width)*t*t;
413 }
414
415 mi::base::Handle<nv::index::ILine_set> line_set1(scene_edit->create_shape<nv::index::ILine_set>());
416 check_success(line_set1.is_valid_interface());
417
418 // set line type
419 line_set1->set_line_type(nv::index::ILine_set::LINE_TYPE_SEGMENTS);
420
421 // set points
422 line_set1->set_lines(&segment_points[0], num_segments*2);
423
424 // set colors
425 line_set1->set_colors(&colors[0], num_segments);
426
427 // set widths
428 line_set1->set_widths(&widths[0], num_segments);
429
430 //set line style
431 line_set1->set_line_style(line_style);
432
433 //set cap style
434 line_set1->set_cap_style(cap_style);
435
436 // append path to the group node
437 const mi::neuraylib::Tag line_set1_tag = dice_transaction->store_for_reference_counting(line_set1.get());
438 check_success(line_set1_tag.is_valid());
439 group_node->append(line_set1_tag, dice_transaction);
440 }
441
442 { //creating a line-set in path mode
443
444 // set up points
445 std::vector< mi::math::Vector_struct<mi::Float32, 3> > points;
446 points.resize(num_points);
447
448 for(mi::Uint32 i=0; i<num_points; i++)
449 {
450 mi::Float32 t = (mi::Float32)i/(mi::Float32)(num_points-1);
451 t = 2.f*t - 1.f;
452
453 points[i].x = t*300.f - 50.f;
454 points[i].y = t*t*t*t*t*t*t*300.f + 20.f;
455 points[i].z = 10.f;
456 }
457
458 // set up widths
459 std::vector<mi::Float32> widths;
460 widths.resize(num_points);
461 for(mi::Uint32 i=0; i<num_points; i++)
462 {
463 mi::Float32 t = (mi::Float32)i/(mi::Float32)(num_points-1);
464 widths[i] = min_width + (1.5f*max_width - min_width)*0.5f*(sinf(4.f*static_cast<mi::Float32>(PI_f)*t) + 1.f);
465 }
466
467 mi::base::Handle<nv::index::ILine_set> line_set2(scene_edit->create_shape<nv::index::ILine_set>());
468 check_success(line_set2.is_valid_interface());
469
470 // set line type
471 line_set2->set_line_type(nv::index::ILine_set::LINE_TYPE_PATH);
472
473 // set points
474 line_set2->set_lines(&points[0], num_points);
475
476 // set colors
477 line_set2->set_colors(&colors[0], num_points);
478
479 // set widths
480 line_set2->set_widths(&widths[0], num_points);
481
482 //set line style
483 line_set2->set_line_style(line_style);
484
485 //set cap style
486 line_set2->set_cap_style(cap_style);
487
488 // append path to the group node
489 const mi::neuraylib::Tag line_set1_tag = dice_transaction->store_for_reference_counting(line_set2.get());
490 check_success(line_set1_tag.is_valid());
491 group_node->append(line_set1_tag, dice_transaction);
492 }
493
494 { //creating a line-set in loop mode
495
496 // set up points
497 std::vector< mi::math::Vector_struct<mi::Float32, 3> > points;
498 points.resize(num_points);
499
500 for(mi::Uint32 i=0; i<num_points; i++)
501 {
502 mi::Float32 t = (mi::Float32)i/(mi::Float32)num_points;
503
504 points[i].x = sinf(2.f * PI_f * t + PI_f/2.f)*250.f;
505 points[i].y = sinf(4.f * PI_f * t) * 150.f - 150;
506 points[i].z = sinf(2.f * PI_f * t) * 10.f;
507 }
508
509 // set up widths
510 std::vector<mi::Float32> widths;
511 widths.resize(num_points);
512 for(mi::Uint32 i=0; i<num_points; i++)
513 {
514 mi::Float32 t = (mi::Float32)i/(mi::Float32)(num_points-1);
515 widths[i] = min_width + (max_width - min_width)*0.5f*(sinf(2.f*PI_f*t + PI_f/2.f) + 1.f);
516 }
517
518 mi::base::Handle<nv::index::ILine_set> line_set3(scene_edit->create_shape<nv::index::ILine_set>());
519 check_success(line_set3.is_valid_interface());
520
521 // set line type
522 line_set3->set_line_type(nv::index::ILine_set::LINE_TYPE_LOOP);
523
524 // set points
525 line_set3->set_lines(&points[0], num_points);
526
527 // set colors
528 line_set3->set_colors(&colors[0], num_points);
529
530 // set widths
531 line_set3->set_widths(&widths[0], num_points);
532
533 //set line style
534 line_set3->set_line_style(line_style);
535
536 //set cap style
537 line_set3->set_cap_style(cap_style);
538
539 // append path to the group node
540 const mi::neuraylib::Tag line_set3_tag = dice_transaction->store_for_reference_counting(line_set3.get());
541 check_success(line_set3_tag.is_valid());
542 group_node->append(line_set3_tag, dice_transaction);
543 }
544
545 const mi::neuraylib::Tag group_node_tag = dice_transaction->store_for_reference_counting(group_node.get());
546 check_success(group_node_tag.is_valid());
547 scene_edit->append(group_node_tag, dice_transaction);
548
549 return true;
550}
551
552//----------------------------------------------------------------------
553void Create_line_style::setup_camera(
554 nv::index::IPerspective_camera* cam) const
555{
556 // Set the camera parameters to see the whole scene
557 mi::math::Vector< mi::Float32, 3 > const from( 234.0f, 604.0f, 500.0f);
558 mi::math::Vector< mi::Float32, 3 > const to ( 255.0f, 255.0f, -255.0f);
559 mi::math::Vector< mi::Float32, 3 > const up ( 0.0f, 1.0f, 0.0f);
560 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
561 viewdir.normalize();
562
563 cam->set(from, viewdir, up);
564 cam->set_aperture(0.033f);
565 cam->set_aspect(1.0f);
566 cam->set_focal(0.03f);
567 cam->set_clip_min(10.0f);
568 cam->set_clip_max(5000.0f);
569}
570
571//----------------------------------------------------------------------
572nv::index::IFrame_results* Create_line_style::render_frame(
573 const std::string& output_fname) const
574{
575 check_success(m_index_rendering.is_valid_interface());
576
577 // set output filename, empty string is valid
578 m_image_file_canvas->set_rgba_file_name(output_fname.c_str());
579
580 check_success(m_session_tag.is_valid());
581
582 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
583 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
584 check_success(dice_transaction.is_valid_interface());
585
586 m_index_session->update(m_session_tag, dice_transaction.get());
587
588 mi::base::Handle<nv::index::IFrame_results> frame_results(
589 m_index_rendering->render(
590 m_session_tag,
591 m_image_file_canvas.get(),
592 dice_transaction.get()));
593 check_success(frame_results.is_valid_interface());
594
595 dice_transaction->commit();
596
597 frame_results->retain();
598 return frame_results.get();
599}
600
601//----------------------------------------------------------------------
602// This example shows how to create paths.
603int main(int argc, const char* argv[])
604{
605 nv::index::app::String_dict sdict;
606 sdict.insert("dice::verbose", "3"); // log level
607 sdict.insert("outfname", "frame_create_line_styles"); // output file base name
608 sdict.insert("verify_image_fname", ""); // for unit test
609 sdict.insert("unittest", "0"); // default mode
610 sdict.insert("num_points", "12"); // 12 points (default)
611 sdict.insert("line_style", "0"); // solid line style (default)
612 sdict.insert("caps_style", "2"); // no cape (default)
613 sdict.insert("is_dump_comparison_image_when_failed", "1"); // default: dump images when failed.
614 sdict.insert("is_call_from_test", "0"); // default: not call from make check.
615
616 // Load IndeX library via Index_connect
617 sdict.insert("dice::network::mode", "OFF");
618
619 // index setting
620 sdict.insert("index::config::set_monitor_performance_values", "true");
621 sdict.insert("index::service", "rendering_and_compositing");
622 sdict.insert("index::cuda_debug_checks", "false");
623
624 // application_layer component loading
625 sdict.insert("index::app::components::application_layer::component_name_list",
626 "canvas_infrastructure image io");
627
628 // Initialize application
629 Create_line_style create_line_style;
630 create_line_style.initialize(argc, argv, sdict);
631 check_success(create_line_style.is_initialized());
632
633 // launch the application. creating the scene and rendering.
634 const mi::Sint32 exit_code = create_line_style.launch();
635 INFO_LOG << "Shutting down ...";
636
637 return exit_code;
638}
639
virtual bool evaluate_options(nv::index::app::String_dict &sdict) CPP11_OVERRIDE
virtual bool initialize_networking(mi::neuraylib::INetwork_configuration *network_configuration, nv::index::app::String_dict &options) CPP11_OVERRIDE
int main(int argc, const char *argv[])
#define check_success(expr)