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