NVIDIA Index example code nvidia_logo_transpbg.gif Up
create_reservoir.cpp
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright 2023 NVIDIA Corporation. All rights reserved.
3 *****************************************************************************/
6
7#include <mi/dice.h>
8
9// Include code shared by all examples.
10#include "utility/example_shared.h"
11
12#include <nv/index/icamera.h>
13#include <nv/index/iindex.h>
14#include <nv/index/ilight.h>
15#include <nv/index/imaterial.h>
16#include <nv/index/itriangle_mesh_scene_element.h>
17#include <nv/index/iscene.h>
18#include <nv/index/iconfig_settings.h>
19#include <nv/index/iscene_group.h>
20#include <nv/index/isession.h>
21#include <nv/index/icolormap.h>
22#include <nv/index/itexture.h>
23#include <nv/index/ishading_model.h>
24#include <nv/index/iwireframe_rendering_style.h>
25
26#include <nv/index/app/index_connect.h>
27#include <nv/index/app/string_dict.h>
28
29#include "utility/canvas_utility.h"
30
31#include <iostream>
32#include <sstream>
33
34//----------------------------------------------------------------------
36 public nv::index::app::Index_connect
37{
38public:
40 :
41 Index_connect()
42 {
43 // INFO_LOG << "DEBUG: Create_reservoir() ctor";
44 }
45
47 {
48 // Note: Index_connect::~Index_connect() will be called after here.
49 // INFO_LOG << "DEBUG: ~Create_reservoir() dtor";
50 }
51
52 // launch application
53 mi::Sint32 launch();
54
55protected:
56 virtual bool evaluate_options(nv::index::app::String_dict& sdict) CPP11_OVERRIDE;
57 // override
59 mi::neuraylib::INetwork_configuration* network_configuration,
60 nv::index::app::String_dict& options) CPP11_OVERRIDE
61 {
62 check_success(network_configuration != 0);
63
64 check_success(options.is_defined("unittest"));
65 const bool is_unittest = nv::index::app::get_bool(options.get("unittest"));
66 if (is_unittest)
67 {
68 info_cout("NETWORK: disabled networking mode.", options);
69 network_configuration->set_mode(mi::neuraylib::INetwork_configuration::MODE_OFF);
70 return true;
71 }
72
73 return initialize_networking_as_default_udp(network_configuration, options);
74 }
75
76private:
77 // Create a synthetic colormap
78 nv::index::IColormap* create_colormap(nv::index::IScene* scene) const;
79 // Create the scene with a reservoir grid
80 // \param[in] geometry_file geometry file of the dataset
81 // \param[in] scalar_file scalar file containing attribute values of the cells
82 // \param[in] reservoir_bbox bounding box of the reservoir, this is also needed for the view computation.
83 // \param[in] wireframe_mode wireframe style to be used to highlight cells
84 // \param[in] wireframe_width width of the wireframe
85 // \param[in] wireframe_color color of the wireframe
86 // \param[in] scene_edit IScene
87 // \param[in] dice_transaction dice transaction
88 // \return true when success
89 bool create_scene(
90 const std::string& geometry_file,
91 const std::string& scalar_file,
92 const mi::math::Bbox<mi::Float32, 3>& reservoir_bbox,
93 const mi::Uint32& wireframe_mode,
94 const mi::Float32& wireframe_width,
95 const mi::math::Color& wireframe_color,
96 nv::index::IScene* scene_edit,
97 mi::neuraylib::IDice_transaction* dice_transaction);
98
99 // setup camera to see this example scene
100 void setup_camera(nv::index::IPerspective_camera* cam) const;
101
102 void view_all_bbox(
103 const mi::math::Vector<mi::Float32, 3>& from,
104 const mi::math::Vector<mi::Float32, 3>& up,
105 const mi::math::Bbox< mi::Float32, 3 >& bbox,
106 const mi::neuraylib::Tag& camera_tag,
107 nv::index::IScene* scene_edit,
108 mi::neuraylib::IDice_transaction* dice_transaction) const;
109
110 // render a frame
111 // \param[in] output_fname output rendering image filename
112 // \return performance values
113 nv::index::IFrame_results* render_frame(const std::string& output_fname) const;
114
115 // This session tag
116 mi::neuraylib::Tag m_session_tag;
117 // NVIDIA IndeX cluster configuration
118 mi::base::Handle<nv::index::ICluster_configuration> m_cluster_configuration;
119 // Application layer image file canvas (a render target)
120 mi::base::Handle<nv::index::app::canvas_infrastructure::IIndex_image_file_canvas> m_image_file_canvas;
121 // Create_icons options
122 std::string m_outfname;
123 bool m_is_unittest;
124 std::string m_verify_image_fname;
125 std::string m_geometry_file;
126 std::string m_scalar_file;
127 mi::math::Vector<mi::Uint32,3> m_subcube_size;
128 mi::math::Bbox<mi::Float32,3> m_roi;
129 mi::Uint32 m_wireframe_mode;
130 mi::Float32 m_wireframe_width;
131 mi::math::Color m_wireframe_color;
132 bool m_supersampling;
133};
134
135//----------------------------------------------------------------------
137{
138 mi::Sint32 exit_code = 0;
139
140 // Get DiCE database components
141 {
142 m_cluster_configuration =
143 get_index_interface()->
144 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. This may fail when there is a license problem.
152 check_success(is_local_host_joined(m_cluster_configuration.get()));
153
154 {
155 // DiCE database access
156 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
157 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
158 check_success(dice_transaction.is_valid_interface());
159 {
160 // Setup session information
161 m_session_tag = m_index_session->create_session(dice_transaction.get());
162 check_success(m_session_tag.is_valid());
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 mi::base::Handle< nv::index::IScene > scene_edit(
168 dice_transaction->edit<nv::index::IScene>(session->get_scene()));
169 check_success(scene_edit.is_valid_interface());
170
171 // Enable supersampling
172 if (m_supersampling)
173 {
174 mi::base::Handle<nv::index::IConfig_settings> config_settings(
175 dice_transaction->edit<nv::index::IConfig_settings>(session->get_config()));
176 check_success(config_settings.is_valid_interface());
177
178 config_settings->set_rendering_samples(16);
179 }
180
181 // Set subcube size
182 {
183 mi::base::Handle<nv::index::IConfig_settings> config_settings(
184 dice_transaction->edit<nv::index::IConfig_settings>(session->get_config()));
185 check_success(config_settings.is_valid_interface());
186
187 // Subcube border size
188 mi::Uint32 subcube_border_size = 1;
189
190 // Supporting continuous translation requires additional memory compared to when only
191 // integer translation is supported
192 bool support_continuous_translation = false;
193
194 // Subcube size will be changed internally if rotation of volume scene elements is supported
195 bool support_rotation = false;
196
197 // Same if they are scaled with a scale factor < 1, need to specify the minimum factor then.
198 mi::Float32_3 min_scale = mi::Float32_3(1,1,1);
199
200 const bool is_success =
201 config_settings->set_subcube_configuration(m_subcube_size, subcube_border_size,
202 support_continuous_translation, support_rotation, min_scale);
203 if(!is_success)
204 ERROR_LOG << "Failed to configure the subcubes.";
205
206 }
207
208 //----------------------------------------------------------------------
209 // Scene setup: hierarchical scene description root node,
210 // scene parameters, camera.
211 //----------------------------------------------------------------------
212 // Reservoir importer based on ensight file format
213 if (m_geometry_file == "")
214 {
215 ERROR_LOG <<"Missing geometry file for reservoir grid importer";
216 return false;
217 }
218
219 if (m_scalar_file == "")
220 {
221 WARN_LOG << "Missing scalar file for reservoir grid importer, "
222 << "cells are colored based on the depth value";
223 }
224
225 // Create a hierarchical scene description that contains the reservoir grid
226 check_success(create_scene(m_geometry_file,
227 m_scalar_file,
228 m_roi,
229 m_wireframe_mode,
230 m_wireframe_width,
231 m_wireframe_color,
232 scene_edit.get(),
233 dice_transaction.get()));
234
235 // Create and edit a camera. Data distribution is based on
236 // the camera. (Because only visible massive data are
237 // considered)
238 mi::base::Handle< nv::index::IPerspective_camera > cam(
239 scene_edit->create_camera<nv::index::IPerspective_camera>());
240 check_success(cam.is_valid_interface());
241 setup_camera(cam.get());
242 const mi::neuraylib::Tag camera_tag = dice_transaction->store(cam.get());
243 check_success(camera_tag.is_valid());
244
245 const mi::math::Vector<mi::Uint32, 2> buffer_resolution(1024, 1024);
246 m_image_file_canvas->set_resolution(buffer_resolution);
247
248 // Set the region of interest.
249 check_success(m_roi.is_volume());
250 scene_edit->set_clipped_bounding_box(m_roi);
251
252 // Set the scene global transformation matrix.
253 // only change the coordinate system
254 mi::math::Matrix<mi::Float32, 4, 4> transform_mat(
255 1.0f, 0.0f, 0.0f, 0.0f,
256 0.0f, 1.0f, 0.0f, 0.0f,
257 0.0f, 0.0f, -1.0f, 0.0f,
258 0.0f, 0.0f, 0.0f, 1.0f
259 );
260
261 scene_edit->set_transform_matrix(transform_mat);
262
263 // Set the current camera to the scene.
264 check_success(camera_tag.is_valid());
265 scene_edit->set_camera(camera_tag);
266
267 const mi::math::Vector<mi::Float32, 3> from(0.0f, 0.0f, 1.0f);
268 const mi::math::Vector<mi::Float32, 3> up (0.0f, 1.0f, 0.0f);
269 view_all_bbox(from, up, m_roi, camera_tag, scene_edit.get(), dice_transaction.get());
270 }
271 // Finish initialization transaction
272 dice_transaction->commit();
273 }
274
275 // Rendering
276 {
277 // Render a frame and save the rendered image to a file.
278 const mi::Sint32 frame_idx = 0;
279 const std::string fname = get_output_file_name(m_outfname, frame_idx);
280
281 mi::base::Handle<nv::index::IFrame_results> frame_results(render_frame(fname));
282 const mi::base::Handle<nv::index::IError_set> err_set(frame_results->get_error_set());
283 if (err_set->any_errors())
284 {
285 std::ostringstream os;
286 const mi::Uint32 nb_err = err_set->get_nb_errors();
287 for (mi::Uint32 e = 0; e < nb_err; ++e)
288 {
289 if (e != 0) os << '\n';
290 const mi::base::Handle<nv::index::IError> err(err_set->get_error(e));
291 os << err->get_error_string();
292 }
293
294 ERROR_LOG << "IIndex_rendering rendering call failed with the following error(s): " << '\n'
295 << os.str();
296 exit_code = 1;
297 }
298
299 // verify the generated frame
300 if (!(verify_canvas_result(get_application_layer_interface(),
301 m_image_file_canvas.get(), m_verify_image_fname, get_options())))
302 {
303 exit_code = 1;
304 }
305 }
306 }
307
308 return exit_code;
309}
310
311//----------------------------------------------------------------------
312bool Create_reservoir::evaluate_options(nv::index::app::String_dict& sdict)
313{
314 const std::string com_name = sdict.get("command:", "<unknown_command>");
315 m_is_unittest = nv::index::app::get_bool(sdict.get("unittest", "false"));
316
317 if (m_is_unittest)
318 {
319 if (nv::index::app::get_bool(sdict.get("is_call_from_test", "false")))
320 {
321 sdict.insert("is_dump_comparison_image_when_failed", "0");
322 }
323 sdict.insert("outfname", ""); // turn off file output in the unit test mode
324 sdict.insert("dice::verbose", "2");
325 }
326
327 m_geometry_file = sdict.get("geometry_file");
328 m_scalar_file = sdict.get("scalar_file");
329 m_subcube_size = nv::index::app::get_vector_from_string<mi::Uint32,3>(sdict.get("subcube_size"));
330 m_roi = nv::index::app::get_bbox_from_string<mi::Float32,3>(sdict.get("roi"));
331 m_wireframe_mode = nv::index::app::get_uint32(sdict.get("wireframe_mode"));
332 m_wireframe_width = nv::index::app::get_float32(sdict.get("wireframe_width"));
333 m_wireframe_color = nv::index::app::get_color(sdict.get("wireframe_color"));
334 m_verify_image_fname = sdict.get("verify_image_fname");
335 m_supersampling = nv::index::app::get_bool(sdict.get("supersampling"));
336
337 info_cout(std::string("running ") + com_name, sdict);
338 info_cout(std::string("outfname = [") + m_outfname +
339 "], verify_image_fname = [" + m_verify_image_fname +
340 "], dice::verbose = " + sdict.get("dice::verbose"), sdict);
341
342 // print help and exit if -h
343 if(sdict.is_defined("h"))
344 {
345 std::cout
346 << "info: Usage: " << com_name << " [option]\n"
347 << "Option: [-h]\n"
348 << " printout this message\n"
349
350 << " [-dice::verbose severity_level]\n"
351 << " verbose severity level (3 is info.). (default: " + sdict.get("dice::verbose")
352 << ")\n"
353
354 << " [-geometry_file \"string\"]\n"
355 << " Subcube size to be rendered with.\n"
356 << " (default: [" << m_geometry_file << "])\n"
357
358 << " [-scalar_file \"string\"]\n"
359 << " Geometry file for the reservoir.\n"
360 << " (default: [" << m_scalar_file << "])\n"
361
362 << " [-subcube_size \"uint uint uint\"]\n"
363 << " Scalar file with attribute values for the cells.\n"
364 << " (default: [" << m_subcube_size << "])\n"
365
366 << " [-roi \"float float float float float float\"]\n"
367 << " the bounding box representing the region of interest (roi).\n"
368 << " (default: [" << m_roi << "])\n"
369
370 << " [-wireframe_mode \"uint\"]\n"
371 << " Enable wireframe rendering style. Values:\n"
372 << " 0: Disabled, 1: Outlines, 2:Pure wireframe\n"
373 << " (default: [" << m_wireframe_mode << "])\n"
374
375 << " [-wireframe_width \"float\"]\n"
376 << " The wireframe/outline width.\n"
377 << " (default: [" << m_wireframe_width << "])\n"
378
379 << " [-wireframe_color \"float float float\"]\n"
380 << " The wireframe\\outlines color.\n"
381 << " (default: [" << m_wireframe_color << "])\n"
382
383 << " [-outfname string]\n"
384 << " name of the output ppm image file. When empty, no image file will be written.\n"
385 << " A frame number and the extension (.ppm) will be added.\n"
386 << " (default: [" << m_outfname << "])\n"
387
388 << " [-verify_image_fname [image_fname]]\n"
389 << " when image_fname exist, verify the rendering image. \n"
390 << " (default: ["<< m_verify_image_fname << "])\n"
391
392 << " [-unittest bool]\n"
393 << " when true, unit test mode."
394 << " (default: " << m_is_unittest << ")\n"
395
396 << " [-supersampling bool]\n"
397 << " when true then supersampling is enabled."
398 << " (default: " << m_supersampling << ")\n)"
399
400 << std::endl;
401 exit(1);
402 }
403
404 return true;
405}
406
407//----------------------------------------------------------------------
408nv::index::IColormap* Create_reservoir::create_colormap(nv::index::IScene* scene) const
409{
410 nv::index::IColormap* colormap = scene->create_attribute<nv::index::IColormap>();
411 std::vector<mi::math::Color_struct> colormap_entries;
412 colormap_entries.resize(256);
413
414 mi::Float32 vmin = 0.0f;
415 mi::Float32 vmax = 0.9f;
416 for(mi::Uint32 i=0; i<256; ++i)
417 {
418 mi::Float32 v = (static_cast<mi::Float32>(i)+0.5f)/256.0f;
419
420 mi::math::Color_struct c = {1.f, 1.f, 1.f, 1.f};
421 mi::Float32 dv;
422
423 if (v < vmin)
424 v = vmin;
425 if (v > vmax)
426 v = vmax;
427 dv = vmax - vmin;
428
429 if (v < (vmin + 0.25f * dv))
430 {
431 c.r = 0.f;
432 c.g = 4.f * (v - vmin) / dv;
433 }
434 else if (v < (vmin + 0.5f * dv))
435 {
436 c.r = 0.f;
437 c.b = 1.f + 4.f * (vmin + 0.25f * dv - v) / dv;
438 }
439 else if (v < (vmin + 0.75f * dv))
440 {
441 c.r = 4.f * (v - vmin - 0.5f * dv) / dv;
442 c.b = 0.f;
443 }
444 else
445 {
446 c.g = 1.f + 4.f * (vmin + 0.75f * dv - v) / dv;
447 c.b = 0.f;
448 }
449 colormap_entries[i] = c;
450 }
451
452 // Set the the colormap values.
453 colormap->set_colormap(&(colormap_entries[0]), colormap_entries.size());
454 return colormap;
455}
456
457//----------------------------------------------------------------------
458bool Create_reservoir::create_scene(
459 const std::string& geometry_file,
460 const std::string& scalar_file,
461 const mi::math::Bbox<mi::Float32, 3>& reservoir_bbox,
462 const mi::Uint32& wireframe_mode,
463 const mi::Float32& wireframe_width,
464 const mi::math::Color& wireframe_color,
465 nv::index::IScene* scene_edit,
466 mi::neuraylib::IDice_transaction* dice_transaction)
467{
468 check_success(dice_transaction != 0);
469 check_success(scene_edit != 0);
470
471 {
472 // Set the default light source
473 mi::base::Handle<nv::index::IDirectional_light> headlight(
474 scene_edit->create_attribute<nv::index::IDirectional_light>());
475 check_success(headlight.is_valid_interface());
476 headlight->set_direction(mi::math::Vector<mi::Float32, 3>(1.f, -1.f, -1.f));
477 const mi::neuraylib::Tag headlight_tag = dice_transaction->store(headlight.get());
478 check_success(headlight_tag.is_valid());
479 scene_edit->append(headlight_tag, dice_transaction);
480
481 // Set the default material
482 mi::base::Handle<nv::index::IPhong_gl> phong_1(scene_edit->create_attribute<nv::index::IPhong_gl>());
483 check_success(phong_1.is_valid_interface());
484 phong_1->set_ambient(mi::math::Color(0.1f, 0.1f, 0.1f, 1.0f));
485 phong_1->set_diffuse(mi::math::Color(0.7f, 0.7f, 0.7f, 1.0f));
486 phong_1->set_specular(mi::math::Color(0.4f, 0.4f, 0.4f, 1.0f));
487 phong_1->set_opacity(1.0);
488 phong_1->set_shininess(10);
489 const mi::neuraylib::Tag phong_1_tag = dice_transaction->store(phong_1.get());
490 check_success(phong_1_tag.is_valid());
491 scene_edit->append(phong_1_tag, dice_transaction);
492 }
493
494 {
495 // The the colormap to demonstrate color index color mapping.
496 mi::base::Handle<nv::index::IColormap> colormap(create_colormap(scene_edit));
497 check_success(colormap.is_valid_interface());
498
499 // Store in DiCE database.
500 const mi::neuraylib::Tag colormap_tag = dice_transaction->store_for_reference_counting(
501 colormap.get(), mi::neuraylib::NULL_TAG, "colormap");
502 check_success(colormap_tag.is_valid());
503 scene_edit->append(colormap_tag, dice_transaction);
504 }
505
506 {
507 // Create a static scene group
508 mi::base::Handle<nv::index::IStatic_scene_group> static_group(
509 scene_edit->create_scene_group<nv::index::IStatic_scene_group>());
510 check_success(static_group.is_valid_interface());
511
512 // wireframe rendering style attribute
513 if(wireframe_mode > 0)
514 {
515 mi::base::Handle<nv::index::IWireframe_rendering_style> wire_style(scene_edit->create_attribute<nv::index::IWireframe_rendering_style>());
516 check_success(wire_style.is_valid_interface());
517
518 switch(wireframe_mode)
519 {
520 case 1:
521 wire_style->set_wireframe_style(nv::index::IWireframe_rendering_style::WIREFRAME_STYLE_OUTLINE);
522 break;
523
524 case 2:
525 wire_style->set_wireframe_style(nv::index::IWireframe_rendering_style::WIREFRAME_STYLE_WIREFRAME);
526 break;
527 }
528
529 wire_style->set_wireframe_width(wireframe_width);
530 wire_style->set_wireframe_color(wireframe_color);
531 const mi::neuraylib::Tag wire_style_tag = dice_transaction->store_for_reference_counting(wire_style.get());
532 check_success(wire_style_tag.is_valid());
533
534 // append wireframe style to the static scene group
535 if(wireframe_mode > 0)
536 {
537 static_group->append(wire_style_tag, dice_transaction);
538 }
539 }
540
541 const std::string cache_type = "off";
542
543 // reservoir grid creation parameter
544 nv::index::app::String_dict reservoir_trimesh_opt;
545 const std::string ns_importer_name = "nv::index::plugin::base_importer.Reservoir_grid_importer";
546 reservoir_trimesh_opt.insert("args::type", "reservoir_grid");
547 reservoir_trimesh_opt.insert("args::importer", ns_importer_name);
548 reservoir_trimesh_opt.insert("args::geometry_file", geometry_file);
549 reservoir_trimesh_opt.insert("args::scalar_file", scalar_file);
550 reservoir_trimesh_opt.insert("args::cache_type", cache_type);
551 std::stringstream sstr;
552 sstr << reservoir_bbox.min.x << " " << reservoir_bbox.min.y << " " << reservoir_bbox.min.z << " "
553 << reservoir_bbox.max.x << " " << reservoir_bbox.max.y << " " << reservoir_bbox.max.z;
554 reservoir_trimesh_opt.insert("args::bbox", sstr.str());
555
556 nv::index::IDistributed_data_import_callback* importer_callback =
557 get_importer_from_application_layer(
558 get_application_layer_interface(),
559 ns_importer_name,
560 reservoir_trimesh_opt);
561
562 // Create the triangle mesh scene element of the reservoir grid
563 mi::base::Handle<nv::index::ITriangle_mesh_scene_element> mesh(
564 scene_edit->create_triangle_mesh(reservoir_bbox, importer_callback, dice_transaction));
565 check_success(mesh != 0);
566
567 // scene element properties
568 mesh->set_enabled(true);
569
570 // storing the mesh in the data (base) store
571 mi::neuraylib::Tag mesh_tag = dice_transaction->store_for_reference_counting(mesh.get());
572 check_success(mesh_tag.is_valid());
573
574 // append mesh to the static scene group
575 static_group->append(mesh_tag, dice_transaction);
576
577 mi::neuraylib::Tag static_group_tag = dice_transaction->store_for_reference_counting(static_group.get());
578 check_success(static_group_tag.is_valid());
579
580 // append the static scene group to the hierachical scene description.
581 scene_edit->append(static_group_tag, dice_transaction);
582 }
583
584 return true;
585}
586
587//----------------------------------------------------------------------
588void Create_reservoir::setup_camera(nv::index::IPerspective_camera* cam) const
589{
590 check_success(cam != 0);
591
592 // Initialize the camera with some default parameters ...
593 const mi::math::Vector< mi::Float32, 3 > from( 0.0f, 0.0f,-5.0f);
594 const mi::math::Vector< mi::Float32, 3 > to ( 0.0f, 0.0f, 0.0f);
595 const mi::math::Vector< mi::Float32, 3 > up ( 0.0f, 1.0f, 0.0f);
596 mi::math::Vector<mi::Float32, 3> viewdir = to - from;
597 viewdir.normalize();
598
599 cam->set(from, viewdir, up);
600 cam->set_aperture(0.033f);
601 cam->set_aspect(1.0f);
602 cam->set_focal(0.03f);
603 cam->set_clip_min(10.0f);
604 cam->set_clip_max(5000.0f);
605}
606
607//----------------------------------------------------------------------
608void Create_reservoir::view_all_bbox(
609 const mi::math::Vector<mi::Float32, 3>& from,
610 const mi::math::Vector<mi::Float32, 3>& up,
611 const mi::math::Bbox< mi::Float32, 3 >& bbox,
612 const mi::neuraylib::Tag& camera_tag,
613 nv::index::IScene* scene_edit,
614 mi::neuraylib::IDice_transaction* dice_transaction) const
615{
616 check_success(dice_transaction != 0);
617
618 if(bbox.empty())
619 {
620 WARN_LOG << "Un-initialized bounding box and not updating the camera settings.";
621 return;
622 }
623
624 {
625 mi::base::Handle<nv::index::IPerspective_camera> camera(dice_transaction->edit<nv::index::IPerspective_camera>(camera_tag));
626 check_success(camera.is_valid_interface());
627
628 // Compute the new camera parameters
629 const mi::math::Bbox< mi::Float32, 3 >& global_roi_bbox = scene_edit->get_clipped_bounding_box();
630 const mi::math::Matrix<mi::Float32, 4, 4>& transform_mat = scene_edit->get_transform_matrix();
631 const mi::math::Vector<mi::Float32, 3> new_min(mi::math::transform_point(transform_mat, global_roi_bbox.min));
632 const mi::math::Vector<mi::Float32, 3> new_max(mi::math::transform_point(transform_mat, global_roi_bbox.max));
633 const mi::math::Bbox< mi::Float32, 3 > transformed_bbox(new_min, new_max);
634 const mi::math::Vector<mi::Float32, 3>& min = transformed_bbox.min;
635 const mi::math::Vector<mi::Float32, 3>& max = transformed_bbox.max;
636 const mi::math::Vector<mi::Float32, 3>& center = transformed_bbox.center();
637 const mi::Float32 rad = mi::math::euclidean_distance(max, min) / 2.0f;
638
639 const mi::Float32 fov_rad_2 = static_cast<mi::Float32>(camera->get_fov_y_rad() / 2.0);
640 const mi::Float32 dist = static_cast<mi::Float32>(rad / tan(fov_rad_2));
641
642 const mi::math::Vector<mi::Float32, 3> eyepos = -(1.f * dist * from) + center;
643 camera->set_eye_point(eyepos);
644 camera->set_up_direction(up);
645
646 const mi::Float32 clip_min = 0.1f * dist;
647 const mi::Float32 clip_max = 10.0f * 1.f * dist;
648
649 camera->set_clip_min(clip_min);
650 camera->set_clip_max(clip_max);
651 mi::math::Vector<mi::Float32, 3> viewdir = center - eyepos;
652 check_success(viewdir.normalize());
653 camera->set_view_direction(viewdir);
654 }
655}
656
657//----------------------------------------------------------------------
658nv::index::IFrame_results* Create_reservoir::render_frame(const std::string& output_fname) const
659{
660 check_success(m_index_rendering.is_valid_interface());
661
662 // set output filename, empty string is valid
663 m_image_file_canvas->set_rgba_file_name(output_fname.c_str());
664
665 check_success(m_session_tag.is_valid());
666
667 mi::base::Handle<mi::neuraylib::IDice_transaction> dice_transaction(
668 m_global_scope->create_transaction<mi::neuraylib::IDice_transaction>());
669 check_success(dice_transaction.is_valid_interface());
670
671 m_index_session->update(m_session_tag, dice_transaction.get());
672
673 mi::base::Handle<nv::index::IFrame_results> frame_results(
674 m_index_rendering->render(
675 m_session_tag,
676 m_image_file_canvas.get(),
677 dice_transaction.get()));
678 check_success(frame_results.is_valid_interface());
679
680 dice_transaction->commit();
681
682 frame_results->retain();
683 return frame_results.get();
684}
685
686//----------------------------------------------------------------------
687// This example shows how to create a reservoir grid from an ensight file.
688int main(int argc, const char* argv[])
689{
690 nv::index::app::String_dict sdict;
691 sdict.insert("dice::verbose", "3"); // log level
692 sdict.insert("geometry_file", "../create_reservoir/reservoir_grid_pillar.bin"); // geometry file for the reservoir
693 sdict.insert("scalar_file", ""); // scalar file for the cell attributes
694 sdict.insert("subcube_size", "512 512 512"); // subcube size
695 sdict.insert("roi", "0 0 0 502 302 94"); // input roi
696 sdict.insert("wireframe_mode", "0"); // wireframe disabled(default)
697 // 1 = outlines
698 // 2 = pure wirframe
699 sdict.insert("wireframe_width", "1.f"); // wireframe width
700 sdict.insert("wireframe_color", "0.1 0.1 0.3"); // wireframe color
701 sdict.insert("outfname", "frame_create_reservoir"); // output file base name
702 sdict.insert("verify_image_fname", ""); // for unit test
703 sdict.insert("unittest", "0"); // default mode
704 sdict.insert("supersampling", "1"); // disable supersampling (default)
705 sdict.insert("is_large_translate", "0"); // large translation mode (default 0)
706 sdict.insert("is_dump_comparison_image_when_failed", "1"); // default: dump images when failed.
707 sdict.insert("is_call_from_test", "0"); // default: not call from make check.
708
709 // Load IndeX library via Index_connect
710 sdict.insert("dice::network::mode", "OFF");
711
712 // index setting
713 sdict.insert("index::config::set_monitor_performance_values", "true");
714 sdict.insert("index::service", "rendering_and_compositing");
715 sdict.insert("index::cuda_debug_checks", "false");
716
717 // application_layer component loading
718 sdict.insert("index::app::components::application_layer::component_name_list",
719 "canvas_infrastructure image io");
720 sdict.insert("index::app::plugins::base_importer::enabled", "true");
721
722 // Initialize application
723 Create_reservoir create_reservoir;
724 create_reservoir.initialize(argc, argv, sdict);
725 check_success(create_reservoir.is_initialized());
726
727 // launch the application. creating the scene and rendering.
728 const mi::Sint32 exit_code = create_reservoir.launch();
729 INFO_LOG << "Shutting down ...";
730
731 return exit_code;
732}
virtual bool initialize_networking(mi::neuraylib::INetwork_configuration *network_configuration, nv::index::app::String_dict &options) CPP11_OVERRIDE
virtual ~Create_reservoir()
virtual bool evaluate_options(nv::index::app::String_dict &sdict) CPP11_OVERRIDE
int main(int argc, const char *argv[])
#define check_success(expr)