Iray SDK API nvidia_logo_transpbg.gif Up
Example for Particles
[Previous] [Next] [Up]

This example imports a partial scene containing definitions for the camera, a light, and some geometry (a ground plane and a yellow cube). It then creates a red particle object using the API.

New Topics

  • Creation of particles

Detailed Description

Creation of particles


To create a particle object you need to specify the centers and the radii of each particle. In create_particles_cuboid() we create a particle object where the particles are contained inside a cuboid, with each particle having a random radius (between a minimum and a maximum). The centers and the radii are first computed and saved in a vector of mi::Float32 and then added to the particle object all at once. Particles can also be added one by one.

Example Source

Source Code Location: examples/example_particles.cpp

/******************************************************************************
* Copyright 2023 NVIDIA Corporation. All rights reserved.
*****************************************************************************/
// examples/example_particles.cpp
//
// Creates and manipulates particle objects.
//
// The example expects the following command line arguments:
//
// example_particles <mdl_path>
//
// mdl_path path to the MDL modules, e.g., iray-<version>/mdl
//
// The rendered image is written to a file named "example_particles.png".
#include <mi/neuraylib.h>
// Include code shared by all examples.
#include "example_shared.h"
// Include an implementation of IRender_target.
#include "example_render_target_simple.h"
#include <iostream>
#include <map>
#include <vector>
// Linear congruential generator for pseudo-random numbers, see
// https://en.wikipedia.org/wiki/Linear_congruential_generator
unsigned int lcg_a = 134775815;
unsigned int lcg_c = 123456;
unsigned int lcg_m = 1 << 31;
unsigned int lcg_prev = 33478921;
// Return a random number in the range [ 0 ... lcg_m )
unsigned int get_random_uint()
{
mi::Uint64 val = (lcg_a * lcg_prev + lcg_c) % lcg_m;
lcg_prev = static_cast<unsigned int>(val);
return lcg_prev;
}
// Return a random number in the range [min..max]
float get_random_float(const float& min, const float& max)
{
return ((float(get_random_uint()) * (max - min)) / float(lcg_m)) + min;
}
// Create particles inside a cuboid.
mi::neuraylib::IParticles* create_particles_cuboid(mi::neuraylib::ITransaction* transaction)
{
// Some constants to define the particles cuboid
const mi::Float32_3 cuboid_center(-0.5f, 0.f, 0.75f);
const mi::Float32 cuboid_x_length = 2.0f;
const mi::Float32 cuboid_y_length = 0.5f;
const mi::Float32 cuboid_z_length = 1.5f;
const mi::Float32 min_particles_radius = 0.01f;
const mi::Float32 max_particles_radius = 0.025f;
const unsigned int num_particles = 1000;
// Constants derived from the ones above
const mi::Float32 cuboid_min_x = cuboid_center.x - cuboid_x_length * 0.5f;
const mi::Float32 cuboid_max_x = cuboid_center.x + cuboid_x_length * 0.5f;
const mi::Float32 cuboid_min_y = cuboid_center.y - cuboid_y_length * 0.5f;
const mi::Float32 cuboid_max_y = cuboid_center.y + cuboid_y_length * 0.5f;
const mi::Float32 cuboid_min_z = cuboid_center.z - cuboid_z_length * 0.5f;
const mi::Float32 cuboid_max_z = cuboid_center.z + cuboid_z_length * 0.5f;
mi::neuraylib::IParticles* particles = transaction->create<mi::neuraylib::IParticles>("Particles");
// In this example the particles will be added all at once, but they can also be added one by one
std::vector<mi::Float32> particles_data;
for (unsigned int n = 0; n < num_particles; ++n) {
// Draw a random position inside the cuboid
const float x = get_random_float(cuboid_min_x, cuboid_max_x);
const float y = get_random_float(cuboid_min_y, cuboid_max_y);
const float z = get_random_float(cuboid_min_z, cuboid_max_z);
// Draw a random radius
const float radius = get_random_float(min_particles_radius, max_particles_radius);
particles_data.push_back(x);
particles_data.push_back(y);
particles_data.push_back(z);
particles_data.push_back(radius);
}
// 'particles_data' now contains 4 times as many floats as there are particles
particles->reserve(num_particles);
particles->set_data(&particles_data.front(), num_particles);
return particles;
}
// Add a particle object that has a red material attached.
void setup_scene( mi::neuraylib::ITransaction* transaction, const char* rootgroup)
{
// Create the particles object
mi::base::Handle<mi::neuraylib::IParticles> particles_object(create_particles_cuboid( transaction));
transaction->store(particles_object.get(), "particles_obj");
// Create the instance for the particles object
transaction->create<mi::neuraylib::IInstance>( "Instance"));
instance->attach( "particles_obj");
// Set the transformation matrix, the visible attribute, and the material
mi::Float64_4_4 matrix( 1.0 );
matrix.translate( 0.0, -0.4, 0.0);
instance->set_matrix( matrix );
instance->create_attribute<mi::IBoolean>( "visible", "Boolean"));
visible->set_value( true);
mi::base::Handle<mi::IRef> material( instance->create_attribute<mi::IRef>( "material", "Ref"));
material->set_reference( "red_material");
transaction->store( instance.get(), "instance_particles");
// Attach the instance to the root group
transaction->edit<mi::neuraylib::IGroup>( rootgroup));
group->attach( "instance_particles");
}
void configuration( mi::neuraylib::INeuray* neuray, const char* mdl_path)
{
// Configure the neuray library. Here we set the search path for .mdl files.
check_success( rc->add_mdl_path( mdl_path) == 0);
check_success( rc->add_mdl_path( ".") == 0);
// Load the OpenImageIO, Iray Photoreal, and .mi importer plugins.
check_success( pc->load_plugin_library( "nv_openimageio" MI_BASE_DLL_FILE_EXT) == 0);
check_success( pc->load_plugin_library( "libiray" MI_BASE_DLL_FILE_EXT) == 0);
check_success( pc->load_plugin_library( "mi_importer" MI_BASE_DLL_FILE_EXT) == 0);
}
void rendering( mi::neuraylib::INeuray* neuray)
{
// Get the database, the global scope of the database, and create a transaction in the global
// scope for importing the scene file and storing the scene.
check_success( database.is_valid_interface());
database->get_global_scope());
scope->create_transaction());
check_success( transaction.is_valid_interface());
// Import the scene file
check_success( import_api.is_valid_interface());
import_api->import_elements( transaction.get(), "file:main.mi"));
check_success( import_result->get_error_number() == 0);
// Add two triangle meshes to the scene
setup_scene( transaction.get(), import_result->get_rootgroup());
// Create the scene object
transaction->create<mi::neuraylib::IScene>( "Scene"));
scene->set_rootgroup( import_result->get_rootgroup());
scene->set_options( import_result->get_options());
scene->set_camera_instance( import_result->get_camera_inst());
transaction->store( scene.get(), "the_scene");
// Create the render context using the Iray Photoreal render mode
scene = transaction->edit<mi::neuraylib::IScene>( "the_scene");
scene->create_render_context( transaction.get(), "iray"));
check_success( render_context.is_valid_interface());
mi::base::Handle<mi::IString> scheduler_mode( transaction->create<mi::IString>());
scheduler_mode->set_c_str( "batch");
render_context->set_option( "scheduler_mode", scheduler_mode.get());
scene = 0;
// Create the render target and render the scene
new Render_target( image_api.get(), "Color", 512, 384));
check_success( render_context->render( transaction.get(), render_target.get(), 0) >= 0);
// Write the image to disk
check_success( export_api.is_valid_interface());
mi::base::Handle<mi::neuraylib::ICanvas> canvas( render_target->get_canvas( 0));
export_api->export_canvas( "file:example_particles.png", canvas.get());
transaction->commit();
}
int main( int argc, char* argv[])
{
// Collect command line parameters
if( argc != 2) {
std::cerr << "Usage: example_particles <mdl_path>" << std::endl;
keep_console_open();
return EXIT_FAILURE;
}
const char* mdl_path = argv[1];
// Access the neuray library
mi::base::Handle<mi::neuraylib::INeuray> neuray( load_and_get_ineuray());
check_success( neuray.is_valid_interface());
// Configure the neuray library
configuration( neuray.get(), mdl_path);
// Start the neuray library
mi::Sint32 result = neuray->start();
check_start_success( result);
// Do the actual rendering
rendering( neuray.get());
// Shut down the neuray library
check_success( neuray->shutdown() == 0);
neuray = 0;
// Unload the neuray library
check_success( unload());
keep_console_open();
return EXIT_SUCCESS;
}
This interface represents bool.
Definition: inumber.h:122
A reference is an object that acts as a pointer to other database elements.
Definition: iref.h:25
A simple string class.
Definition: istring.h:22
Handle class template for interfaces, automatizing the lifetime control via reference counting.
Definition: handle.h:113
NxM-dimensional matrix class template of fixed dimensions.
Definition: matrix.h:367
Fixed-size math vector class template with generic operations.
Definition: vector.h:286
This interface is used to interact with the distributed database.
Definition: idatabase.h:293
This interface is used to export files.
Definition: iexport_api.h:38
A group is a container for other scene elements.
Definition: igroup.h:39
This interface provides various utilities related to canvases and buffers.
Definition: iimage_api.h:49
This interface is used to import files.
Definition: iimport_api.h:100
An instance is a scene element that adds a transformation and attributes to another scene element.
Definition: iinstance.h:117
This is an object representing the Iray library.
Definition: ineuray.h:44
virtual Sint32 shutdown(bool blocking=true)=0
Shuts down the library.
virtual base::IInterface * get_api_component(const base::Uuid &uuid) const =0
Returns an API component from the Iray SDK API.
virtual Sint32 start(bool blocking=true)=0
Starts the operation of the Iray library.
Interface representing a collection of particles.
Definition: iparticles.h:40
virtual void reserve(Size n)=0
Reserves space for n particles.
virtual Sint32 set_data(const Float32 *data, Size n)=0
Sets the data for the whole particle object.
virtual void set_type(Particle_type particle_type)=0
Sets the particle type.
This interface is used to load plugins and to query information about loaded plugins.
Definition: iplugin_configuration.h:24
This interface is used to query and change the rendering configuration.
Definition: irendering_configuration.h:109
The scene is the top-level element describing a subset of DB elements to be rendered.
Definition: iscene.h:44
A transaction provides a consistent view on the database.
Definition: itransaction.h:81
virtual base::IInterface * create(const char *type_name, Uint32 argc=0, const base::IInterface *argv[]=0)=0
Creates an object of the type type_name.
virtual base::IInterface * edit(const char *name)=0
Retrieves an element from the database and returns it ready for editing.
virtual Sint32 commit()=0
Commits the transaction.
virtual Sint32 store(base::IInterface *db_element, const char *name, Uint8 privacy=LOCAL_SCOPE)=0
Stores the element db_element in the database under the name name and with the privacy level privacy.
#define MI_BASE_DLL_FILE_EXT
The operating system specific default filename extension for shared libraries (DLLs)
Definition: config.h:340
unsigned long long Uint64
64-bit unsigned integer.
Definition: types.h:62
float Float32
32-bit float.
Definition: types.h:51
signed int Sint32
32-bit signed integer.
Definition: types.h:46
@ PARTICLE_TYPE_SPHERE
Sphere.
Definition: iparticles.h:27
Iray SDK API.
[Previous] [Next] [Up]