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