NVIDIA Index example code nvidia_logo_transpbg.gif Up
create_synthetic_heightfield.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/iconfig_settings.h>
14#include <nv/index/iindex.h>
15#include <nv/index/ilight.h>
16#include <nv/index/imaterial.h>
17#include <nv/index/iscene.h>
18#include <nv/index/isession.h>
19#include <nv/index/itexture_filter_mode.h>
20
21// Application layer component
22#include <nv/index/app/idata_analysis_and_processing.h>
23#include <nv/index/app/index_connect.h>
24#include <nv/index/app/string_dict.h>
25
26#include "utility/canvas_utility.h"
27
28#include <sstream>
29#include <iostream>
30
31//----------------------------------------------------------------------
33 public nv::index::app::Index_connect
34{
35public:
37 :
38 Index_connect()
39 {
40 // INFO_LOG << "DEBUG: Create_synthetic_heightfield() ctor";
41 }
42
44 {
45 // Note: Index_connect::~Index_connect() will be called after here.
46 // INFO_LOG << "DEBUG: ~Create_synthetic_heightfield() dtor";
47 }
48
49 // launch application
50 mi::Sint32 launch();
51
52protected:
53 virtual bool evaluate_options(nv::index::app::String_dict& sdict) CPP11_OVERRIDE;
54 // override
56 mi::neuraylib::INetwork_configuration* network_configuration,
57 nv::index::app::String_dict& options) CPP11_OVERRIDE
58 {
59 check_success(network_configuration != 0);
60
61 check_success(options.is_defined("unittest"));
62 const bool is_unittest = nv::index::app::get_bool(options.get("unittest"));
63 if (is_unittest)
64 {
65 info_cout("NETWORK: disabled networking mode.", options);
66 network_configuration->set_mode(mi::neuraylib::INetwork_configuration::MODE_OFF);
67 return true;
68 }
69
70 return initialize_networking_as_default_udp(network_configuration, options);
71 }
72
73private:
74 // Setup camera to see this example scene
75 // \param[in] cam a camera
76 void setup_camera(nv::index::IPerspective_camera* cam) const;
77
78 // setup a far away camera for a extreme transformation handling test
79 //
80 // This value is based on Bugzilla 11567
81 // Attachment: Two complete screen dump with 188853_8578 build case
82 //
83 // \param[in] cam a camera
84 void setup_extreme_transformed_camera(nv::index::IPerspective_camera* cam) const;
85
86 // setup a large scene transform for the extreme
87 // transformation handling test
88 //
89 // This value is based on Bugzilla 11567
90 // Attachment: Two complete screen dump with 188853_8578 build case
91 mi::math::Matrix<mi::Float32, 4, 4> get_extreme_transformed_matrix() const;
92
93 // render a frame
94 //
95 // \param[in] output_fname output rendering image filename
96 // \return performance values
97 nv::index::IFrame_results* render_frame(const std::string& output_fname) const;
98
99 // This session tag
100 mi::neuraylib::Tag m_session_tag;
101 // NVIDIA IndeX cluster configuration
102 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
103 // Application layer image file canvas (a render target)
104 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
105 // Create_icons options
106 std::string m_outfname;
107 bool m_is_unittest;
108 std::string m_verify_image_fname;
109 bool m_seeds;
110 bool m_depth_buffer;
111 bool m_supersampling;
112 std::string m_texture;
113 bool m_use_texture;
114 bool m_is_large_translate;
115};
116
117//----------------------------------------------------------------------
119{
120 mi::Sint32 exit_code = 0;
121 {
122 m_cluster_configuration = get_index_interface()->get_api_component<nv::index::ICluster_configuration>();
123 check_success(m_cluster_configuration.is_valid_interface());
124
125 // create image canvas in application_layer
126 m_image_file_canvas = create_image_file_canvas(get_application_layer_interface());
127 check_success(m_image_file_canvas.is_valid_interface());
128
129 // Verifying that local host has joined. This may fail when there is a license problem.
130 check_success(is_local_host_joined(m_cluster_configuration.get()));
131
132 {
133 // Create our DiCE transaction
134 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
135 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
136 check_success(dice_transaction.is_valid_interface());
137
138 // Create an IndeX session.
139 m_session_tag = m_index_session->create_session(dice_transaction.get());
140 check_success(m_session_tag.is_valid());
141 {
142 // Change the global configuration.
143 {
144 mi::base::Handle<const nv::index::ISession> the_session(
145 dice_transaction->access<const nv::index::ISession>(m_session_tag));
146 check_success(the_session.is_valid_interface());
147
148 mi::base::Handle<nv::index::IConfig_settings> config_settings(
149 dice_transaction->edit<nv::index::IConfig_settings>(the_session->get_config()));
150 check_success(config_settings.is_valid_interface());
151
152 // Enable supersampling.
153 if (m_supersampling)
154 {
155 INFO_LOG << "Enable supersampling.";
156 config_settings->set_rendering_samples(8);
157 }
158 }
159
160 // Create a scene that contains a synthetically generated heightfield.
161 {
162 // Access the session instance from the database.
163 mi::base::Handle<const nv::index::ISession> session(
164 dice_transaction->access<const nv::index::ISession>(m_session_tag));
165 check_success(session.is_valid_interface());
166
167 // Access (edit mode) the scene instance from the database.
168 mi::base::Handle<nv::index::IScene> scene_edit(
169 dice_transaction->edit<nv::index::IScene>(session->get_scene()));
170 check_success(scene_edit.is_valid_interface());
171
172 // Create static group node for large data
173 mi::base::Handle<nv::index::IStatic_scene_group> static_group_node(
174 scene_edit->create_scene_group<nv::index::IStatic_scene_group>());
175 check_success(static_group_node.is_valid_interface());
176
177 // Details for creating a synthetic heightfield.
178 const mi::math::Vector<mi::Uint32, 2> heightfield_size(500, 500);
179
180 nv::index::app::String_dict heightfield_opt;
181 heightfield_opt.insert("args::type", "heightfield");
182 heightfield_opt.insert("args::importer", "nv::index::plugin::legacy_importer.Synthetic_heightfield_generator");
183 heightfield_opt.insert("args::synthetic_type", "i");
184 heightfield_opt.insert("args::size", "500 500");
185 heightfield_opt.insert("args::range", "0.1 1000");
186 nv::index::IDistributed_data_import_callback* importer_callback =
187 get_importer_from_application_layer(
188 get_application_layer_interface(),
189 "nv::index::plugin::legacy_importer.Synthetic_heightfield_generator",
190 heightfield_opt);
191
192 // Create heightfield scene element and add it to the scene
193 const mi::Float32 rotate_k = 0.0f;
194 const mi::math::Vector<mi::Float32, 3> translate(0.0f, 0.0f, 0.0f);
195 const mi::math::Vector<mi::Float32, 3> scale(1.0f, 1.0f, 1.0f);
196 const mi::math::Vector<mi::Float32, 2> elevation_range(50.0f, 256.0f);
197
198 mi::base::Handle<nv::index::IRegular_heightfield> heightfield_scene_element(
199 scene_edit->create_regular_heightfield(
200 scale, rotate_k, translate,
201 heightfield_size,
202 elevation_range,
203 importer_callback,
204 dice_transaction.get()));
205 check_success(heightfield_scene_element.is_valid_interface());
206
207 const mi::math::Bbox<mi::Float32, 3> heightfield_bbox = heightfield_scene_element->get_IJK_bounding_box();
208
209 // Set the name of the heightfield scene element
210 const std::string heightfield_name = "synthetic heightfield";
211 heightfield_scene_element->set_name(heightfield_name.c_str());
212
213 // Render the heightfield with additional seed points and lines
214 if (m_seeds)
215 {
216 // Add a line
217 {
218 std::vector<mi::math::Vector<mi::Float32, 3> > seed_line;
219 seed_line.push_back(mi::math::Vector<mi::Float32, 3>(400.f, 100.f, 100.f));
220 seed_line.push_back(mi::math::Vector<mi::Float32, 3>(500.f, 100.f, 200.f));
221 check_success(!seed_line.empty());
222 heightfield_scene_element->add_seed_line(&seed_line[0], seed_line.size());
223 }
224
225 // Add a few points
226 {
227 std::vector<mi::math::Vector<mi::Float32, 3> > seed_points;
228 for (int i = 0; i < 100; ++i)
229 {
230 seed_points.push_back(mi::math::Vector<mi::Float32, 3>(
231 360.0f, static_cast<mi::Float32>(i) * 10.0f, 100.0f));
232 }
233 check_success(!seed_points.empty());
234 heightfield_scene_element->add_seed_points(&seed_points[0], seed_points.size());
235 }
236 //
237 // Enable the rendering of seed points and lines by adding attributes to the scene
238 //
239
240 // Settings for seed points
241 {
242 mi::base::Handle<nv::index::IHeightfield_geometry_settings> point_settings(
243 scene_edit->create_attribute<nv::index::IHeightfield_geometry_settings>());
244 check_success(point_settings.is_valid_interface());
245 // Apply this attribute only to seed points
246 point_settings->set_type_mask(nv::index::IHeightfield_geometry_settings::TYPE_SEED_POINTS);
247 // Use a fixed color with no lighting
248 point_settings->set_color_mode(nv::index::IHeightfield_geometry_settings::MODE_FIXED);
249 // Blue points please
250 point_settings->set_color(mi::math::Color(0.f, 0.f, 1.f));
251 // Enable rendering of seed points
252 point_settings->set_visible(true);
253
254 const mi::neuraylib::Tag point_settings_tag
255 = dice_transaction->store_for_reference_counting(point_settings.get());
256 check_success(point_settings_tag.is_valid());
257 static_group_node->append(point_settings_tag, dice_transaction.get());
258 }
259
260 // Settings for seed lines
261 {
262 mi::base::Handle<nv::index::IHeightfield_geometry_settings> line_settings(
263 scene_edit->create_attribute<nv::index::IHeightfield_geometry_settings>());
264 check_success(line_settings.is_valid_interface());
265 // Apply this attribute only to seed lines
266 line_settings->set_type_mask(nv::index::IHeightfield_geometry_settings::TYPE_SEED_LINES);
267 // Use a fixed color with no lighting
268 line_settings->set_color_mode(nv::index::IHeightfield_geometry_settings::MODE_FIXED);
269 // Red lines please
270 line_settings->set_color(mi::math::Color(1.f, 0.f, 0.f));
271 // Enable rendering of seed lines
272 line_settings->set_visible(true);
273
274 const mi::neuraylib::Tag line_settings_tag
275 = dice_transaction->store_for_reference_counting(line_settings.get());
276 check_success(line_settings_tag.is_valid());
277 static_group_node->append(line_settings_tag, dice_transaction.get());
278 }
279 }
280
281 // ... and store the heightfield scene element in the distributed database ...
282 const mi::neuraylib::Tag heightfield_tag =
283 dice_transaction->store_for_reference_counting(heightfield_scene_element.get());
284 check_success(heightfield_tag.is_valid());
285
286 // Add a light and a material to the static group node
287 {
288 // Add a light
289 mi::base::Handle<nv::index::IDirectional_headlight> headlight(
290 scene_edit->create_attribute<nv::index::IDirectional_headlight>());
291 check_success(headlight.is_valid_interface());
292 const mi::math::Color color_intensity(1.0f, 1.0f, 1.0f, 1.0f);
293 headlight->set_intensity(color_intensity);
294 headlight->set_direction(mi::math::Vector<mi::Float32, 3>(1.0f, -1.0f, -1.0f));
295 const mi::neuraylib::Tag headlight_tag = dice_transaction->store_for_reference_counting(headlight.get());
296 check_success(headlight_tag.is_valid());
297 static_group_node->append(headlight_tag, dice_transaction.get());
298
299 // Material for the heightfield
300 mi::base::Handle<nv::index::IPhong_gl> phong_1(scene_edit->create_attribute<nv::index::IPhong_gl>());
301 check_success(phong_1.is_valid_interface());
302
303 if (m_use_texture)
304 {
305 // Use just ambient white with texture
306 phong_1->set_ambient(mi::math::Color(1.f));
307 phong_1->set_diffuse(mi::math::Color(0.f));
308 phong_1->set_specular(mi::math::Color(0.f));
309 }
310 else
311 {
312 // Define a more interesting greenish material
313 phong_1->set_ambient(mi::math::Color(0.f, 0.3f, 0.0f, 0.3f));
314 phong_1->set_diffuse(mi::math::Color(0.f, 0.8f, 0.2f, 0.3f));
315 phong_1->set_specular(mi::math::Color(0.6f));
316 phong_1->set_shininess(100.f);
317 }
318
319 const mi::neuraylib::Tag phong_1_tag
320 = dice_transaction->store_for_reference_counting(phong_1.get());
321 check_success(phong_1_tag.is_valid());
322 static_group_node->append(phong_1_tag, dice_transaction.get());
323 }
324
325 // Optionally map a computed texture onto the heightfield
326 if (m_use_texture)
327 {
328 // Mandelbrot texture
329 if (m_texture == "mandelbrot")
330 {
331 mi::base::Handle<nv::index::ITexture_filter_mode> tex_filter(
332 scene_edit->create_attribute<nv::index::ITexture_filter_mode_nearest_neighbor>());
333 check_success(tex_filter.is_valid_interface());
334 mi::neuraylib::Tag tex_filter_tag = dice_transaction->store_for_reference_counting(tex_filter.get());
335 check_success(tex_filter_tag.is_valid());
336 static_group_node->append(tex_filter_tag, dice_transaction.get());
337
338 // Create the computed texture, with a size fitting the heightfield
339 mi::base::Handle<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing> processing(
340 get_application_layer_interface()->get_api_component<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing>());
341 check_success(processing.is_valid_interface());
342 // Create a mandelbrot technique and add it to the scene. For more details on how to implement the checkerboard, please review the provided
343 // source that was shipped with the application layer component 'nv::index::app::data_analysis_and_processing::IData_analysis_and_processing'.
344 mi::base::Handle<nv::index::IDistributed_compute_technique> mapping(
345 processing->get_sample_tool_set()->create_mandelbrot_2d_technique(mi::math::Vector<mi::Float32, 2>(1250.f, 680.f)));
346
347 // Add the mapping to the scene before the heightfield
348 mi::neuraylib::Tag mapping_tag = dice_transaction->store_for_reference_counting(mapping.get());
349 check_success(mapping_tag.is_valid());
350 static_group_node->append(mapping_tag, dice_transaction.get());
351 }
352 // Map height values in the heightfield to colors
353 else if (m_texture == "height_color")
354 {
355 // Create the computed texture, passing the height range of the heightfield
356 const mi::math::Vector<mi::Float32, 2> height_range(
357 heightfield_bbox.min.z, heightfield_bbox.max.z);
358
359 mi::base::Handle<nv::index::ITexture_filter_mode> tex_filter(
360 scene_edit->create_attribute<nv::index::ITexture_filter_mode_nearest_neighbor>());
361 check_success(tex_filter.is_valid_interface());
362 mi::neuraylib::Tag tex_filter_tag = dice_transaction->store_for_reference_counting(tex_filter.get());
363 check_success(tex_filter_tag.is_valid());
364 static_group_node->append(tex_filter_tag, dice_transaction.get());
365
366 // Create the computed texture, with a size fitting the heightfield
367 mi::base::Handle<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing> processing(
368 get_application_layer_interface()->get_api_component<nv::index::app::data_analysis_and_processing::IData_analysis_and_processing>());
369 check_success(processing.is_valid_interface());
370 // Create a mandelbrot technique and add it to the scene. For more details on how to implement the checkerboard, please review the provided
371 // source that was shipped with the application layer component 'nv::index::app::data_analysis_and_processing::IData_analysis_and_processing'.
372 const mi::math::Color color0(0.f, 1.f, 0.f, 1.f); // green
373 const mi::math::Color color1(1.f, 0.f, 0.f, 1.f); // red
374 mi::base::Handle<nv::index::IDistributed_compute_technique> mapping(
375 processing->get_sample_tool_set()->create_color_encoded_elevation_technique(height_range, color0, color1));
376 check_success(mapping.is_valid_interface());
377
378 // Add the mapping to the scene before the heightfield
379 mi::neuraylib::Tag mapping_tag = dice_transaction->store_for_reference_counting(mapping.get());
380 static_group_node->append(mapping_tag, dice_transaction.get());
381 }
382 else
383 {
384 ERROR_LOG << "Unknown texture mode '" << m_texture << "'";
385 check_success(false);
386 }
387 }
388
389 // Append the heightfield to the scene group
390 static_group_node->append(heightfield_tag, dice_transaction.get());
391 mi::neuraylib::Tag static_group_node_tag =
392 dice_transaction->store_for_reference_counting(static_group_node.get());
393 check_success(static_group_node_tag.is_valid());
394
395 // Append the static scene group to the scene.
396 scene_edit->append(static_group_node_tag, dice_transaction.get());
397
398 std::stringstream sstr;
399 sstr << "Created a synthetic heightfield: size = "
400 << heightfield_size << ", tag = " << heightfield_tag.id;
401 INFO_LOG << sstr.str();
402
403 // Create a camera and adjust the camera parameter.
404 mi::base::Handle< nv::index::IPerspective_camera > cam(
405 scene_edit->create_camera<nv::index::IPerspective_camera>());
406 check_success(cam.is_valid_interface());
407
408 mi::math::Vector<mi::Uint32,2> buffer_resolution;
409 if (m_is_large_translate)
410 {
411 INFO_LOG << "large translate test mode.";
412 setup_extreme_transformed_camera(cam.get());
413 buffer_resolution = mi::math::Vector<mi::Uint32,2>(1602, 934);
414 }
415 else
416 {
417 setup_camera(cam.get());
418 buffer_resolution = mi::math::Vector<mi::Uint32,2>(512, 512);
419 }
420 const mi::neuraylib::Tag camera_tag = dice_transaction->store(cam.get());
421
422 m_image_file_canvas->set_resolution(buffer_resolution);
423
424 // Define a region of interest for the entire scene in the
425 // scene's global coordinate system.
426 const mi::math::Bbox<mi::Float32, 3> region_of_interest(
427 0.f, 0.f, 0.f,
428 static_cast< mi::Float32 >(heightfield_size.x),
429 static_cast< mi::Float32 >(heightfield_size.y),
430 static_cast< mi::Float32 >(heightfield_size.x) // Note: using the x dimension to define the z size
431 );
432 scene_edit->set_clipped_bounding_box(region_of_interest);
433
434 // Finally, optionally adjust the scene's coordinate system
435 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(
436 1.0f, 0.0f, 0.0f, 0.0f,
437 0.0f, 1.0f, 0.0f, 0.0f,
438 0.0f, 0.0f, -1.0f, 0.0f, // adjust for coordinate system
439 0.0f, 0.0f, 0.0f, 1.0f
440 );
441
442 if (m_is_large_translate)
443 {
444 transform_mat = get_extreme_transformed_matrix();
445 }
446
447 scene_edit->set_transform_matrix(transform_mat);
448
449 // ... and add the camera to the scene.
450 scene_edit->set_camera(camera_tag);
451 }
452 // Finish the initialization transaction
453 dice_transaction->commit();
454 }
455
456 // Rendering
457 {
458 // Render a frame and save the rendered image to a file.
459 const mi::Sint32 frame_idx = 0;
460 const std::string fname = get_output_file_name(m_outfname, frame_idx);
461 if(m_depth_buffer)
462 {
463 // The layer is added by automatically when set the depth_file_name
464 const std::string depth_file_name = m_outfname + "_depth_buffer";
465 m_image_file_canvas->set_depth_file_name(get_output_file_name(depth_file_name, frame_idx).c_str());
466 }
467
468 mi::base::Handle<nv::index::IFrame_results> frame_results(render_frame(fname));
469 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
470 if (err_set->any_errors())
471 {
472 std::ostringstream os;
473 const mi::Uint32 nb_err = err_set->get_nb_errors();
474 for (mi::Uint32 e = 0; e < nb_err; ++e)
475 {
476 if (e != 0) os << '\n';
477 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
478 os << err->get_error_string();
479 }
480
481 ERROR_LOG << "IIndex_rendering rendering call failed with the following error(s): " << '\n'
482 << os.str();
483 exit_code = 1;
484 }
485
486 // if(layer_id != invalid_layer_id)
487 // {
488 // arc.m_canvas.detach_layer(layer_id);
489 // }
490
491 // Verify the generated frame
492 if (!verify_canvas_result(get_application_layer_interface(),
493 m_image_file_canvas.get(), m_verify_image_fname, get_options()))
494 {
495 exit_code = 1;
496 }
497 }
498 }
499 }
500
501 return exit_code;
502}
503
504//----------------------------------------------------------------------
505bool Create_synthetic_heightfield::evaluate_options(nv::index::app::String_dict& sdict)
506{
507 const std::string com_name = sdict.get("command:", "<unknown_command>");
508 m_is_unittest = nv::index::app::get_bool(sdict.get("unittest", "false"));
509
510 if (m_is_unittest)
511 {
512 if (nv::index::app::get_bool(sdict.get("is_call_from_test", "false")))
513 {
514 sdict.insert("is_dump_comparison_image_when_failed", "0");
515 }
516 sdict.insert("outfname", ""); // turn off file output in the unit test mode
517 sdict.insert("dice::verbose", "2");
518 }
519
520 m_outfname = sdict.get("outfname");
521 m_verify_image_fname = sdict.get("verify_image_fname");
522 m_seeds = nv::index::app::get_bool(sdict.get("seeds", "false"));
523 m_depth_buffer = nv::index::app::get_bool(sdict.get("depth_buffer", "false"));
524 m_supersampling = nv::index::app::get_bool(sdict.get("supersampling", "false"));
525 m_texture = sdict.get("texture");
526 m_use_texture = m_texture != "none";
527 m_is_large_translate = nv::index::app::get_bool(sdict.get("is_large_translate", "false"));
528
529 info_cout("running " + com_name, sdict);
530 info_cout("outfname = [" + m_outfname +
531 "], verify_image_fname = [" + m_verify_image_fname +
532 "], dice::verbose = " + sdict.get("dice::verbose"), sdict);
533
534 // print help and exit if -h
535 if (sdict.is_defined("h"))
536 {
537 std::cout
538 << "info: Usage: " << com_name << " [option]\n"
539 << "Option: [-h]\n"
540 << " print out this message\n"
541 << " [-dice::verbose severity_level]\n"
542 << " verbose severity level (3 is info). (default: " + sdict.get("dice::verbose")
543 << ")\n"
544
545 << " [-seeds bool]\n"
546 << " render with additional 'seed' points and lines. (default: " + m_seeds
547 << ")\n"
548
549 << " [-depth_buffer bool]\n"
550 << " render depth buffer and store depth buffer as image (ppm). (default: " + m_depth_buffer
551 << ")\n"
552
553 << " [-supersampling bool]\n"
554 << " when true then supersampling is enabled."
555 << "(default: " << m_supersampling << ")\n"
556
557 << " [-texture mode]\n"
558 << " map a computed texture onto the heightfield.\n"
559 << " Available modes: none, mandelbrot, height_color\n"
560 << " (default: " << m_texture << ")\n"
561
562 << " [-is_large_translate bool]\n"
563 << " on/off large translation mode."
564 << "(default: " << m_is_large_translate << ")\n"
565
566 << " [-outfname string]\n"
567 << " output ppm file base name. When empty, no output.\n"
568 << " A frame number and extension (.ppm) will be added.\n"
569 << " (default: [" << m_outfname << "])\n"
570
571 << " [-verify_image_fname image_fname]\n"
572 << " when image_fname exist, verify the rendering image.\n"
573 << " (default: [" << m_verify_image_fname << "])\n"
574
575 << " [-unittest bool]\n"
576 << " when true, unit test mode. "
577 << "(default: [" << m_is_unittest << "])"
578 << std::endl;
579 exit(1);
580 }
581
582 return true;
583}
584
585//----------------------------------------------------------------------
586void Create_synthetic_heightfield::setup_camera(nv::index::IPerspective_camera* cam) const
587{
588 check_success(cam != 0);
589
590 // Set the camera parameters to see the whole scene
591 const mi::math::Vector<mi::Float32, 3> from(700, 700, 200);
592 const mi::math::Vector<mi::Float32, 3> to ( 250.f, 250.f, -200.f);
593 const mi::math::Vector<mi::Float32, 3> up ( 0.f, 0.f, 1.0f);
594 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
595 viewdir.normalize();
596
597 cam->set(from, viewdir, up);
598 cam->set_aperture(0.033f);
599 cam->set_aspect(1.0f);
600 cam->set_focal(0.03f);
601 cam->set_clip_min(2.0f);
602 cam->set_clip_max(1000.0f);
603}
604
605//----------------------------------------------------------------------
606void Create_synthetic_heightfield::setup_extreme_transformed_camera(nv::index::IPerspective_camera* cam) const
607{
608 check_success(cam != 0);
609
610 // *** Camera:
611 // index::camera::eye_point = 1808409.125 9981818 10948.5126953125
612 // index::camera::view_direction = (1808409.125 9981818 -1500) - eye_point
613 // index::camera::up_direction = 0 1 0
614 // index::camera::aspect = 1.7152034261242
615 // index::camera::aperture = 0.033
616 // index::camera::focal = 0.03
617 // index::camera::clip_min = 124.485130310059
618 // index::camera::clip_max = 17585.455078125
619 // index::canvas_resolution = 1602 934
620
621 // Adjusted the camera position for p = 23+1.
622 // mi::math::Vector< mi::Float32, 3 > const from( 1805060.125f + 1024.0f, 9978520.0f + 1024.0f, 256.0f);
623 // mi::math::Vector< mi::Float32, 3 > const to ( 1805060.125f + 256.0f, 9978520.0f + 256.0f, -256.0f);
624 mi::math::Vector< mi::Float32, 3 > const from( 1805060.125f + 20480.0f, 9978520.0f + 20480.0f, 2048.0f);
625 mi::math::Vector< mi::Float32, 3 > const to ( 1805060.125f + 5120.0f, 9978520.0f + 5120.0f, -1024.0f);
626 mi::math::Vector< mi::Float32, 3 > const up ( 0.0f, 0.0f, 1.0f);
627 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
628 viewdir.normalize();
629
630 cam->set(from, viewdir, up);
631 cam->set_aperture(0.033f);
632 cam->set_aspect(1.71520f); // not 1.7152034261242f, see IEEE754
633 cam->set_focal(0.03f);
634 cam->set_clip_min(124.485f); // not 124.485130310059f, see IEEE754
635 cam->set_clip_max(17585.6f); // not 17585.55078125f, see IEEE754
636
637 INFO_LOG << "Set camera extreme mode";
638}
639
640//----------------------------------------------------------------------
641mi::math::Matrix<mi::Float32, 4, 4> Create_synthetic_heightfield::get_extreme_transformed_matrix() const
642{
643 // transform =
644 // [ 20.6100006103516 0 0 1805060
645 // 0 20.6100006103516 0 9978520
646 // 0 0 -4 0
647 // 0 0 0 1 ]
648 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(
649 20.0f, 0.0f, 0.0f, 0.0f,
650 0.0f, 20.0, 0.0f, 0.0f,
651 0.0f, 0.0f, -20.0f, 0.0f,
652 1805060.0f, 9978520.0f, 0.0f, 1.0f
653 );
654
655 return transform_mat;
656}
657
658//----------------------------------------------------------------------
659nv::index::IFrame_results* Create_synthetic_heightfield::render_frame(const std::string& output_fname) const
660{
661 check_success(m_index_rendering.is_valid_interface());
662
663 // set output filename, empty string is valid
664 m_image_file_canvas->set_rgba_file_name(output_fname.c_str());
665
666 check_success(m_session_tag.is_valid());
667
668 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
669 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
670 check_success(dice_transaction.is_valid_interface());
671
672 m_index_session->update(m_session_tag, dice_transaction.get());
673
674 mi::base::Handle<nv::index::IFrame_results> frame_results(
675 m_index_rendering->render(
676 m_session_tag,
677 m_image_file_canvas.get(),
678 dice_transaction.get()));
679 check_success(frame_results.is_valid_interface());
680
681 dice_transaction->commit();
682
683 frame_results->retain();
684 return frame_results.get();
685}
686
687//----------------------------------------------------------------------
688// This example shows how to create a synthetic heightfield
689int main(int argc, const char* argv[])
690{
691 nv::index::app::String_dict sdict;
692 sdict.insert("dice::verbose", "3"); // log level
693 sdict.insert("seeds", "0"); // enable seeds (default off)
694 sdict.insert("depth_buffer", "0"); // write depth buffer to image file
695 sdict.insert("outfname", "frame_create_synthetic_heightfield"); // output file base name
696 sdict.insert("verify_image_fname", ""); // for unit test
697 sdict.insert("unittest", "0"); // unit test mode
698 sdict.insert("supersampling", "0"); // disable supersampling (default)
699 sdict.insert("texture", "none"); // texture (default none)
700 sdict.insert("is_large_translate", "0"); // large translation mode (default 0)
701 sdict.insert("is_dump_comparison_image_when_failed", "1"); // default: dump images when failed.
702 sdict.insert("is_call_from_test", "0"); // default: not call from make check.
703
704 // Load IndeX library via Index_connect
705 sdict.insert("dice::network::mode", "OFF");
706
707 // index setting
708 sdict.insert("index::config::set_monitor_performance_values", "true");
709 sdict.insert("index::service", "rendering_and_compositing");
710 sdict.insert("index::cuda_debug_checks", "false");
711
712 // application_layer component loading
713 sdict.insert("index::app::components::application_layer::component_name_list",
714 "canvas_infrastructure image io data_analysis_and_processing");
715 sdict.insert("index::app::plugins::base_importer::enabled", "true");
716 sdict.insert("index::app::plugins::legacy_importer::enabled", "true");
717
718 // Initialize application
719 Create_synthetic_heightfield create_synthetic_heightfield;
720 create_synthetic_heightfield.initialize(argc, argv, sdict);
721 check_success(create_synthetic_heightfield.is_initialized());
722
723 // launch the application. creating the scene and rendering.
724 const mi::Sint32 exit_code = create_synthetic_heightfield.launch();
725 INFO_LOG << "Shutting down ...";
726
727 return exit_code;
728}
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)