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