...
This extension enables maxwell to render particles as spheres. These particles can be stored in a several file formats, such as .bin or .pxy file, abc, pxy, rpc, typically saved from realflow, or passed as internal data which is stored in the .mxs file.
...
Example of how to create a MaxwellParticles object, add a uv channel, set its custom type to "VelocityVorticity" and enable loading the particle densities vorticities array.
Code Block | ||||
---|---|---|---|---|
| ||||
CextensionManager* extensionManager = CextensionManager::instance(); CgeometryProceduralExtension* geomProcExtension = extensionManager->createGeometryProceduralExtension( "MaxwellParticles" ); //Get the extension container. When using this method of getting the container, //nearly all parameters have default values, and there is no need to explicitly set them. MXparamList* particlesParams = geomProcExtension->getExtensionData(); //Fill the required data char* filename = "/home/rocco/Emitter01_00023.bin"; particlesParams->setString( "FileName", filename ); //Enable loading particle densitiesvorticity data byte load = 1; particlesParams->setByte( "Load particle DensityVorticity", load ); //These two numbers can be obtained parsing the particles file or all the particles sequence //They're needed to map the values of velocitiesvorticities from 0.0 to 1.0 to access the texture. float minV = 0.0; float maxV = 23.67; particlesParams->setFloat( "Min VelocityVorticity", minV ); particlesParams->setFloat( "Max VelocityVorticity", maxV ); //Add the procedural object to the scene Cmaxwell::Cobject obj = scene->createGeometryProceduralObject( "My Particles", particlesParams ); //Let´s add a uv channel... dword uvIndex; //returned uv channel index. Use this index in the texture map properties to access its uv'suvs byte isOk = obj.addChannelUVW( uvIndex ); // uvIndex will be set to the actual uv channel number of the object. //...and set it to a custom UV generator, 317, in this case, velocityvorticity modulus obj.generateCustomUVW( uvIndex, 317 );//3 is the type of the custom uv generator. //Now assign a material and set the first BSDF reflectance0º color a texture driven by uv channel 'uvIndex' //This uv channel, since it is a scalar one-valued channel, stores its value in the U coordinate. |
...
Name | Type | Description |
---|---|---|
char* | Particles filename | |
float | Particle radius multiplier | |
float | Motion blur multiplier | |
float | Camera shutterspeed | |
"Load particles %" | float | Percentage of particles to load |
"Create N particles per particle" | unsigned int | Enables Multipoint feature if N > 0 |
"Extra particles dispersion" | float | Dispersion of the extra particles cloud |
"Extra particles deformation" | float | Deformation of the extra particles cloud |
"Load particle Force" | byte | Load or not array of Force vectors |
"Min Force" | float | Minimum force modulus value |
"Max Force" | float | Maximum force modulus value |
"Load particle Vorticity" | byte | Load or not array of Vorticity vectors |
"Min Vorticity" | float | Minimum vorticity modulus value |
"Max Vorticity" | float | Maximum vorticity modulus value |
"Load particle Normal" | byte | Load or not array of Normal vectors |
"Load particle neighbors no." | byte | Load or not array of particle neighbors# |
"Min Nneighbors" | unsigned int | Minimum number of neighbors value |
"Max Nneighbors" | unsigned int | Maximum number of neighbors value"Max Nneighbors" |
"Load particle UV" | byte | Load or not array of particle UV |
"Load particle Age" | byte | Load or not array of particle Age |
"Min Age" | float | Minimum age value |
"Max Age" | float | Maximum age value |
"Load particle Isolation Time" | byte | Load or not array of particle isolation time |
"Min Isolation Time" | float | Minimum isolation time value |
"Max Isolation Time" | float | Maximum isolation time value |
"Load particle Viscosity" | byte | Load or not array of particle viscosity |
"Min Viscosity" | float | Minimum viscosity value |
"Max Viscosity" | float | Maximum viscosity value |
"Load particle Density" | byte | Load or not array of particle density |
"Min Density" | float | Minimum density value |
"Max Density" | float | Maximum density value |
"Load particle Pressure" | byte | Load or not array of particle pressure |
"Min Pressure" | float | Minimum pressure value |
"Max Pressure" | float | Maximum pressure value |
"Load particle Mass" | byte | Load or not array of particle mass |
"Min Mass" | float | Minimum mass value |
"Max Mass" | float | Maximum mass value |
"Load particle Temperature" | byte | Load or not array of particle temperature |
"Min Temperature" | float | Minimum temperature value |
"Max Temperature" | float | Maximum temperature value |
"Load particle ID" | byte | Load or not array of particle ID |
"PARTICLE_POSITIONS" | float* | Array of particle positions |
"PARTICLE_SPEEDS" | float* | Array of particle speeds |
"PARTICLE_RADII" | float* | Array of particle radii |
"PARTICLE_IDS" | int* | Array of particleID's |
UV Generators
Name | Index |
---|---|
"Particle UV" | 0 |
"Particle UW" | 1 |
"Particle VW" | 2 |
"Velocity Modulus" | 3 |
"Velocity Vx" | 4 |
"Velocity Vy" | 5 |
"Velocity Vz" | 6 |
"Velocity Vx Vy" | 7 |
"Velocity Vx Vz" | 8 |
"Velocity Vy Vz" | 9 |
"Force Modulus" | 10 |
"Force Fx" | 11 |
"Force Fy" | 12 |
"Force Fz" | 13 |
"Force Fx Fy" | 14 |
"Force Fx Fz" | 15 |
"Force Fy Fz" | 16 |
"Vorticity Modulus" | 17 |
"Vorticity wx" | 18 |
"Vorticity wy" | 19 |
"Vorticity wz" | 20 |
"Vorticity wx wy" | 21 |
"Vorticity wx wz" | 22 |
"Vorticity wy wz" | 23 |
"Normal Nx" | 24 |
"Normal Ny" | 25 |
"Normal Nz" | 26 |
"Normal Nx Ny" | 27 |
"Normal Nx Nz" | 28 |
"Normal Ny Nz" | 29 |
"No. neighbors" | 30 |
"Age" | 31 |
"Isolation Time" | 32 |
"Viscosity" | 33 |
"Density" | 34 |
"Pressure" | 35 |
"Mass" | 36 |
"Temperature" | 37 |
"ID" | 38 |
"FileName"
Name of the file that contains particles data. It is a NULL terminated string.
Example:
Code Block | ||
---|---|---|
| ||
char* file = "/home/paco/Emitter01_00049.bin";
extParam->setString( "FileName", file ); |
"Radius Factor"
Multiplier for the particle radius that is read from the file. Can go from 0.00001 to 1000000 and the default value is 1.
Example:
Code Block | ||
---|---|---|
| ||
float rFactor = 0.3f;
extParam->setFloat( "Radius Factor", rFactor ); |
"MB Factor"
Multiplier to increase or decrease the amount of motion blur of the particles. Can go from 0.0 to 1000000.0. Default is 1.0.
"PARTICLE_FORCE" | float* | Array of particle force |
"PARTICLE_VORTICITY" | float* | Array of particle vorticity |
"PARTICLE_NORMALS" | float* | Array of particle normals |
"PARTICLE_NNEIGHBORS" | int* | Array of particle's number of neighbors |
"PARTICLE_UVW" | float* | Array of particle native texture coordinates |
"PARTICLE_AGE" | float* | Array of particle age |
"PARTICLE_ISOL_TIME" | float* | Array of particle isolation time |
"PARTICLE_VISCOSITY" | float* | Array of particle viscosity |
"PARTICLE_DENSITY" | float* | Array of particle density |
"PARTICLE_PRESSURE" | float* | Array of particle pressure |
"PARTICLE_MASS" | float* | Array of particle mass |
"PARTICLE_TEMPERATURE" | float* | Array of particle temperature |
"PARTICLE_FLAG_COLORS" | byte | Indicates whether particle colors are available or not |
"PARTICLE_COLORS" | float* | Array of per particle color |
UV Generators
Name | Index |
---|---|
"Particle UV" | 0 |
"Particle UW" | 1 |
"Particle VW" | 2 |
"Velocity Modulus" | 3 |
"Velocity Vx" | 4 |
"Velocity Vy" | 5 |
"Velocity Vz" | 6 |
"Velocity Vx Vy" | 7 |
"Velocity Vx Vz" | 8 |
"Velocity Vy Vz" | 9 |
"Force Modulus" | 10 |
"Force Fx" | 11 |
"Force Fy" | 12 |
"Force Fz" | 13 |
"Force Fx Fy" | 14 |
"Force Fx Fz" | 15 |
"Force Fy Fz" | 16 |
"Vorticity Modulus" | 17 |
"Vorticity wx" | 18 |
"Vorticity wy" | 19 |
"Vorticity wz" | 20 |
"Vorticity wx wy" | 21 |
"Vorticity wx wz" | 22 |
"Vorticity wy wz" | 23 |
"Normal Nx" | 24 |
"Normal Ny" | 25 |
"Normal Nz" | 26 |
"Normal Nx Ny" | 27 |
"Normal Nx Nz" | 28 |
"Normal Ny Nz" | 29 |
"No. neighbors" | 30 |
"Age" | 31 |
"Isolation Time" | 32 |
"Viscosity" | 33 |
"Density" | 34 |
"Pressure" | 35 |
"Mass" | 36 |
"Temperature" | 37 |
"ID" | 38 |
"FileName"
Name of the file that contains particles data. It is a NULL terminated string.
Example:
Code Block | ||
---|---|---|
| ||
floatchar* factorfile = 0.3f"/home/paco/Emitter01_00049.bin"; extParam->setFloat>setString( "MB FactorFileName", factorfile ); |
...
"Radius Factor"
Shutterspeed of the active camera. Affects the amount of motion of the particles. It is the inverse of the time the shutter is openMultiplier for the particle radius that is read from the file. Can go from 0.00001 to 1000000 and the default value is 1.
Example:
Code Block | ||
---|---|---|
| ||
float shutterrFactor = 1250.f3f; extParam->setFloat( "ShutterRadius 1/Factor", shutterrFactor ); |
"
...
MB Factor"
Multiplier to increase or decrease the amount of motion blur of the particles. Can go from 0.0 to 1001000000.0, default value is 100. Default is 1.0.
Example:
Code Block | ||
---|---|---|
| ||
float percentfactor = 750.f3f; extParam->setFloat( "LoadMB particles %Factor", percentfactor ); |
...
"
...
Shutter 1/"
Shutterspeed of the active camera. Affects the amount of motion of the particles. It is the inverse of the time the shutter is open.
Example:
Code Block | ||
---|---|---|
| ||
unsignedfloat int nPartsshutter = 10125.f; extParam->setUInt>setFloat( "Create N particles per particleShutter 1/", nPartsshutter ); |
"
...
Load particles
...
%"
This parameter sets the size of the cloud of extra particles around each original particlePercentage of particles to load. Can go from 0.0 to 100000. Default is 0100.0, default value is 100.
Example:
Code Block | ||
---|---|---|
| ||
float dispersionpercent = 275.f; extParam->setFloat( "ExtraLoad particles dispersion%", dispersionpercent ); |
"
...
Create N particles
...
per particle"
Sets the amount of deformation of the new particles cloud along the speed vector of the original particle. Can go from 0 to 100000. Default is 0This parameter, if set greater than zero, activates the Multipoint feature, creating N more particles around each particle. So, if you have 100 particles and set this parameter to 4, it will create 400 more particles, and the final count will be 500.
Example:
Code Block | ||
---|---|---|
| ||
floatunsigned int deformationnParts = 1.1f10; extParam->setFloat>setUInt( "ExtraCreate N particles deformationper particle", deformationnParts ); |
"
...
Extra particles dispersion"
This parameter sets the size of the cloud of extra particles around each original particle. Can go from 0 to 100000. Default is 0.
Example:
Code Block | ||
---|---|---|
| ||
float dispersion = 2.f;
extParam->setFloat( "Extra particles dispersion", dispersion ); |
"Extra particles deformation"
Sets the amount of deformation of the new particles cloud along the speed vector of the original particle. Can go from 0 to 100000. Default is 0.
Example:
Code Block | ||
---|---|---|
| ||
bytefloat loadArraydeformation = 1.1f; extParam->setByte>setFloat( "LoadExtra particleparticles Viscositydeformation", loadArraydeformation ); |
"
...
Load particle Force" "
...
Load particle Vorticity"
...
"
...
Load particle Normal" "
...
Load particle neighbors no." "
...
Load particle UV" "
...
Load particle Age" "
...
Load particle Isolation Time" "
...
Load particle Viscosity" "
...
Load particle Density" "
...
Load particle Pressure"
...
"Load particle Mass" "
...
Load particle Temperature" "
...
Load particle ID"
These values must be set to normalize the values read from the corresponding magnitudes arrays. For vector magnitudes the max and min values should be the max and min modulus of these vectors.
"PARTICLE_POSITIONS"
Particle data can come whether in a file or internally stored in the .mxs file. If a filename is not supplied, the extension checks for internal data, and if successful, loads it. This parameter is a linear array of floats x0 y0 z0 x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4 flags enable the extension to load the magnitudes arrays to be used with the corresponding UV generators. Note that loading every array without later using it with the UV generator is a waste of memory and could slow the render process. Use them only if you need them.
The particle ID array is needed only if the Multipoint feature is used.
Code Block | ||
---|---|---|
| ||
byte loadArray = 1;
extParam->setByte( "Load particle Viscosity", loadArray ); |
"Min Force" "Max Force" "Min Vorticity" "Max Vorticity" "Min Nneighbors" "Max Nneighbors" "Min Age" "Max Age" "Min Isolation Time" "Max Isolation Time" "Min Viscosity" "Max Viscosity" "Min Density" "Max Density" "Min Pressure" "Max Pressure" "Min Mass" "Max Mass" "Min Temperature" "Max Temperature"
These values must be set to normalize from 0.0 to 1.0 the values read from the corresponding magnitudes arrays. For vector magnitudes the max and min values should be the max and min modulus of these vectors.
"PARTICLE_POSITIONS"
Particle data can come whether in a file or internally stored in the .mxs file. If a filename is not supplied, the extension checks for internal data, and if successful, loads it. This parameter is a linear array of floats x0 y0 z0 x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4 ...., its length is 3*numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 4;
float points[ 3*4 ];
for( int idx = 0; idx < numParticles; idx++ )
{
points[ 3*idx + 0 ] = (float)idx;
points[ 3*idx + 1 ] = (float)idx;
points[ 3*idx + 2 ] = (float)idx;
}
extParam->setFloatArray( "PARTICLE_POSITIONS", points, 3*numParticles ); |
"PARTICLE_SPEEDS"
Linear array of particle speeds, floating point numbers, needed to enable calculation of motion blur: Vx0 Vy0 Vz0 Vx1 Vy1 Vz1 Vx2 Vy2 Vz2...., its length is 3*numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 4;
float speeds[ 3*4 ];
for( int idx = 0; idx < numParticles; idx++ )
{
speeds[ 3*idx + 0 ] = (float)idx;
speeds[ 3*idx + 1 ] = (float)idx;
speeds[ 3*idx + 2 ] = (float)idx;
}
extParam->setFloatArray( "PARTICLE_SPEEDS", speeds, 3*numParticles ); |
"PARTICLE_RADII"
Linear array of particle radii, floating point numbers: r0 r1 r2 r3 r4 r5 r6 .... The length of this array can be either 1 or numParticles. If only one radius is given , it is applied to all the particles, otherwise each particle gets its own radius.
Example:
Code Block | ||
---|---|---|
| ||
//Each particle its own radius
int numParticles = 4;
float radius[ 4 ];
for( int idx = 0; idx < numParticles; idx++ )
{
radius[ idx ] = (float)idx + 0.01f;
}
extParam->setFloatArray( "PARTICLE_RADII", radius, numParticles );
//One radius for all particles
float r = 0.4f;
setFloatArray( "PARTICLE_RADII", &r, 1 ); |
"PARTICLE_IDS"
Linear array of particle IDs, id0 id1 id2 id3 id4 id5.......needed to enable coherent calculation of multipoint. It is an integer array.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 3;
int ids[ 3 ];
ids[ 0 ] = 23;
ids[ 1 ] = 9;
ids[ 2 ] = 51;
extParam->setIntArray( "PARTICLE_IDS", ids, numParticles ); |
"PARTICLE_FORCE"
Linear array of particle force : Fx0 Fy0 Fz0 Fx1 Fy1 Fz1 Fx2 Fy2 Fz2...., its length is 3*numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 4;
float force[ 3*4 ];
for( int idx = 0; idx < numParticles; idx++ )
{
force[ 3*idx + 0 ] = (float)idx;
force[ 3*idx + 1 ] = (float)idx;
force[ 3*idx + 2 ] = (float)idx;
}
extParam->setFloatArray( "PARTICLE_FORCE", force, 3*numParticles ); |
"PARTICLE_VORTICITY"
Linear array of particle vorticity : Wx0 Wy0 Wz0 Wx1 Wy1 Wz1 Wx2 Wy2 Wz2...., its length is 3*numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 4;
float force[ 3*4 ];
for( int idx = 0; idx < numParticles; idx++ )
{
vorticity[ 3*idx + 0 ] = (float)idx;
vorticity[ 3*idx + 1 ] = (float)idx;
vorticity[ 3*idx + 2 ] = (float)idx;
}
extParam->setFloatArray( "PARTICLE_VORTICITY", vorticity, 3*numParticles ); |
"PARTICLE_NORMALS"
Linear array of normals of the field at each particle: Nx0 Ny0 Nz0 Nx1 Ny1 Nz1 Nx2 Ny2 Nz2...., its length is 3*numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 4;
float norm[ 3*4 ];
for( int idx = 0; idx < numParticles; idx++ )
{
norm[ 3*idx + 0 ] = (float)idx;
norm[ 3*idx + 1 ] = (float)idx;
norm[ 3*idx + 2 ] = (float)idx;
}
extParam->setFloatArray( "PARTICLE_NORMALS", norm, 3*numParticles ); |
"PARTICLE_NNEIGHBORS"
Linear array of number of neighbors for each particle: n0 n1 n2 n3 n4 n5...It is an integer array and its length is numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 3;
int nn[ 3 ];
nn[ 0 ] = 2;
nn[ 1 ] = 1;
nn[ 2 ] = 1;
extParam->setIntArray( "PARTICLE_NNEIGHBORS", nn, numParticles ); |
"PARTICLE_UVW"
Linear array of texture coordinates (uvw) at each particle: u0 v0 w0 u1 v1 w1 u2 v2 w2...., its length is 3*numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 4;
float uvw[ 3*4 ];
for( int idx = 0; idx < numParticles; idx++ )
{
uvw[ 3*idx + 0 ] = (float)idx/numParticles;
uvw[ 3*idx + 1 ] = (float)idx/numParticles;
uvw[ 3*idx + 2 ] = (float)idx/numParticles;
}
extParam->setFloatArray( "PARTICLE_UVW", uvw, 3*numParticles ); |
"PARTICLE_AGE"
Linear array of particle age: a0 a1 a2...., its length is numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 3;
float age[ 3 ];
age[ 0 ] = 4.3;
age[ 1 ] = 0.1;
age[ 2 ] = 7.2;
extParam->setFloatArray( "PARTICLE_AGE", age, numParticles ); |
"PARTICLE_ISOL_TIME"
Linear array of particle isolation time: i0 i1 i2...., its length is numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 3;
float iso[ 3 ];
iso[ 0 ] = 4.3;
iso[ 1 ] = 0.1;
iso[ 2 ] = 7.2;
extParam->setFloatArray( "PARTICLE_ISOL_TIME", iso, numParticles ); |
"PARTICLE_VISCOSITY"
Linear array of particle viscosity: v0 v1 v2...., its length is numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 3;
float vis[ 3 ];
vis[ 0 ] = 4.3;
vis[ 1 ] = 0.1;
vis[ 2 ] = 7.2;
extParam->setFloatArray( "PARTICLE_VISCOSITY", vis, numParticles ); |
"PARTICLE_DENSITY"
Linear array of particle density: d0 d1 d2...., its length is numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 3;
float den[ 3 ];
den[ 0 ] = 4.3;
den[ 1 ] = 0.1;
den[ 2 ] = 7.2;
extParam->setFloatArray( "PARTICLE_DENSITY", den, numParticles ); |
"PARTICLE_PRESSURE"
Linear array of particle pressure: p0 p1 p2...., its length is 3* numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 43; float pointsprs[ 3*4 ]; for( int idx = 0; idx < numParticles; idx++ ) { points[ 3*idx +prs[ 0 ] = (float)idx; points[ 3*idx + = 4.3; prs[ 1 ] = (float)idx0.1; points[ 3*idx +prs[ 2 ] = (float)idx7.2; } extParam->setFloatArray( "PARTICLE_POSITIONSPRESSURE", pointsprs, 3*numParticles ); |
...
"PARTICLE_
...
MASS"
Linear array of particle speeds, floating point numbers, needed to enable calculation of motion blur: Vx0 Vy0 Vz0 Vx1 Vy1 Vz1 Vx2 Vy2 Vz2mass: m0 m1 m2...., its length is 3* numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 43; float speedsmass[ 3*4 ]; for( int idx = 0; idx < numParticles; idx++ ) { speeds[ 3*idx + mass[ 0 ] = (float)idx; speeds[ 3*idx +4.3; mass[ 1 ] = (float)idx0.1; speedsmass[ 3*idx + 2 ] = (float)idx; }7.2; extParam->setFloatArray( "PARTICLE_SPEEDSMASS", speedsmass, 3*numParticles ); |
"PARTICLE_
...
TEMPERATURE"
Linear array of particle radii, floating point numbers: r0 r1 r2 r3 r4 r5 r6 .temperature: t0 t1 t2... The length of this array can be either 1 or numParticles. If only one radius is given , it is applied to all the particles, otherwise each particle gets its own radius, its length is numberOfParticles.
Example:
Code Block | ||
---|---|---|
| ||
//Each particle its own radius int numParticles = 43; float radiustemp[ 43 ]; for(temp[ int0 idx] = 04.3; idx < numParticles; idx++ ) { radius[ idxtemp[ 1 ] = 0.1; temp[ 2 ] = (float)idx + 0.01f; }7.2; extParam->setFloatArray( "PARTICLE_RADIITEMPERATURE", radiustemp, numParticles ); //One radius for all particles float r = 0.4f; setFloatArray( "PARTICLE_RADII", &r |
"PARTICLE_FLAG_COLORS"
Flag indicating if the particle colors array is present or not. It is an array of length 1. Only usable with internal particles.
Example:
Code Block | ||
---|---|---|
| ||
byte flag = 1;
extParam->setByteArray( "PARTICLE_FLAG_COLORS", &flag, 1 ); |
"PARTICLE_
...
COLORS"
Linear array of particle IDs, id0 id1 id2 id3 id4 id5..color (rgb) at each particle: r0 g0 b0 r1 g1 b1 r2 g2 b2.....needed to enable coherent calculation of multipoint. It is an integer array., its length is 3*numberOfParticles. Only usable with internal particles
Example:
Code Block | ||
---|---|---|
| ||
int numParticles = 3; int ids[ 3 ]; ids[ int numParticles = 4; float rgb[ 3*4 ]; for( int idx = 0; idx < numParticles; idx++ ) { rgb[ 3*idx + 0 ] = 23; ids[(float)idx/numParticles; rgb[ 3*idx + 1 ] = 9(float)idx/numParticles; ids[ rgb[ 3*idx + 2 ] = 51(float)idx/numParticles; } extParam->setIntArray>setFloatArray( "PARTICLE_IDSCOLORS", idsrgb, 3*numParticles ); |