NVIDIA Index example code nvidia_logo_transpbg.gif Up
create_path.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/iindex_debug_configuration.h>
17#include <nv/index/ilight.h>
18#include <nv/index/imaterial.h>
19#include <nv/index/ipath.h>
20#include <nv/index/iplane.h>
21#include <nv/index/iscene.h>
22#include <nv/index/iscene_group.h>
23#include <nv/index/isession.h>
24#include <nv/index/itexture_filter_mode.h>
25
26#include <nv/index/ipath_query_results.h>
27
28#include <nv/index/app/index_connect.h>
29#include <nv/index/app/string_dict.h>
30#include <nv/index/app/idata_analysis_and_processing.h>
31
32#include "utility/canvas_utility.h"
33
34#include <iostream>
35#include <sstream>
36
37// tag and its info for test purpose
39{
40public:
41 // default constructor
43 m_assoc_type("<not defined>"),
44 m_num_points(-1)
45 {
46 // empty
47 }
48 // default constructor
49 Test_tag_info(const std::string & type_name, mi::Sint32 num_points) :
50 m_assoc_type(type_name),
51 m_num_points(num_points)
52 {
53 // empty
54 }
55 // destructor
57 {
58 // empty
59 }
60 // copy constructor
62 {
65 }
66 // operator=
68 {
69 if(this != &rhs){
70 this->m_assoc_type = rhs.m_assoc_type;
71 this->m_num_points = rhs.m_num_points;
72 }
73 return (*this);
74 }
75
76public:
77 // tag associated type name
78 std::string m_assoc_type;
79 // number of points if the scene element has, otherwise, -1
80 mi::Sint32 m_num_points;
81
82private:
83};
84
85class Tag_comp {
86public:
87 bool operator()(const mi::neuraylib::Tag & lhs, const mi::neuraylib::Tag & rhs) const
88 {
89 return lhs.id < rhs.id;
90 }
91};
92
93//----------------------------------------------------------------------
95 public nv::index::app::Index_connect
96{
97public:
99 {
100 mi::Uint32 num_points;
106 mi::Uint32 up_factor;
107 mi::Float32 up_tension;
108 };
109
110 // ctor
112 :
113 Index_connect()
114 {
115 // INFO_LOG << "DEBUG: Create_path() ctor";
116 }
117
118 virtual ~Create_path()
119 {
120 // Note: Index_connect::~Index_connect() will be called after here.
121 // INFO_LOG << "DEBUG: ~Create_path() dtor";
122 }
123
124 // launch application
125 mi::Sint32 launch();
126
127protected:
128 virtual bool evaluate_options(nv::index::app::String_dict& sdict) CPP11_OVERRIDE;
129 // override
131 mi::neuraylib::INetwork_configuration* network_configuration,
132 nv::index::app::String_dict& options) CPP11_OVERRIDE
133 {
134 check_success(network_configuration != 0);
135
136 check_success(options.is_defined("unittest"));
137 const bool is_unittest = nv::index::app::get_bool(options.get("unittest"));
138 if (is_unittest)
139 {
140 info_cout("NETWORK: disabled networking mode.", options);
141 network_configuration->set_mode(mi::neuraylib::INetwork_configuration::MODE_OFF);
142 return true;
143 }
144
145 return initialize_networking_as_default_udp(network_configuration, options);
146 }
147
148private:
149 mi::Float32 evaluate_path(mi::Float32 x) const;
150 mi::math::Color_struct jetmap(mi::Float32 v, mi::Float32 vmin, mi::Float32 vmax) const;
151
152 nv::index::IColormap* create_colormap(nv::index::IScene* scene, bool use_transparency) const;
153 // Create scene.
154 bool create_scene(
155 nv::index::IScene* scene_edit,
156 std::vector<mi::neuraylib::Tag>& path_tags,
157 std::map< mi::neuraylib::Tag, Test_tag_info, Tag_comp >& test_tag_info_map,
158 mi::neuraylib::IDice_transaction* dice_transaction) const;
159
160 // setup camera to see this example scene
161 // \param[in] cam a camera
162 void setup_camera(nv::index::IPerspective_camera* cam) const;
163 // Setup a far away camera for a extreme transformation handling test
164 //
165 // This value is based on Bugzilla 11567
166 // Attachment: Two complete screen dump with 188853_8578 build case
167 // \param[in] cam a camera
168 void setup_extreme_transformed_camera(nv::index::IPerspective_camera* cam) const;
169
170 // setup a large scene transform for the extreme
171 // transformation handling test
172 //
173 // This value is based on Bugzilla 11567
174 // Attachment: Two complete screen dump with 188853_8578 build case
175 mi::math::Matrix<mi::Float32, 4, 4> get_extreme_transformed_matrix() const;
176 // render a frame
177 //
178 // \param[in] output_fname output rendering image filename
179 // \return performance values
180 nv::index::IFrame_results* render_frame(const std::string& output_fname) const;
181
182 // This session tag
183 mi::neuraylib::Tag m_session_tag;
184 // NVIDIA IndeX cluster configuration
185 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
186 // Application layer image file canvas (a render target)
187 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
188 // Create_icons options
189 std::string m_outfname;
190 bool m_is_unittest;
191 std::string m_verify_image_fname;
192 bool m_supersampling;
193 bool m_is_large_translate;
194 Path_test_params m_path_test_params;
195};
196
197
198//----------------------------------------------------------------------
200{
201 mi::Sint32 exit_code = 0;
202
203 // Get DiCE database components
204 {
205 mi::base::Handle<nv::index::IIndex_scene_query> iindex_query(
206 get_index_interface()->get_api_component<nv::index::IIndex_scene_query>());
207 check_success(iindex_query.is_valid_interface());
208
209 m_cluster_configuration =
210 get_index_interface()->get_api_component<nv::index::ICluster_configuration>();
211 check_success(m_cluster_configuration.is_valid_interface());
212
213 // create image canvas in application_layer
214 m_image_file_canvas = create_image_file_canvas(get_application_layer_interface());
215 check_success(m_image_file_canvas.is_valid_interface());
216
217 // Verifying that local host has joined
218 // This may fail when there is a license problem.
219 check_success(is_local_host_joined(m_cluster_configuration.get()));
220
221 std::map< mi::neuraylib::Tag, Test_tag_info, Tag_comp > test_tag_info_map;
222 std::vector<mi::neuraylib::Tag> path_tags; // used for later entry lookup queries.
223 {
224 // DiCE database access
225 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
226 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
227 check_success(dice_transaction.is_valid_interface());
228 {
229 // Setup session information
230 m_session_tag = m_index_session->create_session(dice_transaction.get());
231 check_success(m_session_tag.is_valid());
232 mi::base::Handle<const nv::index::ISession> session(
233 dice_transaction->access<const nv::index::ISession>(m_session_tag));
234 check_success(session.is_valid_interface());
235
236 mi::base::Handle< nv::index::IScene > scene_edit(
237 dice_transaction->edit< nv::index::IScene >(session->get_scene()));
238 check_success(scene_edit.is_valid_interface());
239
240 // Enable supersampling
241 if (m_supersampling)
242 {
243 INFO_LOG << "Enable full-screen supersampling.";
244 mi::base::Handle<nv::index::IConfig_settings> config_settings(
245 dice_transaction->edit<nv::index::IConfig_settings>(session->get_config()));
246 check_success(config_settings.is_valid_interface());
247
248 config_settings->set_rendering_samples(16);
249 }
250
251 //----------------------------------------------------------------------
252 // Scene setup: hierarchical scene description root node,
253 // scene parameters, camera.
254 //----------------------------------------------------------------------
255 check_success(create_scene(scene_edit.get(), path_tags, test_tag_info_map, dice_transaction.get()));
256 check_success(test_tag_info_map.size() == path_tags.size());
257
258 // Create and edit a camera. Data distribution is based on
259 // the camera. (Because only visible massive data are considered)
260 mi::base::Handle< nv::index::IPerspective_camera > cam(
261 scene_edit->create_camera<nv::index::IPerspective_camera>());
262 check_success(cam.is_valid_interface());
263
264 mi::math::Vector<mi::Uint32, 2> buffer_resolution;
265 if (m_is_large_translate)
266 {
267 INFO_LOG << "large translate test mode.";
268 setup_extreme_transformed_camera(cam.get());
269 buffer_resolution = mi::math::Vector<mi::Uint32, 2>(1602, 934);
270 }
271 else
272 {
273 setup_camera(cam.get());
274 buffer_resolution = mi::math::Vector<mi::Uint32, 2>(1024, 1024);
275 }
276 const mi::neuraylib::Tag camera_tag = dice_transaction->store(cam.get());
277 check_success(camera_tag.is_valid());
278
279 m_image_file_canvas->set_resolution(buffer_resolution);
280
281 // Set up the scene
282 const mi::math::Bbox_struct< mi::Float32, 3 > xyz_roi_st = {
283 { -1000.0f, -1000.0f, -1000.0f, },
284 { 1000.0f, 1000.0f, 1000.0f, },
285 };
286
287 // set the region of interest
288 const mi::math::Bbox< mi::Float32, 3 > xyz_roi(xyz_roi_st);
289 check_success(xyz_roi.is_volume());
290 scene_edit->set_clipped_bounding_box(xyz_roi_st);
291
292 // Set the scene global transformation matrix.
293 // only change the coordinate system
294 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(
295 1.0f, 0.0f, 0.0f, 0.0f,
296 0.0f, 1.0f, 0.0f, 0.0f,
297 0.0f, 0.0f, -1.0f, 0.0f,
298 0.0f, 0.0f, 0.0f, 1.0f
299 );
300
301 if (m_is_large_translate)
302 {
303 transform_mat = get_extreme_transformed_matrix();
304 }
305
306 scene_edit->set_transform_matrix(transform_mat);
307
308 INFO_LOG << "transformed: " << scene_edit->get_transform_matrix();
309
310 // Set the current camera to the scene.
311 check_success(camera_tag.is_valid());
312 scene_edit->set_camera(camera_tag);
313 }
314 dice_transaction->commit();
315 }
316
317 // Rendering
318 {
319 // Render a frame and save the rendered image to a file.
320 const mi::Sint32 frame_idx = 0;
321 const std::string fname = get_output_file_name(m_outfname, frame_idx);
322 mi::base::Handle<nv::index::IFrame_results> frame_results(render_frame(fname));
323 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
324 if (err_set->any_errors())
325 {
326 std::ostringstream os;
327
328
329 const mi::Uint32 nb_err = err_set->get_nb_errors();
330 for (mi::Uint32 e = 0; e < nb_err; ++e)
331 {
332 if (e != 0) os << '\n';
333 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
334 os << err->get_error_string();
335 }
336
337 ERROR_LOG << "IIndex_rendering rendering call failed with the following error(s): " << '\n'
338 << os.str();
339 exit_code = 1;
340 }
341 }
342
343 // Picking
344 {
345 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
346 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
347 check_success(dice_transaction.is_valid_interface());
348 {
349 mi::math::Vector_struct<mi::Uint32, 2> pick_location;
350 pick_location.x = 256;
351 pick_location.y = 314;
352 INFO_LOG << "Query pick location: " << pick_location;
353 mi::base::Handle<nv::index::IScene_pick_results> scene_pick_results(
354 iindex_query->pick(pick_location, m_image_file_canvas.get(), m_session_tag, dice_transaction.get()));
355 const mi::Uint32 nb_results = scene_pick_results->get_nb_results();
356 if(nb_results>0)
357 {
358 INFO_LOG << "Number of pick results: " << nb_results;
359 for(mi::Uint32 i=0; i<nb_results; ++i)
360 {
361 const mi::base::Handle<nv::index::IScene_pick_result> result(scene_pick_results->get_result(i));
362 const mi::math::Vector_struct<mi::Float32, 3>& intersection = result->get_intersection();
363 INFO_LOG << "Intersection no. " << i << "\n"
364 << "\t\t Element (tag) " << result->get_scene_element().id << "\n"
365 << "\t\t Sub index: " << result->get_scene_element_sub_index() << "\n"
366 << "\t\t Distance: " << result->get_distance() << "\n"
367 << "\t\t Position (local space): " << intersection << "\n"
368 << "\t\t Color (evaluated): " << result->get_color();
369
370 if(result->get_intersection_info_class() == nv::index::IPath_pick_result::IID() )
371 {
372 mi::base::Handle<const nv::index::IPath_pick_result> path_pick_result(
373 result->get_interface<const nv::index::IPath_pick_result>());
374 if(path_pick_result.get())
375 {
376 INFO_LOG << "Path specific pick results:" << "\n"
377 << "\t\t Segment id: " << path_pick_result->get_segment();
378 }
379 }
380 }
381 }
382
383 const mi::Size nb_tags = path_tags.size();
384 for (mi::Size i = 0; i < nb_tags; ++i)
385 {
386 const mi::neuraylib::Tag path_scene_element_tag = path_tags[i];
387 check_success(test_tag_info_map.find(path_scene_element_tag) != test_tag_info_map.end());
388 const Test_tag_info tti = test_tag_info_map[path_scene_element_tag];
389
390 // The loop is supposed to query every entry of the given path until
391 // an entry for the given index value is not available anymore, i.e., the
392 // length of the path has been exceeded.
393 // Once the path has been exceeded, the example should continue with the next
394 // path (outer loop).
395 const mi::Uint32 LOOP_DELTA = 9;
396 for(mi::Uint32 index = 0; index < 100; index += LOOP_DELTA)
397 {
398 if(tti.m_num_points <= static_cast< mi::Sint32 >(index)){
399 WARN_LOG << "Note: expected the following warning: "
400 << "The index " << index << " is greater than the number of entries in the path "
401 << "(entry count: " << tti.m_num_points << "). for tag: "
402 << path_scene_element_tag.id << ", type: " << tti.m_assoc_type
403 << " with access index: " << index << " in this test.";
404 }
405
406 // Issue an entry lookup query
407 mi::base::Handle<nv::index::IScene_lookup_result> lookup_result(iindex_query->entry_lookup(
408 index, // index
409 path_scene_element_tag,
410 m_session_tag,
411 dice_transaction.get()));
412
413 // Verify if the data entry available at path location.
414 if(!lookup_result.is_valid_interface())
415 {
416 WARN_LOG << "No entry available at path index: " << index;
417 INFO_LOG << "Please note, the path might simply have too few entries.";
418 check_success(tti.m_num_points <= static_cast< mi::Sint32 >(index));
419 break;
420 }
421
422 // Verify the query results
423 if(lookup_result->get_intersection_info_class() == nv::index::IPath_lookup_result::IID())
424 {
425 mi::base::Handle<const nv::index::IPath_lookup_result> path_lookup_result(
426 lookup_result->get_interface<const nv::index::IPath_lookup_result>());
427 if(path_lookup_result.get())
428 {
429 INFO_LOG << "Path specific lookup results:";
430 INFO_LOG << "\t Tag id: " << path_scene_element_tag.id;
431 INFO_LOG << "\t Entry index: " << index;
432 INFO_LOG << "\t Vertex: " << path_lookup_result->get_vertex();
433 INFO_LOG << "\t Color index: " << path_lookup_result->get_radius();
434 INFO_LOG << "\t Color: " << path_lookup_result->get_color();
435 INFO_LOG << "\t Color index: " << path_lookup_result->get_color_index();
436 }
437 }
438 }
439 }
440
441 // verify the generated frame
442 if (!(verify_canvas_result(get_application_layer_interface(),
443 m_image_file_canvas.get(), m_verify_image_fname, get_options())))
444 {
445 exit_code = 1;
446 }
447
448 }
449 // Finish this transaction
450 dice_transaction->commit();
451 }
452 }
453
454 return exit_code;
455}
456
457//----------------------------------------------------------------------
458bool Create_path::evaluate_options(nv::index::app::String_dict& sdict)
459{
460 const std::string com_name = sdict.get("command:", "<unknown_command>");
461 m_is_unittest = nv::index::app::get_bool(sdict.get("unittest", "false"));
462
463 if (m_is_unittest)
464 {
465 if (nv::index::app::get_bool(sdict.get("is_call_from_test", "false")))
466 {
467 sdict.insert("is_dump_comparison_image_when_failed", "0");
468 }
469 sdict.insert("outfname", ""); // turn off file output in the unit test mode
470 sdict.insert("dice::verbose", "2");
471 }
472
473 m_outfname = sdict.get("outfname", "");
474 m_verify_image_fname = sdict.get("verify_image_fname");
475 m_supersampling = nv::index::app::get_bool(sdict.get("supersampling", "false"));
476 m_is_large_translate = nv::index::app::get_bool(sdict.get("is_large_translate", "false"));
477 // Path_test_params
478 m_path_test_params.num_points = nv::index::app::get_uint32(sdict.get("num_samples", ""));
479 m_path_test_params.use_colormap = nv::index::app::get_bool( sdict.get("use_colormap", "false"));
480 m_path_test_params.use_rgba = nv::index::app::get_bool( sdict.get("use_rgba", "false"));
481 m_path_test_params.npr_mode = nv::index::app::get_bool( sdict.get("npr_mode", "false"));
482 m_path_test_params.test_transparency = nv::index::app::get_bool( sdict.get("test_transparency", "false"));
483 m_path_test_params.upsampling = nv::index::app::get_bool( sdict.get("upsampling", "false"));
484 m_path_test_params.up_factor = nv::index::app::get_uint32(sdict.get("up_factor", "2"));
485 m_path_test_params.up_tension = nv::index::app::get_float32(sdict.get("up_tension", "0"));
486
487 info_cout(std::string("running ") + com_name, sdict);
488 info_cout(std::string("outfname = [") + m_outfname +
489 "], verify_image_fname = [" + m_verify_image_fname +
490 "], dice::verbose = " + sdict.get("dice::verbose"), sdict);
491
492 // print help and exit if -h
493 if(sdict.is_defined("h")){
494 std::cout
495 << "info: Usage: " << com_name << " [option]\n"
496 << "Option: [-h]\n"
497 << " printout this message\n"
498 << " [-dice::verbose severity_level]\n"
499 << " verbose severity level (3 is info.). (default: " + sdict.get("dice::verbose")
500 << ")\n"
501
502 << " [-supersampling bool]\n"
503 << " when true then full screen supersampling is enabled."
504 << "(default: " << m_supersampling << ")\n"
505
506 << " [-num_samples int]\n"
507 << " set the number of path samples for the test."
508 << "(default: " << m_path_test_params.num_points << ")\n"
509
510 << " [-use_colormap bool]\n"
511 << " enable/disable colormap source."
512 << "(default: " << m_path_test_params.use_colormap << ")\n"
513
514 << " [-use_rgba bool]\n"
515 << " enable/disable rgba array source."
516 << "(default: " << m_path_test_params.use_rgba << ")\n"
517
518 << " [-npr_mode bool]\n"
519 << " enable/disable non-photorealistic mode."
520 << "(default: " << m_path_test_params.npr_mode << ")\n"
521
522 << " [-test_transparency bool]\n"
523 << " enable/disable transparency test."
524 << "(default: " << m_path_test_params.test_transparency << ")\n"
525
526 << " [-upsampling bool]\n"
527 << " enable/disable upsampling."
528 << "(default: " << m_path_test_params.upsampling << ")\n"
529
530 << " [-up_factor int]\n"
531 << " upsampling factor. Increase of the sampling rate factor."
532 << "(default: " << m_path_test_params.up_factor << ")\n"
533
534 << " [-up_tension float]\n"
535 << " upsampling tension. tension of the fitting curve [0.0, 1.0]."
536 << "(default: " << m_path_test_params.up_tension << ")\n"
537
538 << " [-is_large_translate bool]\n"
539 << " on/off large translation mode."
540 << "(default: " << m_is_large_translate << ")\n"
541
542 << " [-outfname string]\n"
543 << " output ppm file base name. When empty, no output.\n"
544 << " A frame number and extension (.ppm) will be added.\n"
545 << " (default: [" << m_outfname << "])\n"
546 << " [-verify_image_fname [image_fname]]\n"
547 << " when image_fname exist, verify the rendering image. (default: ["
548 << m_verify_image_fname << "])\n"
549
550 << " [-unittest bool]\n"
551 << " when true, unit test mode (create smaller volume). "
552 << "(default: " << m_is_unittest << ")"
553 << std::endl;
554 exit(1);
555 }
556 return true;
557}
558
559//----------------------------------------------------------------------
560mi::Float32 Create_path::evaluate_path(mi::Float32 x) const
561{
562 return expf(-x) + 0.15f*cosf(3.f*static_cast<mi::Float32>(MI_PI)*x/4.f);
563}
564
565//----------------------------------------------------------------------
566mi::math::Color_struct Create_path::jetmap(mi::Float32 v, mi::Float32 vmin, mi::Float32 vmax) const
567{
568 mi::math::Color_struct c = {1.f, 1.f, 1.f, 1.f};
569 mi::Float32 dv;
570
571 if (v < vmin)
572 v = vmin;
573 if (v > vmax)
574 v = vmax;
575 dv = vmax - vmin;
576
577 if (v < (vmin + 0.25f * dv))
578 {
579 c.r = 0.f;
580 c.g = 4.f * (v - vmin) / dv;
581 }
582 else if (v < (vmin + 0.5f * dv))
583 {
584 c.r = 0.f;
585 c.b = 1.f + 4.f * (vmin + 0.25f * dv - v) / dv;
586 }
587 else if (v < (vmin + 0.75f * dv))
588 {
589 c.r = 4.f * (v - vmin - 0.5f * dv) / dv;
590 c.b = 0.f;
591 }
592 else
593 {
594 c.g = 1.f + 4.f * (vmin + 0.75f * dv - v) / dv;
595 c.b = 0.f;
596 }
597
598 return(c);
599}
600
601//----------------------------------------------------------------------
602nv::index::IColormap* Create_path::create_colormap(nv::index::IScene* scene, bool use_transparency) const
603{
604 const mi::Float32 MIN_TRANS = 0.2f;
605 const mi::Float32 MAX_TRANS = 0.9f;
606
607 nv::index::IColormap* colormap = scene->create_attribute<nv::index::IColormap>();
608 check_success(colormap != 0);
609 std::vector<mi::math::Color_struct> colormap_entries;
610 colormap_entries.resize(256);
611 for(mi::Uint32 i=0; i<256; ++i)
612 {
613 colormap_entries[i] = jetmap((static_cast<mi::Float32>(i)+0.5f)/256.f, 0.f, 1.f);
614 if(use_transparency)
615 {
616 mi::Float32 t = (static_cast<mi::Float32>(i) + 0.5f)/256.f;
617 colormap_entries[i].a = MIN_TRANS + (MAX_TRANS - MIN_TRANS)*t;
618 }
619 }
620
621 // Set the the colormap values.
622 colormap->set_colormap(&colormap_entries[0], colormap_entries.size());
623 return colormap;
624}
625
626//----------------------------------------------------------------------
627bool Create_path::create_scene(
628 nv::index::IScene* scene_edit,
629 std::vector<mi::neuraylib::Tag>& path_tags,
630 std::map< mi::neuraylib::Tag, Test_tag_info, Tag_comp >& test_tag_info_map,
631 mi::neuraylib::IDice_transaction* dice_transaction) const
632{
633 check_success(dice_transaction != 0);
634 check_success(scene_edit != 0);
635
636 {
637 // Set the default light source
638 mi::base::Handle<nv::index::IDirectional_light> light_global(
639 scene_edit->create_attribute<nv::index::IDirectional_light>());
640 check_success(light_global.is_valid_interface());
641 light_global->set_direction(mi::math::Vector<mi::Float32, 3>(0.5f, 0.f, 1.f));
642 const mi::neuraylib::Tag light_global_tag = dice_transaction->store_for_reference_counting(light_global.get());
643 check_success(light_global_tag.is_valid());
644 scene_edit->append(light_global_tag, dice_transaction);
645
646 // Set the default material
647 mi::base::Handle<nv::index::IPhong_gl> phong_1(scene_edit->create_attribute<nv::index::IPhong_gl>());
648 check_success(phong_1.is_valid_interface());
649 if(m_path_test_params.npr_mode)
650 {
651 phong_1->set_ambient(mi::math::Color(0.75f, 0.75f, 0.75f, 1.0f));
652 phong_1->set_diffuse(mi::math::Color(0.0f, 0.0f, 0.0f, 1.0f));
653 phong_1->set_specular(mi::math::Color(0.0f, 0.0f, 0.0f, 1.0f));
654 phong_1->set_shininess(0);
655 }
656 else
657 {
658 phong_1->set_ambient(mi::math::Color(0.15f, 0.15f, 0.15f, 1.0f));
659 phong_1->set_diffuse(mi::math::Color(0.95f, 0.95f, 0.95f, 1.0f));
660 phong_1->set_specular(mi::math::Color(0.4f, 0.4f, 0.4f, 1.0f));
661 phong_1->set_shininess(85);
662 }
663 const mi::neuraylib::Tag phong_1_tag = dice_transaction->store_for_reference_counting(phong_1.get());
664 check_success(phong_1_tag.is_valid());
665 scene_edit->append(phong_1_tag, dice_transaction);
666
667 // The the colormap to demonstrate color index color mapping.
668 mi::base::Handle<nv::index::IColormap> colormap(create_colormap(scene_edit, m_path_test_params.test_transparency));
669 check_success(colormap.is_valid_interface());
670 const mi::neuraylib::Tag colormap_tag = dice_transaction->store_for_reference_counting(colormap.get());
671 check_success(colormap_tag.is_valid());
672 scene_edit->append(colormap_tag, dice_transaction);
673 }
674
675 mi::math::Bbox< mi::Float32, 3 > path_bbox;
676
677 {
678 const mi::Uint32 num_points = m_path_test_params.num_points;
679
680 // get the color source style from parameters
681 nv::index::IPath_style::Color_source color_source;
682 if(m_path_test_params.use_colormap && m_path_test_params.use_rgba)
683 color_source = nv::index::IPath_style::COLOR_SOURCE_BOTH;
684 else if(m_path_test_params.use_colormap)
685 color_source = nv::index::IPath_style::COLOR_SOURCE_COLORMAP_ONLY;
686 else if(m_path_test_params.use_rgba)
687 color_source = nv::index::IPath_style::COLOR_SOURCE_RGBA_ONLY;
688 else
689 color_source = nv::index::IPath_style::COLOR_SOURCE_NONE;
690
691
692 //create rgba array. A grayscale color scale with a "V" shape
693 std::vector<mi::math::Color_struct> colors;
694 colors.resize(num_points);
695 for(mi::Uint32 i=0; i<num_points; i++)
696 {
697 mi::Float32 g = (static_cast<mi::Float32>(i) + 0.5f)/static_cast<mi::Float32>(num_points);
698 mi::Float32 f = fabsf(2.0f*g - 1.0f);
699 colors[i].r = g;
700 colors[i].g = 1.f - f;
701 colors[i].b = 1.f - f;
702 colors[i].a = 1.f;
703 }
704
705 // Set up the transformation matrix, define a translation and create and store the scene group
706 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(1.f);
707 transform_mat.translate(mi::math::Vector<mi::Float32, 3>(120.f, 0.f, 0.f));
708 mi::base::Handle<nv::index::ITransformed_scene_group> group_node(
709 scene_edit->create_scene_group<nv::index::ITransformed_scene_group>());
710 check_success(group_node.is_valid_interface());
711 group_node->set_transform(transform_mat);
712
713 // set up points
714 std::vector< mi::math::Vector_struct<mi::Float32, 3> > points;
715 points.resize(num_points);
716 for(mi::Uint32 i=0; i<num_points; i++)
717 {
718 points[i].y = ((static_cast<mi::Float32>(i) + 0.5f)/static_cast<mi::Float32>(num_points))*6.f;
719 points[i].x = evaluate_path(points[i].y);
720 points[i].z = 1.f;
721
722 path_bbox.insert(points[i]);
723
724 points[i].x = points[i].x*100.f - 80.f;
725 points[i].y = points[i].y*100.f + 10.f;
726 points[i].z *= 100.f;
727
728 path_bbox.insert(points[i]);
729 }
730
731 // set up colormap ids
732 std::vector<mi::Uint32> colormap_ids;
733 colormap_ids.resize(num_points);
734 for(mi::Uint32 i=0; i<num_points; i++){
735 colormap_ids[i] = (mi::Uint32) (255.f*((static_cast<mi::Float32>(i)+0.5f)/
736 static_cast<mi::Float32>(num_points)));
737 }
738
739 {
740 //create a path style with linear interpolation
741 mi::base::Handle<nv::index::IPath_style> path_style1(scene_edit->create_attribute<nv::index::IPath_style>());
742 check_success(path_style1.is_valid_interface());
743 path_style1->set_interpolation(nv::index::IPath_style::INTERPOLATION_LINEAR);
744 path_style1->set_color_source(color_source);
745 path_style1->set_upsampling(m_path_test_params.upsampling, m_path_test_params.up_factor, m_path_test_params.up_tension);
746 const mi::neuraylib::Tag path_style1_tag = dice_transaction->store_for_reference_counting(path_style1.get());
747 check_success(path_style1_tag.is_valid());
748 group_node->append(path_style1_tag, dice_transaction);
749
750 mi::base::Handle<nv::index::IPath_3D> path1(scene_edit->create_shape<nv::index::IPath_3D>());
751 check_success(path1.is_valid_interface());
752
753 // set radius
754 path1->set_radius(15.f);
755
756 // set points
757 path1->set_points(&points[0], num_points);
758
759 // set colormap ids
760 path1->set_color_map_indexes(&colormap_ids[0], num_points);
761 path1->set_colors(&colors[0], num_points);
762
763 // append path to the group node
764 const mi::neuraylib::Tag path1_tag = dice_transaction->store_for_reference_counting(path1.get());
765 check_success(path1_tag.is_valid());
766 group_node->append(path1_tag, dice_transaction);
767
768 path_tags.push_back(path1_tag);
769 test_tag_info_map[path1_tag] = Test_tag_info("IPath_3D", num_points); // for test purpose
770 }
771
772 {
773 //create a path style with segment interpolation
774 mi::base::Handle<nv::index::IPath_style> path_style2(scene_edit->create_attribute<nv::index::IPath_style>());
775 check_success(path_style2.is_valid_interface());
776 path_style2->set_interpolation(nv::index::IPath_style::INTERPOLATION_SEGMENT);
777 path_style2->set_color_source(color_source);
778 path_style2->set_upsampling(m_path_test_params.upsampling, m_path_test_params.up_factor, m_path_test_params.up_tension);
779 const mi::neuraylib::Tag path2_style_tag =
780 dice_transaction->store_for_reference_counting(path_style2.get());
781 check_success(path2_style_tag.is_valid());
782 group_node->append(path2_style_tag, dice_transaction);
783
784 mi::base::Handle<nv::index::IPath_3D> path2(scene_edit->create_shape<nv::index::IPath_3D>());
785 check_success(path2.is_valid_interface());
786
787 // set radius
788 path2->set_radius(12.0f);
789
790 // set points
791 for(mi::Uint32 i=0; i<num_points; i++){
792 points[i].x += 200;
793 path_bbox.insert(points[i]);
794 }
795
796 path2->set_points(&points[0], num_points);
797
798 // set colormap ids
799 path2->set_color_map_indexes(&colormap_ids[0], num_points);
800 path2->set_colors(&colors[0], num_points);
801
802 // append path to the group node
803 const mi::neuraylib::Tag path2_tag = dice_transaction->store_for_reference_counting(path2.get());
804 check_success(path2_tag.is_valid());
805 group_node->append(path2_tag, dice_transaction);
806
807 path_tags.push_back(path2_tag);
808 test_tag_info_map[path2_tag] = Test_tag_info("IPath_3D", num_points); // for test purpose
809 }
810
811 {
812 //create a path style with nearest interpolation
813 mi::base::Handle<nv::index::IPath_style> path_style3(scene_edit->create_attribute<nv::index::IPath_style>());
814 check_success(path_style3.is_valid_interface());
815 path_style3->set_interpolation(nv::index::IPath_style::INTERPOLATION_NEAREST);
816 path_style3->set_color_source(color_source);
817 path_style3->set_upsampling(m_path_test_params.upsampling, m_path_test_params.up_factor, m_path_test_params.up_tension);
818 const mi::neuraylib::Tag path3_style_tag = dice_transaction->store_for_reference_counting(path_style3.get());
819 check_success(path3_style_tag.is_valid());
820 group_node->append(path3_style_tag, dice_transaction);
821
822 mi::base::Handle<nv::index::IPath_3D> path3(scene_edit->create_shape<nv::index::IPath_3D>());
823 check_success(path3.is_valid_interface());
824
825 // set radius
826 path3->set_radius(7.0f);
827
828 // set points
829 for(mi::Uint32 i=0; i<num_points; i++){
830 points[i].x += 200;
831 path_bbox.insert(points[i]);
832 }
833
834 path3->set_points(&points[0], num_points);
835
836 // set colormap ids
837 path3->set_color_map_indexes(&colormap_ids[0], num_points);
838 path3->set_colors(&colors[0], num_points);
839
840 // append path to the group node
841 const mi::neuraylib::Tag path3_tag = dice_transaction->store_for_reference_counting(path3.get());
842 check_success(path3_tag.is_valid());
843 group_node->append(path3_tag, dice_transaction);
844
845 path_tags.push_back(path3_tag);
846 test_tag_info_map[path3_tag] = Test_tag_info("IPath_3D", num_points); // for test purpose
847 }
848
849 if(m_path_test_params.test_transparency)
850 {
851 // background plane
852 mi::math::Vector<mi::Float32, 3> plane_point(-500.f, -100.f, 150.0f);
853 mi::math::Vector<mi::Float32, 3> plane_normal(0.f, 0.f, 1.f);
854 mi::math::Vector<mi::Float32, 3> plane_up(0.f, 1.f, 0.f);
855 mi::math::Vector<mi::Float32, 2> plane_extent(1200.0f, 800.0f);
856
857 mi::base::Handle<nv::index::ITexture_filter_mode> tex_filter(
858 scene_edit->create_attribute<nv::index::ITexture_filter_mode_nearest_neighbor>());
859 check_success(tex_filter.is_valid_interface());
860 mi::neuraylib::Tag tex_filter_tag = dice_transaction->store_for_reference_counting(tex_filter.get());
861 check_success(tex_filter_tag.is_valid());
862 group_node->append(tex_filter_tag, dice_transaction);
863
864 // Access an application layer component that provides some sample techniques such as the checkerboard for 2d surfaces:
865 mi::base::Handle<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing> processing(
866 get_application_layer_interface()->get_api_component<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing>());
867 check_success(processing.is_valid_interface());
868 // Create a checkerboard technique and add it to the scene. For more details on how to implement the checkerboard, please review the provided
869 // source that was shipped with the application layer component 'nv::index::app::data_analysis_and_processing::IData_analysis_and_processing'.
870 mi::base::Handle<nv::index::IDistributed_compute_technique> mapping(
871 processing->get_sample_tool_set()->create_checker_board_2d_technique(
872 plane_extent,
873 nv::index::IDistributed_compute_destination_buffer_2d_texture::FORMAT_RGBA_FLOAT32,
874 mi::math::Color(0.9f, 0.2f, 0.15f, 0.7f),
875 mi::math::Color(0.2f, 0.2f, 0.8f, 1.0f)));
876 check_success(mapping.is_valid_interface());
877
878 mi::neuraylib::Tag mapping_tag = dice_transaction->store_for_reference_counting(mapping.get());
879 check_success(mapping_tag.is_valid());
880
881 group_node->append(mapping_tag, dice_transaction);
882
883 mi::base::Handle<nv::index::IPlane> plane(scene_edit->create_shape<nv::index::IPlane>());
884 check_success(plane.is_valid_interface());
885 plane->set_point(plane_point);
886 plane->set_normal(plane_normal);
887 plane->set_up(plane_up);
888 plane->set_extent(plane_extent);
889
890 mi::neuraylib::Tag plane_tag = dice_transaction->store_for_reference_counting(plane.get());
891 check_success(plane_tag.is_valid());
892 group_node->append(plane_tag, dice_transaction);
893
894 path_tags.push_back(plane_tag);
895 test_tag_info_map[plane_tag] = Test_tag_info("IPlane", -1); // for test purpose
896 }
897
898 const mi::neuraylib::Tag group_node_tag = dice_transaction->store_for_reference_counting(group_node.get());
899 check_success(group_node_tag.is_valid());
900 scene_edit->append(group_node_tag, dice_transaction);
901
902 INFO_LOG << "Bounding box of the vertices that create the paths: " << path_bbox;
903 }
904
905 return true;
906}
907
908//----------------------------------------------------------------------
909void Create_path::setup_camera(nv::index::IPerspective_camera* cam) const
910{
911 check_success(cam != 0);
912
913 // Set the camera parameters to see the whole scene
914 const mi::math::Vector< mi::Float32, 3 > from( 234.0f, 604.0f, 500.0f);
915 const mi::math::Vector< mi::Float32, 3 > to ( 255.0f, 255.0f, -255.0f);
916 const mi::math::Vector< mi::Float32, 3 > up ( 0.0f, 1.0f, 0.0f);
917 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
918 viewdir.normalize();
919
920 cam->set(from, viewdir, up);
921 cam->set_aperture(0.033f);
922 cam->set_aspect(1.0f);
923 cam->set_focal(0.03f);
924 cam->set_clip_min(10.0f);
925 cam->set_clip_max(5000.0f);
926}
927
928//----------------------------------------------------------------------
929void Create_path::setup_extreme_transformed_camera(nv::index::IPerspective_camera* cam) const
930{
931 check_success(cam != 0);
932
933 // *** Camera:
934 // index::camera::eye_point = 1808409.125 9981818 10948.5126953125
935 // index::camera::view_direction = (1808409.125 9981818 -1500) - eye_point
936 // index::camera::up_direction = 0 1 0
937 // index::camera::aspect = 1.7152034261242
938 // index::camera::aperture = 0.033
939 // index::camera::focal = 0.03
940 // index::camera::clip_min = 124.485130310059
941 // index::camera::clip_max = 17585.455078125
942 // index::canvas_resolution = 1602 934
943
944 // Adjusted the camera position for p = 23+1.
945 mi::math::Vector< mi::Float32, 3 > const from( 1805060.125f + 8192.0f, 9978520.0f + 16384.0f, 16384.0f);
946 mi::math::Vector< mi::Float32, 3 > const to ( 1805060.125f + 8192.0f, 9978520.0f + 8292.0f, -256.0f);
947 mi::math::Vector< mi::Float32, 3 > const up ( 0.0f, 1.0f, 0.0f);
948 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
949 viewdir.normalize();
950
951 cam->set(from, viewdir, up);
952 cam->set_aperture(0.033f);
953 cam->set_aspect(1.71520f); // not 1.7152034261242f, see IEEE754
954 cam->set_focal(0.03f);
955 cam->set_clip_min(124.485f); // not 124.485130310059f, see IEEE754
956 cam->set_clip_max(17585.6f); // not 17585.55078125f, see IEEE754
957
958 INFO_LOG << "A camera set up using a large matrix.";
959}
960
961//----------------------------------------------------------------------
962mi::math::Matrix<mi::Float32, 4, 4> Create_path::get_extreme_transformed_matrix() const
963{
964 // transform =
965 // [ 20.6100006103516 0 0 1805060
966 // 0 20.6100006103516 0 9978520
967 // 0 0 -4 0
968 // 0 0 0 1 ]
969
970 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(
971 20.61f, 0.0f, 0.0f, 0.0f,
972 0.0f, 20.61f, 0.0f, 0.0f,
973 0.0f, 0.0f, -4.0f, 0.0f,
974 1805060.0f, 9978520.0f, 0.0f, 1.0f
975 );
976 return transform_mat;
977}
978
979//----------------------------------------------------------------------
980nv::index::IFrame_results* Create_path::render_frame(const std::string& output_fname) const
981{
982 check_success(m_index_rendering.is_valid_interface());
983
984 // set output filename, empty string is valid
985 m_image_file_canvas->set_rgba_file_name(output_fname.c_str());
986
987 check_success(m_session_tag.is_valid());
988
989 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
990 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
991 check_success(dice_transaction.is_valid_interface());
992
993 m_index_session->update(m_session_tag, dice_transaction.get());
994
995 mi::base::Handle<nv::index::IFrame_results> frame_results(
996 m_index_rendering->render(
997 m_session_tag,
998 m_image_file_canvas.get(),
999 dice_transaction.get()));
1000 check_success(frame_results.is_valid_interface());
1001
1002 dice_transaction->commit();
1003
1004 frame_results->retain();
1005 return frame_results.get();
1006}
1007
1008//----------------------------------------------------------------------
1009int main(int argc, const char* argv[])
1010{
1011 nv::index::app::String_dict sdict;
1012 sdict.insert("dice::verbose", "3"); // log level
1013 sdict.insert("outfname", "frame_create_path"); // output file base name
1014 sdict.insert("verify_image_fname", ""); // for unit test
1015 sdict.insert("unittest", "0"); // default mode
1016 sdict.insert("supersampling", "0"); // disable supersampling (default)
1017 sdict.insert("num_samples", "40"); // 40 samples (default)
1018 sdict.insert("use_colormap", "1"); // use color map (default)
1019 sdict.insert("use_rgba", "0"); // don't use rgba array (default)
1020 sdict.insert("npr_mode", "0"); // don't use npr mode (default)
1021 sdict.insert("test_transparency", "0"); // don't test transparency (default)
1022 sdict.insert("upsampling", "0"); // don't use upsampling (default)
1023 sdict.insert("up_factor", "2"); // 2x (default)
1024 sdict.insert("up_tension", "0.0"); // 0.0 (default)
1025 sdict.insert("is_large_translate", "0"); // large translation mode (default 0)
1026 sdict.insert("is_dump_comparison_image_when_failed", "1"); // default: dump images when failed.
1027 sdict.insert("is_call_from_test", "0"); // default: not call from make check.
1028
1029 // DiCE settings
1030 sdict.insert("dice::network::mode", "OFF");
1031
1032 // index setting
1033 sdict.insert("index::config::set_monitor_performance_values", "true");
1034 sdict.insert("index::service", "rendering_and_compositing");
1035 sdict.insert("index::cuda_debug_checks", "false");
1036
1037 // application_layer component loading
1038 sdict.insert("index::app::components::application_layer::component_name_list",
1039 "canvas_infrastructure image io data_analysis_and_processing");
1040
1041 // Initialize application
1042 Create_path create_path;
1043 create_path.initialize(argc, argv, sdict);
1044 check_success(create_path.is_initialized());
1045
1046 // launch the application. creating the scene and rendering.
1047 const mi::Sint32 exit_code = create_path.launch();
1048 INFO_LOG << "Shutting down ...";
1049
1050 return exit_code;
1051}
virtual ~Create_path()
virtual bool evaluate_options(nv::index::app::String_dict &sdict) CPP11_OVERRIDE
mi::Sint32 launch()
virtual bool initialize_networking(mi::neuraylib::INetwork_configuration *network_configuration, nv::index::app::String_dict &options) CPP11_OVERRIDE
bool operator()(const mi::neuraylib::Tag &lhs, const mi::neuraylib::Tag &rhs) const
Definition: create_path.cpp:87
std::string m_assoc_type
Definition: create_path.cpp:78
mi::Sint32 m_num_points
Definition: create_path.cpp:80
Test_tag_info(const std::string &type_name, mi::Sint32 num_points)
Definition: create_path.cpp:49
Test_tag_info & operator=(const Test_tag_info &rhs)
Definition: create_path.cpp:67
Test_tag_info(const Test_tag_info &tti)
Definition: create_path.cpp:61
int main(int argc, const char *argv[])
#define check_success(expr)