NVIDIA Index example code nvidia_logo_transpbg.gif Up
dynamic_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 <iostream>
21#include <sstream>
22
23#include "utility/frame_command.h"
24
25#include <nv/index/app/index_connect.h>
26#include <nv/index/app/string_dict.h>
27#include <nv/index/app/time_functions.h>
28
29//----------------------------------------------------------------------
31 public nv::index::app::Index_connect
32{
33public:
35 :
36 Index_connect(),
37 m_is_unittest(false),
38 m_max_iter(0),
39 m_resolution_x(0),
40 m_resolution_y(0),
41 m_roi_x(0),
42 m_roi_y(0),
43 m_roi_z(0),
44 m_is_save_all_frame(false),
45 m_is_animation_on(false)
46 {
47 // INFO_LOG << "DEBUG: Dynamic_point_set() ctor";
48 }
49
51 {
52 // Note: Index_connect::~Index_connect() will be called after here.
53 // INFO_LOG << "DEBUG: ~Dynamic_point_set() 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 // attribute to color map example
82 // \param[in] attrib attribute value
83 // \return color defined by an attribute
84 mi::math::Color_struct get_color_st_from_attribute(mi::Sint32 attrib) const;
85 // attribute to radius map example
86 // \param[in] attrib attribute value
87 // \return a radius corresponding to the attribute value
88 mi::Float32 get_radius_from_attribute(mi::Sint32 attrib) const;
89 // create point set in the scene.
90 // \param[in] session_tag session tag
91 // \param[in] dice_transaction dice transaction
92 void create_point_set(
93 const mi::neuraylib::Tag& session_tag,
94 mi::neuraylib::IDice_transaction* dice_transaction);
95
96 // translate point set
97 //
98 // \param[in] point_set_tag point set tag to translate the position
99 // \param[in] trans_delta_vec translation delta vector
100 // \param[in] dice_transaction dice transaction
101 void translate_point_set(
102 const mi::neuraylib::Tag& point_set_tag,
103 const mi::math::Vector< mi::Float32, 3 >& trans_delta_vec,
104 mi::neuraylib::IDice_transaction* dice_transaction) const;
105 // delete scene element
106 // \param[in] scene_element_tag scene element tag to be deleted
107 // \param[in] transform_tag transform tag
108 // \param[in] dice_transaction dice transaction
109 void delete_scene_element(
110 const mi::neuraylib::Tag& scene_element_tag,
111 const mi::neuraylib::Tag& transform_tag,
112 mi::neuraylib::IDice_transaction* dice_transaction) const;
113
114 // All top view
115 //
116 // Note: this function assumes that the screen shape is height <=
117 // width resolution.
118 //
119 // \param[in] vbbox viewing bounding box
120 // \param[in] aspect aspect ratio of the screen
121 // \param[in] fovy_2 half of fov of y in radian
122 // \param[out] from camera from
123 // \param[out] to camera to
124 // \param[out] up camera up
125 // \param[out] clip_min cliping plane min distance
126 // \param[out] clip_max cliping plane max distance
127 void get_top_view_param(const mi::math::Bbox<mi::Float32, 3>& vbbox,
128 const mi::Float32 aspect,
129 const mi::Float32 fovy_2,
130 mi::math::Vector< mi::Float32, 3 >& from,
131 mi::math::Vector< mi::Float32, 3 >& to,
132 mi::math::Vector< mi::Float32, 3 >& up,
133 mi::Float32 & clip_min,
134 mi::Float32 & clip_max) const;
135
136 // get resolution from opt
137 mi::math::Vector<mi::Uint32, 2> get_resolution() const;
138
139 // setup camera to see this example scene
140 // \param[in] cam a camera
141 // \param[in] roi_max region of interest max (min is fixed to (0,0,0)
142 // \param[in] dice_transaction dice transaction
143 void setup_camera(
144 nv::index::IPerspective_camera* cam,
145 const mi::math::Vector<mi::Uint32, 3>& roi_max,
146 mi::neuraylib::IDice_transaction* dice_transaction) const;
147
148 // set up as the main host
149 // \return true when success
150 bool setup_main_host();
151
152 // animate point
153 // \param[in] session_tag session tag
154 // \param[in] frame_idx current frame index used for animate the point set
155 // \param[in] dice_transaction dice transaction
156 void animate_point(
157 const mi::neuraylib::Tag& session_tag,
158 mi::Sint32 frame_idx,
159 mi::neuraylib::IDice_transaction* dice_transaction);
160
161 // render a frame
162 // \param[in] output_fname output rendering image filename
163 // \return performance values
164 nv::index::IFrame_results* render_frame(const std::string& output_fname) const;
165
166 // update the scene and render a frame
167 // \param[in] frame_idx current frame index
168 // \return true when success
169 bool update_scene_and_render_frame(mi::Sint32 frame_idx);
170
171 // main host rendering loop
172 // \return true when success
173 bool mainhost_rendering_loop();
174
175 // set up dynamic scene: points
176 void setup_animation();
177
178 // This session tag
179 mi::neuraylib::Tag m_session_tag;
180 // NVIDIA IndeX cluster configuration
181 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
182 // Application layer image file canvas (a render target)
183 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
184 // Create_icons options
185 std::string m_outfname;
186 bool m_is_unittest;
187 // std::string m_verify_image_fname;
188 mi::Sint32 m_max_iter;
189 mi::Uint32 m_resolution_x;
190 mi::Uint32 m_resolution_y;
191 mi::Sint32 m_roi_x;
192 mi::Sint32 m_roi_y;
193 mi::Sint32 m_roi_z;
194 bool m_is_save_all_frame;
195 bool m_is_animation_on;
196 // group node tag which contains point_set
197 mi::neuraylib::Tag m_point_set_group_tag;
198 // point_set tag
199 mi::neuraylib::Tag m_point_set_tag;
200 // dynamic scene commands. Use as a stack
201 std::vector<Frame_command> m_frame_command_vec;
202};
203
204//----------------------------------------------------------------------
206{
207 // required on host side too
208 nv::index::app::util::time::sleep(0.1f); // wait for 0.1 second
209
210 // setup main host
211 check_success(setup_main_host());
212
213 // set up dynamic scene
214 setup_animation();
215
216 // call main host rendering loop
217 mainhost_rendering_loop();
218
219 return 0;
220}
221
222//----------------------------------------------------------------------
223bool Dynamic_point_set::evaluate_options(nv::index::app::String_dict& sdict)
224{
225 const std::string com_name = sdict.get("command:", "<unknown_command>");
226 m_is_unittest = nv::index::app::get_bool(sdict.get("unittest", "false"));
227
228 if (m_is_unittest)
229 {
230 if (nv::index::app::get_bool(sdict.get("is_call_from_test", "false")))
231 {
232 sdict.insert("is_dump_comparison_image_when_failed", "0");
233 }
234 sdict.insert("max_iter", "20");
235 sdict.insert("outfname", ""); // turn off file output in the unit test mode
236 sdict.insert("dice::verbose", "2");
237 }
238
239 m_outfname = sdict.get("outfname");
240 m_max_iter = nv::index::app::get_sint32(sdict.get("max_iter"));
241 m_resolution_x = nv::index::app::get_uint32(sdict.get("resolution_x"));
242 m_resolution_y = nv::index::app::get_uint32(sdict.get("resolution_y"));
243 m_roi_x = nv::index::app::get_sint32(sdict.get("roi_x"));
244 m_roi_y = nv::index::app::get_sint32(sdict.get("roi_y"));
245 m_roi_z = nv::index::app::get_sint32(sdict.get("roi_z"));
246 m_is_save_all_frame = nv::index::app::get_bool(sdict.get("is_save_all_frame"));
247 m_is_animation_on = nv::index::app::get_bool(sdict.get("is_animation_on"));
248
249 info_cout(std::string("running ") + com_name, sdict);
250 info_cout(std::string("outfname = [") + m_outfname +
251 "], dice::verbose = " + sdict.get("dice::verbose"), sdict);
252
253 // print help and exit if -h
254 if(sdict.is_defined("h"))
255 {
256 std::cout
257 << "info: Usage: " << com_name <<" [option]\n"
258 << "Option: [-h]\n"
259 << " printout this message\n"
260 << " [-dice::verbose severity_level]\n"
261 << " verbose severity level (3 is info.). (default: " + sdict.get("dice::verbose")
262 << ")\n"
263
264 << " [-dice::network::multicast_address address]\n"
265 << " set multicast address. (default: "
266 << sdict.get("dice::network::multicast_address") + ")\n"
267
268 << " [-max_iter number_of_iteration]\n"
269 << " set rendering loop iterations. default: " << m_max_iter
270 << " frames\n"
271
272 << " [-resolution_x int] [-resolution_y int]\n"
273 << " screen resolution x and y. (default " << m_resolution_x
274 << " " << m_resolution_y<< ")\n"
275
276 << " [-roi_x int] [-roi_y int] [-roi_z int]\n"
277 << " region of interest max position.\n"
278 << " (The min position is set to (0,0,0).)\n"
279 << " (default: " << m_roi_x << " " << m_roi_y << " " << m_roi_z << ")\n"
280
281 << " [-outfname string]\n"
282 << " output ppm file base name. When "", no output.\n"
283 << " The frame number and extension(.ppm) will be added.\n"
284 << " (default: " << m_outfname << ")\n"
285
286 << " [-is_save_all_frame bool]\n"
287 << " when 1, save only the last frame. (default: "
288 << m_is_save_all_frame << ")\n"
289
290 << " [-is_animation_on bool]\n"
291 << " when 1, points are animated in every frame. (default: "
292 << m_is_animation_on << ")\n"
293
294 << " [-unittest bool]\n"
295 << " when true, unit test mode (create smaller volume). "
296 << "(default: " << m_is_unittest << ")"
297 << std::endl;
298 exit(1);
299 }
300 return true;
301}
302
303//----------------------------------------------------------------------
304mi::math::Color_struct Dynamic_point_set::get_color_st_from_attribute(mi::Sint32 attrib) const
305{
306 const mi::Sint32 intval = abs(attrib);
307 mi::math::Color_struct col;
308 const mi::Float32 coef = 1.0f / 15.0f;
309 col.r = coef * static_cast< mi::Float32 >(intval & 15);
310 col.g = coef * static_cast< mi::Float32 >((intval >> 4) & 15);
311 col.b = coef * static_cast< mi::Float32 >((intval >> 8) & 15);
312 col.a = 1.0;
313
314 return col;
315}
316
317//----------------------------------------------------------------------
318mi::Float32 Dynamic_point_set::get_radius_from_attribute(mi::Sint32 attrib) const
319{
320 const mi::Float32 rad = static_cast< mi::Float32 >(abs(attrib) % 12);
321 return rad;
322}
323
324//----------------------------------------------------------------------
325void Dynamic_point_set::create_point_set(
326 const mi::neuraylib::Tag& session_tag,
327 mi::neuraylib::IDice_transaction* dice_transaction)
328{
329 check_success(session_tag.is_valid());
330 check_success(dice_transaction != 0);
331
332 mi::base::Handle<nv::index::ISession const> session(
333 dice_transaction->access<nv::index::ISession const>(
334 session_tag));
335 check_success(session.is_valid_interface());
336
337 mi::base::Handle<nv::index::IScene> scene_edit(
338 dice_transaction->edit<nv::index::IScene>(
339 session->get_scene()));
340 check_success(scene_edit.is_valid_interface());
341
342 mi::base::Handle<nv::index::ITransformed_scene_group> group_node(
343 scene_edit->create_scene_group<nv::index::ITransformed_scene_group>());
344 check_success(group_node.is_valid_interface());
345
346 // add a light and a material
347 {
348 // Add a light
349 mi::base::Handle<nv::index::IDirectional_headlight> headlight(
350 scene_edit->create_attribute<nv::index::IDirectional_headlight>());
351 check_success(headlight.is_valid_interface());
352 const mi::math::Color_struct color_intensity = { 1.0f, 1.0f, 1.0f, 1.0f, };
353 headlight->set_intensity(color_intensity);
354 headlight->set_direction(mi::math::Vector<mi::Float32, 3>(1.0f, -1.0f, -1.0f));
355 const mi::neuraylib::Tag headlight_tag = dice_transaction->store_for_reference_counting(headlight.get());
356 check_success(headlight_tag.is_valid());
357 group_node->append(headlight_tag, dice_transaction);
358
359 // add material for 3D points shape (the material is only effective for 3D shape)
360 mi::base::Handle<nv::index::IPhong_gl> phong_1(scene_edit->create_attribute<nv::index::IPhong_gl>());
361 check_success(phong_1.is_valid_interface());
362 phong_1->set_ambient(mi::math::Color(0.3f, 0.3f, 0.3f, 1.0f));
363 phong_1->set_diffuse(mi::math::Color(0.4f, 0.4f, 0.4f, 1.0f));
364 phong_1->set_specular(mi::math::Color(0.4f));
365 phong_1->set_shininess(100.f);
366 const mi::neuraylib::Tag phong_1_tag = dice_transaction->store_for_reference_counting(phong_1.get());
367 check_success(phong_1_tag.is_valid());
368 group_node->append(phong_1_tag, dice_transaction);
369 }
370
371 // Point coordinates and its attributes. According to the
372 // attributes, color and radius are defined.
373 // Here, we create two point sets.
374 std::vector< mi::math::Vector_struct< mi::Float32, 3> > point_pos_vec;
375 std::vector< mi::math::Color_struct > color_vec;
376 std::vector< mi::Float32 > radii_vec;
377
378 // square shaped positions
379 const mi::Sint32 column_count= 20;
380 const mi::Sint32 point_count = 200;
381 const mi::Float32 x_mag = 25.0;
382 const mi::Float32 y_mag = 25.0;
383 const mi::Float32 z = 30.0;
384 const mi::Float32 y_offset = 0.0f;
385 for(mi::Sint32 i = 0; i < point_count; ++i){
386 mi::math::Vector_struct< mi::Float32, 3> pos;
387 pos.x = static_cast< mi::Float32 >(i % column_count) * x_mag;
388 pos.y = static_cast< mi::Float32 >(i / column_count) * y_mag + y_offset;
389 pos.z = z;
390 point_pos_vec.push_back(pos);
391 color_vec.push_back(get_color_st_from_attribute(i));
392 radii_vec.push_back(get_radius_from_attribute(i));
393 }
394
395 // Create a point sets
396 mi::base::Handle< nv::index::IPoint_set > point_set(scene_edit->create_shape<nv::index::IPoint_set>());
397 check_success(point_set.is_valid_interface());
398
399 nv::index::IPoint_set::Point_style style =nv::index::IPoint_set::SHADED_CIRCLE;
400 point_set->set_point_style(style);
401 point_set->set_vertices(&point_pos_vec[0], point_pos_vec.size());
402 point_set->set_colors( &color_vec[0], color_vec.size());
403 point_set->set_radii( &radii_vec[0], radii_vec.size());
404
405 // Add the points to the database
406 m_point_set_tag = dice_transaction->store_for_reference_counting(point_set.get());
407 // if you are not registered Attribute_point_set, the next check fails.
408 check_success(m_point_set_tag.is_valid());
409
410 // Add to the scene description
411 group_node->append(m_point_set_tag, dice_transaction);
412 INFO_LOG << "Added point_set (size: " << point_count << ") to the scene (tag id: "
413 << m_point_set_tag.id << ").";
414
415 m_point_set_group_tag = dice_transaction->store_for_reference_counting(group_node.get());
416 check_success(m_point_set_group_tag.is_valid());
417 scene_edit->append(m_point_set_group_tag, dice_transaction);
418}
419
420//----------------------------------------------------------------------
421void Dynamic_point_set::translate_point_set(
422 const mi::neuraylib::Tag& point_set_tag,
423 const mi::math::Vector< mi::Float32, 3 >& trans_delta_vec,
424 mi::neuraylib::IDice_transaction* dice_transaction) const
425{
426 check_success(point_set_tag.is_valid());
427 check_success(dice_transaction != 0);
428
429 mi::base::Handle< nv::index::IPoint_set > point_set(
430 dice_transaction->edit< nv::index::IPoint_set >(point_set_tag));
431 check_success(point_set.is_valid_interface());
432
433 mi::Size const vertex_count = point_set->get_nb_vertices();
434 if(vertex_count == 0)
435 {
436 // no vertices
437 return;
438 }
439
440 mi::math::Vector_struct<mi::Float32, 3> const * const p_vtx = point_set->get_vertices();
441 check_success(p_vtx != 0);
442
443 std::vector< mi::math::Vector_struct<mi::Float32, 3> > vcopy;
444 vcopy.reserve(vertex_count);
445
446 for(mi::Uint32 i = 0; i < vertex_count; ++i)
447 {
448 mi::math::Vector_struct<mi::Float32, 3> vpos = p_vtx[i];
449 vpos.x += trans_delta_vec.x;
450 vpos.y += trans_delta_vec.y;
451 vpos.z += trans_delta_vec.z;
452 vcopy.push_back(vpos);
453 }
454 check_success(vcopy.size() == vertex_count);
455
456 point_set->set_vertices(&(vcopy[0]), vcopy.size());
457}
458
459//----------------------------------------------------------------------
460void Dynamic_point_set::delete_scene_element(
461 const mi::neuraylib::Tag& scene_element_tag,
462 const mi::neuraylib::Tag& transform_tag,
463 mi::neuraylib::IDice_transaction* dice_transaction) const
464{
465 check_success(scene_element_tag.is_valid());
466 check_success(transform_tag.is_valid());
467 check_success(dice_transaction != 0);
468
469 mi::base::Handle<nv::index::ITransformed_scene_group> group_node(
470 dice_transaction->edit<nv::index::ITransformed_scene_group>(transform_tag));
471 check_success(group_node.is_valid_interface());
472
473 group_node->remove(scene_element_tag, dice_transaction);
474
475 std::stringstream sstr;
476 sstr << "scene element: " << scene_element_tag.id;
477 DEBUG_LOG << sstr.str() << " was removed from the scene.";
478}
479
480//----------------------------------------------------------------------
481void Dynamic_point_set::get_top_view_param(const mi::math::Bbox<mi::Float32, 3>& vbbox,
482 const mi::Float32 aspect,
483 const mi::Float32 fovy_2,
484 mi::math::Vector< mi::Float32, 3 >& from,
485 mi::math::Vector< mi::Float32, 3 >& to,
486 mi::math::Vector< mi::Float32, 3 >& up,
487 mi::Float32 & clip_min,
488 mi::Float32 & clip_max) const
489{
490 check_success((0.0 < fovy_2) && (fovy_2 < M_PI_2));
491 const mi::Float32 dist = static_cast<mi::Float32>((0.6 * mi::math::euclidean_distance(vbbox.max, vbbox.min)) /
492 (sqrt(2.0) * tan(fovy_2)));
493 from = -(dist * mi::math::Vector< mi::Float32, 3 >(0.0f, 0.0f, -1.0f)) + vbbox.center();
494 to = vbbox.center();
495 up = mi::math::Vector< mi::Float32, 3 >(0.0f, 1.0f, 0.0f);
496 clip_min = 0.1f * dist;
497 clip_max = 10.0f * dist;
498}
499
500//----------------------------------------------------------------------
501mi::math::Vector<mi::Uint32, 2> Dynamic_point_set::get_resolution() const
502{
503 mi::math::Vector<mi::Uint32, 2> res(m_resolution_x, m_resolution_y);
504 if((res.x == 0) || (res.y == 0))
505 {
506 ERROR_LOG << "illegal_resolution setting: [" << res.x << "x" << res.y << "], use 1024x1024.";
507 res.x = 1024;
508 res.y = 1024;
509 }
510 return res;
511}
512
513//----------------------------------------------------------------------
514void Dynamic_point_set::setup_camera(
515 nv::index::IPerspective_camera* cam,
516 const mi::math::Vector<mi::Uint32, 3>& roi_max,
517 mi::neuraylib::IDice_transaction* dice_transaction) const
518{
519 check_success(cam != 0);
520
521 cam->set_aperture(0.033f);
522 cam->set_focal(0.03f);
523
524 const mi::math::Vector<mi::Uint32, 2> res = get_resolution();
525 const mi::Float32 pix_aspect_ratio_1x1 = 1.0f;
526 // static_cast< mi::Float32 >(res.x) / static_cast< mi::Float32 >(res.y);
527
528 cam->set_aspect(pix_aspect_ratio_1x1);
529
530 // get top view for this scene
531 mi::math::Bbox< mi::Float32, 3 > const
532 vbbox(0.0f, 0.0f, 0.0f,
533 static_cast< mi::Float32>(roi_max.x), static_cast< mi::Float32>(roi_max.y),
534 static_cast< mi::Float32>(roi_max.z));
535 mi::math::Vector< mi::Float32, 3 > from(0.0f, 0.0f, 0.0f);
536 mi::math::Vector< mi::Float32, 3 > to (0.0f, 0.0f, 0.0f);
537 mi::math::Vector< mi::Float32, 3 > up (0.0f, 0.0f, 0.0f);
538 mi::Float32 clip_min = 0.1f;
539 mi::Float32 clip_max = 10.0f;
540 get_top_view_param(vbbox,
541 static_cast<mi::Float32>(cam->get_aspect()),
542 static_cast<mi::Float32>((cam->get_fov_y_rad() / 2.0)),
543 from, to, up, clip_min, clip_max);
544
545 INFO_LOG << "set camera resolution [" << res.x << " " << res.y
546 << "], aspect_ratio: " << pix_aspect_ratio_1x1;
547
548 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
549 viewdir.normalize();
550
551 cam->set(from, viewdir, up);
552 cam->set_clip_min(clip_min);
553 cam->set_clip_max(clip_max);
554}
555
556//----------------------------------------------------------------------
557bool Dynamic_point_set::setup_main_host()
558{
559 // roi max
560 mi::math::Vector< mi::Uint32, 3 > roi_max(m_roi_x, m_roi_y, m_roi_z);
561 for(mi::Sint32 i = 0; i < 3; ++i)
562 {
563 if(roi_max[i] <= 0)
564 {
565 ERROR_LOG << "illegal roi setting: [" << i <<"] = " << roi_max[i] << ", use 1024.";
566 roi_max[i] = 1024;
567 }
568 }
569
570 // Access the IndeX rendering query interface
571 m_cluster_configuration =
572 get_index_interface()->get_api_component<nv::index::ICluster_configuration>();
573 check_success(m_cluster_configuration.is_valid_interface());
574
575 // create image canvas in application_layer
576 m_image_file_canvas = create_image_file_canvas(get_application_layer_interface());
577 check_success(m_image_file_canvas.is_valid_interface());
578
579 // Verifying that local host has joined
580 // This may fail when there is a license problem.
581 check_success(is_local_host_joined(m_cluster_configuration.get()));
582
583 // DiCE database access
584 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
585 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
586 check_success(dice_transaction.is_valid_interface());
587 {
588 // Setup session information
589 m_session_tag =
590 m_index_session->create_session(dice_transaction.get());
591 check_success(m_session_tag.is_valid());
592 //----------------------------------------------------------------------
593 // Scene setup
594
595 // no scene setup in the start up in this example
596
597 // Create and edit a camera. Data distribution is based on
598 // the camera. (Because only visible massive data are
599 // considered)
600 mi::base::Handle< nv::index::ISession const > session(
601 dice_transaction->access< nv::index::ISession const >(
602 m_session_tag));
603 check_success(session.is_valid_interface());
604
605 mi::base::Handle< nv::index::IScene > scene_edit(
606 dice_transaction->edit<nv::index::IScene>(session->get_scene()));
607 check_success(scene_edit.is_valid_interface());
608
609 mi::base::Handle< nv::index::IPerspective_camera > cam(
610 scene_edit->create_camera<nv::index::IPerspective_camera>());
611 check_success(cam.is_valid_interface());
612 setup_camera(cam.get(), roi_max, dice_transaction.get());
613 const mi::neuraylib::Tag camera_tag = dice_transaction->store(cam.get());
614 check_success(camera_tag.is_valid());
615
616 const mi::math::Vector<mi::Uint32, 2> buffer_resolution = get_resolution();
617 m_image_file_canvas->set_resolution(buffer_resolution);
618
619 // Set up the scene
620 mi::math::Bbox_struct< mi::Float32, 3 > const xyz_roi_st = {
621 { 0.0f, 0.0f, 0.0f, },
622 { static_cast< mi::Float32 >(roi_max.x),
623 static_cast< mi::Float32 >(roi_max.y),
624 static_cast< mi::Float32 >(roi_max.z), },
625 };
626
627 // set the region of interest
628 const mi::math::Bbox< mi::Float32, 3 > xyz_roi(xyz_roi_st);
629 check_success(xyz_roi.is_volume());
630 scene_edit->set_clipped_bounding_box(xyz_roi_st);
631
632 // Set the scene global transformation matrix.
633 // only change the coordinate system
634 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(
635 1.0f, 0.0f, 0.0f, 0.0f,
636 0.0f, 1.0f, 0.0f, 0.0f,
637 0.0f, 0.0f, -1.0f, 0.0f,
638 0.0f, 0.0f, 0.0f, 1.0f
639 );
640 scene_edit->set_transform_matrix(transform_mat);
641
642 // Set the current camera to the scene.
643 check_success(camera_tag.is_valid());
644 scene_edit->set_camera(camera_tag);
645
646 INFO_LOG << "ROI set to [0, 0, 0]-[" << roi_max.x << ", " << roi_max.y << ", " << roi_max.z << "]";
647 }
648 dice_transaction->commit();
649
650 INFO_LOG << "Initialization complete.";
651
652 return true;
653}
654
655//----------------------------------------------------------------------
656void Dynamic_point_set::animate_point(
657 const mi::neuraylib::Tag& session_tag,
658 mi::Sint32 frame_idx,
659 mi::neuraylib::IDice_transaction* dice_transaction)
660{
661 if(m_frame_command_vec.empty())
662 {
663 // no more processing commands
664 return;
665 }
666
667 if(m_frame_command_vec.back().get_frame() != frame_idx)
668 {
669 return;
670 }
671
672 Frame_command fc = m_frame_command_vec.back(); // copy
673 check_success(!m_frame_command_vec.empty());
674 m_frame_command_vec.pop_back();
675
676 INFO_LOG << "execute command: " << fc.to_string();
677 const std::string & com = fc.get_command();
678 if(com == "create")
679 {
680 if(m_point_set_tag.is_valid())
681 {
682 ERROR_LOG << "create: Point set has been already created. ignored.";
683 return;
684 }
685 create_point_set(session_tag, dice_transaction);
686 }
687 else if(com == "delete")
688 {
689 if(!(m_point_set_tag.is_valid()))
690 {
691 ERROR_LOG << ("delete: Point set doesn't exist. ignored.");
692 return;
693 }
694 delete_scene_element(m_point_set_tag,
695 m_point_set_group_tag,
696 dice_transaction);
697 m_point_set_tag = mi::neuraylib::NULL_TAG;
698 }
699 else if(com == "translate_delta")
700 {
701 if(!(m_point_set_tag.is_valid()))
702 {
703 ERROR_LOG << ("translate_delta: Point set doesn't exist. ignored.");
704 return;
705 }
706 std::vector< std::string > args = fc.get_argument();
707 check_success(args.size() == 4);
708 mi::math::Vector< mi::Float32, 3 > trans_delta_vec(nv::index::app::get_float32(args[1]),
709 nv::index::app::get_float32(args[2]),
710 nv::index::app::get_float32(args[3]));
711 translate_point_set(m_point_set_tag,
712 trans_delta_vec,
713 dice_transaction);
714 }
715 else
716 {
717 ERROR_LOG << ("unknown command [" + com + "]. ignored.");
718 }
719}
720
721//----------------------------------------------------------------------
722nv::index::IFrame_results* Dynamic_point_set::render_frame(const std::string& output_fname) const
723{
724 check_success(m_index_rendering.is_valid_interface());
725
726 // set output filename, empty string is valid
727 m_image_file_canvas->set_rgba_file_name(output_fname.c_str());
728
729 check_success(m_session_tag.is_valid());
730
731 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
732 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
733 check_success(dice_transaction.is_valid_interface());
734
735 m_index_session->update(m_session_tag, dice_transaction.get());
736
737 mi::base::Handle<nv::index::IFrame_results> frame_results(
738 m_index_rendering->render(
739 m_session_tag,
740 m_image_file_canvas.get(),
741 dice_transaction.get()));
742 check_success(frame_results.is_valid_interface());
743
744 dice_transaction->commit();
745
746 frame_results->retain();
747 return frame_results.get();
748}
749
750//----------------------------------------------------------------------
751bool Dynamic_point_set::update_scene_and_render_frame(mi::Sint32 frame_idx)
752{
753 bool success = true;
754
755 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(create_transaction());
756 check_success(dice_transaction.is_valid_interface());
757 {
758 // Change the scene element, camera, etc. here. This example
759 // does not change any, but usually you can change camera
760 // parameters, add/remove scene elements here.
761 animate_point(m_session_tag, frame_idx, dice_transaction.get());
762 }
763 dice_transaction->commit();
764
765
766 // Render a frame and save the rendered image to a file.
767 // Only save the file at the end of the iteration.
768 std::string fname = "";
769 if (m_is_save_all_frame)
770 {
771 fname = get_output_file_name(m_outfname, frame_idx);
772 }
773
774 mi::base::Handle<nv::index::IFrame_results> frame_results(render_frame(fname));
775 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
776 if (err_set->any_errors())
777 {
778 std::ostringstream os;
779
780 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
781 const mi::Uint32 nb_err = err_set->get_nb_errors();
782 for (mi::Uint32 e = 0; e < nb_err; ++e)
783 {
784 if (e != 0) os << '\n';
785 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
786 os << err->get_error_string();
787 }
788
789 ERROR_LOG << "IIndex_rendering rendering call failed with the following error(s): " << '\n'
790 << os.str();
791 success = false;
792 }
793
794 return success;
795}
796
797//----------------------------------------------------------------------
798bool Dynamic_point_set::mainhost_rendering_loop()
799{
800 check_success(m_max_iter > 0);
801 const mi::Sint32 max_frame_count = m_max_iter - 1;
802 INFO_LOG << "set max iteration: " << m_max_iter;
803 INFO_LOG << "set is_save_all_frame: " << (m_is_save_all_frame ? "true" : "false");
804
805 // rendering loop
806 bool is_ok = true;
807 for(mi::Sint32 i = 0; i < m_max_iter; ++i)
808 {
809 if((!m_is_save_all_frame) && (i != max_frame_count))
810 {
811 m_is_save_all_frame = true;
812 }
813
814 is_ok = update_scene_and_render_frame(i);
815 if(!is_ok)
816 {
817 break;
818 }
819 }
820
821 INFO_LOG << "Finished main host rendering loop.";
822
823 return is_ok;
824}
825
826//----------------------------------------------------------------------
827void Dynamic_point_set::setup_animation()
828{
829 // commands
830 std::vector< std::string > com_create;
831 com_create.push_back("create");
832 std::vector< std::string > com_translate;
833 com_translate.push_back("translate_delta");
834 com_translate.push_back("20.0"); // dx
835 com_translate.push_back("20.0"); // dy
836 com_translate.push_back("20.0"); // dz
837
838 std::vector< std::string > com_delete;
839 com_delete.push_back("delete");
840
841 m_frame_command_vec.push_back(Frame_command(5, com_create));
842
843 for(mi::Sint32 i = 10; i < 20; ++i)
844 {
845 m_frame_command_vec.push_back(Frame_command(i, com_translate));
846 }
847 m_frame_command_vec.push_back(Frame_command(22, com_delete));
848
849 if(!m_is_unittest)
850 {
851 // non unit test mode
852 // create and delete again
853 mi::Sint32 const base_frame = 30;
854 mi::Sint32 const interval = 5; // must be larger than offset
855 mi::Sint32 const iter = 3;
856 for(mi::Sint32 i = 0; i < iter; ++i)
857 {
858 mi::Sint32 iter_base = base_frame + (i * interval);
859 mi::Sint32 offset = 0;
860 m_frame_command_vec.push_back(Frame_command(iter_base + offset, com_create));
861 ++offset;
862 m_frame_command_vec.push_back(Frame_command(iter_base + offset, com_translate));
863 ++offset;
864 m_frame_command_vec.push_back(Frame_command(iter_base + offset, com_delete));
865 ++offset;
866 check_success(offset < interval);
867 }
868 }
869
870 std::sort(m_frame_command_vec.begin(), m_frame_command_vec.end(), Frame_command_sorter());
871
872 // descendant order: debug print (need this int)
873 assert(!(m_frame_command_vec.empty()));
874 for(mi::Sint32 i = static_cast<mi::Sint32>(m_frame_command_vec.size() - 1); i >=0 ; --i)
875 {
876 // std::cout << "idx: " << i << std::endl;
877 DEBUG_LOG << m_frame_command_vec.at(i).to_string();
878 }
879}
880
881//----------------------------------------------------------------------
882// main for dynamic_point_set
883int main(int argc, const char* argv[])
884{
885 nv::index::app::String_dict sdict;
886 sdict.insert("dice::verbose", "3"); // log level
887 sdict.insert("dice::network::multicast_address", "224.1.3.2"); // default multicast address
888 sdict.insert("max_iter", "40"); // default max rendering loop iterations
889 sdict.insert("resolution_x", "1024"); // X resolution
890 sdict.insert("resolution_y", "1024"); // Y resolution
891 sdict.insert("roi_x", "512"); // region of interest max X
892 sdict.insert("roi_y", "512"); // region of interest max Y
893 sdict.insert("roi_z", "512"); // region of interest max Z
894 sdict.insert("outfname", "frame_dynamic_point"); // output file base name
895 sdict.insert("is_save_all_frame", "0"); // save all frame
896 sdict.insert("is_animation_on", "1"); // points animation
897 sdict.insert("point_rendering_mode", "raytracing"); // point rendering mode
898 sdict.insert("point_radius_mode", "object_space"); // point radius mode
899 sdict.insert("unittest", "0"); // unit test mode
900 sdict.insert("is_dump_comparison_image_when_failed", "1"); // default: dump images when failed.
901 sdict.insert("is_call_from_test", "0"); // default: not call from make check.
902
903 // Load IndeX library via Index_connect
904 sdict.insert("dice::network::mode", "OFF");
905
906 // index setting
907 sdict.insert("index::config::set_monitor_performance_values", "true");
908 sdict.insert("index::service", "rendering_and_compositing");
909 sdict.insert("index::cuda_debug_checks", "false");
910
911 // application_layer component loading
912 sdict.insert("index::app::components::application_layer::component_name_list",
913 "canvas_infrastructure image io");
914
915 // Initialize application
916 Dynamic_point_set dynamic_point_set;
917 dynamic_point_set.initialize(argc, argv, sdict);
918 check_success(dynamic_point_set.is_initialized());
919
920 // launch the application. creating the scene and rendering.
921 const mi::Sint32 exit_code = dynamic_point_set.launch();
922 INFO_LOG << "Shutting down ...";
923
924 return exit_code;
925}
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
int main(int argc, const char *argv[])
#define check_success(expr)