NVIDIA Index example code nvidia_logo_transpbg.gif Up
create_line_set.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/iindex.h>
14#include <nv/index/iline_set.h>
15#include <nv/index/iscene.h>
16#include <nv/index/isession.h>
17
18#include <nv/index/app/index_connect.h>
19#include <nv/index/app/string_dict.h>
20
21#include "utility/canvas_utility.h"
22#include "utility/app_rendering_context.h"
23
24#include <iostream>
25#include <sstream>
26
27//----------------------------------------------------------------------
29 public nv::index::app::Index_connect
30{
31public:
33 :
34 Index_connect()
35 {
36 // INFO_LOG << "DEBUG: Create_line_set() ctor";
37 }
38
40 {
41 // Note: Index_connect::~Index_connect() will be called after here.
42 // INFO_LOG << "DEBUG: ~Create_line_set() dtor";
43 }
44
45 // launch application
46 mi::Sint32 launch();
47
48protected:
49 virtual bool evaluate_options(nv::index::app::String_dict& sdict) CPP11_OVERRIDE;
50 // override
52 mi::neuraylib::INetwork_configuration* network_configuration,
53 nv::index::app::String_dict& options) CPP11_OVERRIDE
54 {
55 check_success(network_configuration != 0);
56
57 check_success(options.is_defined("unittest"));
58 const bool is_unittest = nv::index::app::get_bool(options.get("unittest"));
59 if (is_unittest)
60 {
61 info_cout("NETWORK: disabled networking mode.", options);
62 network_configuration->set_mode(mi::neuraylib::INetwork_configuration::MODE_OFF);
63 return true;
64 }
65
66 return initialize_networking_as_default_udp(network_configuration, options);
67 }
68
69private:
70 // get a color value from an integer
71 // \param[in] attrib attribute value
72 // \return a color associated with an attribute
73 mi::math::Color_struct get_color_from_attribute(mi::Sint32 attrib) const;
74
75 // get a width value from an integer
76 // \param[in] attrib attribute value
77 // \return a width value associated with an attribute
78 mi::Float32 get_width_from_attribute(mi::Float32 attrib) const;
79
80 // create line set in the scene.
81 //
82 // \param[in] scene_edit IScene for the scene edit.
83 // \param[in] dice_transaction dice transaction
84 // \return true when success
85 bool create_line_set(
86 nv::index::IScene* scene_edit,
87 mi::neuraylib::IDice_transaction* dice_transaction) const;
88
89 // setup camera to see this example scene
90 //
91 // \param[in] cam a camera
92 void setup_camera(nv::index::IPerspective_camera* cam) const;
93
94 nv::index::IFrame_results* render_frame(const std::string& output_fname) const;
95
96
97 // This session tag
98 mi::neuraylib::Tag m_session_tag;
99 // NVIDIA IndeX cluster configuration
100 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
101 // Application layer image file canvas (a render target)
102 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
103 // Create_icons options
104 std::string m_outfname;
105 bool m_is_unittest;
106 std::string m_verify_image_fname;
107};
108
109//----------------------------------------------------------------------
111{
112 mi::Sint32 exit_code = 0;
113
114 // Get DiCE database components
115 {
116 m_cluster_configuration =
117 get_index_interface()->get_api_component<nv::index::ICluster_configuration>();
118 check_success(m_cluster_configuration.is_valid_interface());
119
120 // create image canvas in application_layer
121 m_image_file_canvas = create_image_file_canvas(get_application_layer_interface());
122 check_success(m_image_file_canvas.is_valid_interface());
123
124 // Verifying that local host has joined
125 // This may fail when there is a license problem.
126 check_success(is_local_host_joined(m_cluster_configuration.get()));
127 {
128 // DiCE database access
129 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
130 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
131 check_success(dice_transaction.is_valid_interface());
132 {
133 // Setup session information
134 m_session_tag =
135 m_index_session->create_session(dice_transaction.get());
136 check_success(m_session_tag.is_valid());
137 mi::base::Handle< nv::index::ISession const > session(
138 dice_transaction->access< nv::index::ISession const >(
139 m_session_tag));
140 check_success(session.is_valid_interface());
141
142 mi::base::Handle< nv::index::IScene > scene_edit(
143 dice_transaction->edit<nv::index::IScene>(session->get_scene()));
144 check_success(scene_edit.is_valid_interface());
145
146 //----------------------------------------------------------------------
147 // Scene setup: add line set shape, scene parameters, camera.
148 //----------------------------------------------------------------------
149 // Add line set shape to the scene
150 check_success(create_line_set(scene_edit.get(), dice_transaction.get()));
151
152 // Create and edit a camera. Data distribution is based on
153 // the camera. (Because only visible massive data are
154 // considered)
155 mi::base::Handle< nv::index::IPerspective_camera > cam(
156 scene_edit->create_camera<nv::index::IPerspective_camera>());
157 check_success(cam.is_valid_interface());
158 setup_camera(cam.get());
159 const mi::neuraylib::Tag camera_tag = dice_transaction->store(cam.get());
160 check_success(camera_tag.is_valid());
161
162 const mi::math::Vector<mi::Uint32, 2> buffer_resolution(512, 512);
163 m_image_file_canvas->set_resolution(buffer_resolution);
164
165 // Set up the scene
166 mi::math::Bbox_struct< mi::Float32, 3 > const xyz_roi_st = {
167 { 0.0f, 0.0f, 0.0f, },
168 { 500.0f, 500.0f, 500.0f, },
169 };
170
171 // set the region of interest
172 const mi::math::Bbox< mi::Float32, 3 > xyz_roi(xyz_roi_st);
173 check_success(xyz_roi.is_volume());
174 scene_edit->set_clipped_bounding_box(xyz_roi_st);
175
176 // Set the scene global transformation matrix.
177 // only change the coordinate system
178 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(
179 1.0f, 0.0f, 0.0f, 0.0f,
180 0.0f, 1.0f, 0.0f, 0.0f,
181 0.0f, 0.0f, -1.0f, 0.0f,
182 0.0f, 0.0f, 0.0f, 1.0f
183 );
184 scene_edit->set_transform_matrix(transform_mat);
185
186 // Set the current camera to the scene.
187 check_success(camera_tag.is_valid());
188 scene_edit->set_camera(camera_tag);
189 }
190 dice_transaction->commit();
191 }
192
193 // Rendering
194 {
195 const mi::Sint32 frame_idx = 0;
196 const std::string fname = get_output_file_name(m_outfname, frame_idx);
197 mi::base::Handle<nv::index::IFrame_results> frame_results(render_frame(fname));
198 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
199 if (err_set->any_errors())
200 {
201 std::ostringstream os;
202 const mi::Uint32 nb_err = err_set->get_nb_errors();
203 for (mi::Uint32 e = 0; e < nb_err; ++e)
204 {
205 if (e != 0) os << '\n';
206 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
207 os << err->get_error_string();
208 }
209
210 ERROR_LOG << "IIndex_rendering rendering call failed with the following error(s): " << '\n'
211 << os.str();
212 exit_code = 1;
213 }
214
215
216 // verify the generated frame
217 if (!(verify_canvas_result(get_application_layer_interface(),
218 m_image_file_canvas.get(), m_verify_image_fname, get_options())))
219 {
220 exit_code = 1;
221 }
222 }
223 }
224 // index_connect shutdown
225 return exit_code;
226}
227
228//----------------------------------------------------------------------
229bool Create_line_set::evaluate_options(nv::index::app::String_dict& sdict)
230{
231 const std::string com_name = sdict.get("command:", "<unknown_command>");
232 m_is_unittest = nv::index::app::get_bool(sdict.get("unittest", "false"));
233
234 if (m_is_unittest)
235 {
236 if (nv::index::app::get_bool(sdict.get("is_call_from_test", "false")))
237 {
238 sdict.insert("is_dump_comparison_image_when_failed", "0");
239 }
240 sdict.insert("outfname", ""); // turn off file output in the unit test mode
241 sdict.insert("dice::verbose", "2");
242 }
243
244 m_outfname = sdict.get("outfname", "");
245 m_verify_image_fname = sdict.get("verify_image_fname", "");
246
247 info_cout(std::string("running ") + com_name, sdict);
248 info_cout("outfname = [" + m_outfname +
249 "], verify_image_fname = [" + m_verify_image_fname +
250 "], dice::verbose = " + sdict.get("dice::verbose"), sdict);
251
252 // print help and exit if -h
253 if(sdict.is_defined("h"))
254 {
255 std::cout
256 << "info: Usage: " << com_name << " [option]\n"
257 << "Option: [-h]\n"
258 << " printout this message\n"
259 << " [-dice::verbose severity_level]\n"
260 << " verbose severity level (3 is info.). (default: " + sdict.get("dice::verbose")
261 << ")\n"
262 << " [-outfname string]\n"
263 << " output ppm file base name. When empty, no output.\n"
264 << " A frame number and extension (.ppm) will be added.\n"
265 << " (default: [" << m_outfname << "])\n"
266 << " [-verify_image_fname [image_fname]]\n"
267 << " when image_fname exist, verify the rendering image. (default: ["
268 << m_verify_image_fname << "])\n"
269 << " [-unittest bool]\n"
270 << " when true, unit test mode (create smaller volume). "
271 << "(default: " << m_is_unittest << ")"
272 << std::endl;
273 exit(1);
274 }
275 return true;
276}
277
278//----------------------------------------------------------------------
279mi::math::Color_struct Create_line_set::get_color_from_attribute(mi::Sint32 attrib) const
280{
281 mi::math::Color_struct col;
282 const mi::Float32 coef = 1.0f / 15.0f;
283 col.r = coef * static_cast< mi::Float32 >(attrib & 15);
284 col.g = coef * static_cast< mi::Float32 >((attrib >> 4) & 15);
285 col.b = coef * static_cast< mi::Float32 >((attrib >> 8) & 15);
286 col.a = 1.0;
287
288 return col;
289}
290
291//----------------------------------------------------------------------
292mi::Float32 Create_line_set::get_width_from_attribute(mi::Float32 attrib) const
293{
294 const mi::Float32 width =
295 static_cast< mi::Float32 >(static_cast< mi::Sint32 >(fabs(attrib)) % 16);
296 return width;
297}
298
299//----------------------------------------------------------------------
300bool Create_line_set::create_line_set(
301 nv::index::IScene* scene_edit,
302 mi::neuraylib::IDice_transaction* dice_transaction) const
303{
304 check_success(scene_edit != 0);
305 check_success(dice_transaction != 0);
306
307 // hierarchical scene description node for the point set
308 mi::base::Handle<nv::index::ITransformed_scene_group> group_node(
309 scene_edit->create_scene_group<nv::index::ITransformed_scene_group>());
310 check_success(group_node.is_valid_interface());
311
312 // Line coordinates and its attributes. According to the
313 // attributes, color and width are defined.
314 // Here, we create two line sets.
315 std::vector< mi::math::Vector_struct< mi::Float32, 3> > line_seg_vec[2];
316 std::vector< mi::math::Color_struct > color_vec[2];
317 std::vector< mi::Float32 > width_vec[2];
318
319 // Square shaped positions
320 const mi::Sint32 column_count = 20;
321 const mi::Sint32 line_segment_count = 200;
322 const mi::Sint32 line_set_count = 2;
323 const mi::Float32 x_org = 0.0;
324 const mi::Float32 y_org = 0.0;
325 const mi::Float32 x_mag = 25.0;
326 const mi::Float32 y_mag = 25.0;
327 const mi::Float32 z = 30.0;
328 const mi::Float32 y_offset[2] = { 0.0f, 280.0f };
329 mi::Sint32 idx_p = 0; // point index
330
331 for(mi::Sint32 i = 0; i < line_segment_count; ++i)
332 {
333 // one segment has two points
334 for(mi::Sint32 k = 0; k < 2; ++k){
335 mi::math::Vector_struct< mi::Float32, 3> pos[2];
336 for(mi::Sint32 j = 0; j < line_set_count; ++j){
337 pos[j].x = x_org + static_cast< mi::Float32 >(idx_p % column_count) * x_mag;
338 pos[j].y = y_org + static_cast< mi::Float32 >(idx_p / column_count) * y_mag + y_offset[j];
339 pos[j].z = z;
340 line_seg_vec[j].push_back(pos[j]);
341 }
342 ++idx_p;
343 }
344 for(mi::Sint32 j = 0; j < line_set_count; ++j){
345 color_vec[j].push_back(get_color_from_attribute(i));
346 width_vec[j].push_back(get_width_from_attribute(static_cast<mi::Float32>(i)));
347 }
348 }
349
350 // Create two line sets
351 for(mi::Sint32 j = 0; j < 2; ++j)
352 {
353 // Create attribute_line_set scene element and add it to the scene
354 mi::base::Handle<nv::index::ILine_set> line_set(scene_edit->create_shape<nv::index::ILine_set>());
355 check_success(line_set.is_valid_interface());
356 line_set->set_line_type(nv::index::ILine_set::LINE_TYPE_SEGMENTS);
357
358 check_success((line_seg_vec[j].size()) > 0);
359 line_set->set_lines(&(line_seg_vec[j][0]), line_seg_vec[j].size() / 2); // may cut the last point
360 line_set->set_colors(&(color_vec[j][0]), color_vec[j].size());
361 line_set->set_widths(&(width_vec[j][0]), width_vec[j].size());
362
363 // Add the line segments to the database
364 const mi::neuraylib::Tag line_set_tag = dice_transaction->store_for_reference_counting(line_set.get());
365 // if you are not registered Attribute_line_set, the next check fails.
366 check_success(line_set_tag.is_valid());
367 // Add to the scene description
368 group_node->append(line_set_tag, dice_transaction);
369 INFO_LOG << "Added line_set (size: " << line_set_count << ") to the scene (tag id: "
370 << line_set_tag.id << ").";
371 }
372
373 mi::neuraylib::Tag group_node_tag = dice_transaction->store_for_reference_counting(group_node.get());
374 check_success(group_node_tag.is_valid());
375 scene_edit->append(group_node_tag, dice_transaction);
376
377 return true;
378}
379
380//----------------------------------------------------------------------
381void Create_line_set::setup_camera(nv::index::IPerspective_camera* cam) const
382{
383 check_success(cam != 0);
384
385 // Set the camera parameters to see the whole scene.
386 mi::math::Vector< mi::Float32, 3 > const from( 254.0f, 254.0f, 550.0f);
387 mi::math::Vector< mi::Float32, 3 > const to ( 255.0f, 255.0f, -255.0f);
388 mi::math::Vector< mi::Float32, 3 > const up ( 0.0f, 1.0f, 0.0f);
389 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
390 viewdir.normalize();
391
392 cam->set(from, viewdir, up);
393 cam->set_aperture(0.033f);
394 cam->set_aspect(1.0f);
395 cam->set_focal(0.03f);
396 cam->set_clip_min(10.0f);
397 cam->set_clip_max(5000.0f);
398}
399
400//----------------------------------------------------------------------
401nv::index::IFrame_results* Create_line_set::render_frame(
402 const std::string& output_fname) const
403{
404 check_success(m_index_rendering.is_valid_interface());
405
406 // set output filename, empty string is valid
407 m_image_file_canvas->set_rgba_file_name(output_fname.c_str());
408
409 check_success(m_session_tag.is_valid());
410
411 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
412 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
413 check_success(dice_transaction.is_valid_interface());
414
415 m_index_session->update(m_session_tag, dice_transaction.get());
416
417 mi::base::Handle<nv::index::IFrame_results> frame_results(
418 m_index_rendering->render(
419 m_session_tag,
420 m_image_file_canvas.get(),
421 dice_transaction.get()));
422 check_success(frame_results.is_valid_interface());
423
424 dice_transaction->commit();
425
426 frame_results->retain();
427 return frame_results.get();
428}
429
430//----------------------------------------------------------------------
431// This example shows how to create line set shape in the scene.
432int main(int argc, const char* argv[])
433{
434 nv::index::app::String_dict sdict;
435 sdict.insert("dice::verbose", "3"); // log level
436 sdict.insert("outfname", "frame_create_line_set"); // output file base name
437 sdict.insert("verify_image_fname", ""); // for unit test
438 sdict.insert("unittest", "0"); // default mode
439 sdict.insert("is_dump_comparison_image_when_failed", "1"); // default: dump images when failed.
440 sdict.insert("is_call_from_test", "0"); // default: not call from make check.
441
442 // Load IndeX library via Index_connect
443 sdict.insert("dice::network::mode", "OFF");
444
445 // index setting
446 sdict.insert("index::config::set_monitor_performance_values", "true");
447 sdict.insert("index::service", "rendering_and_compositing");
448 sdict.insert("index::cuda_debug_checks", "false");
449
450 // application_layer component loading
451 sdict.insert("index::app::components::application_layer::component_name_list",
452 "canvas_infrastructure image io");
453
454 // Initialize application
455 Create_line_set create_line_set;
456 create_line_set.initialize(argc, argv, sdict);
457 check_success(create_line_set.is_initialized());
458
459 // launch the application. creating the scene and rendering.
460 const mi::Sint32 exit_code = create_line_set.launch();
461 INFO_LOG << "Shutting down ...";
462
463 return exit_code;
464}
virtual bool initialize_networking(mi::neuraylib::INetwork_configuration *network_configuration, nv::index::app::String_dict &options) CPP11_OVERRIDE
virtual bool evaluate_options(nv::index::app::String_dict &sdict) CPP11_OVERRIDE
mi::Sint32 launch()
virtual ~Create_line_set()
int main(int argc, const char *argv[])
#define check_success(expr)