RfM
Sample RiMel Scripts IV
Polymesh converted to a Blobby


return to main index


Introduction

This tutorial presents a technique for rendering a polymesh object as a single RenderMan Blobby consists of individual "blobs" locatred at the vertices of the polymesh - figure 1.



Figure 1

Listings 1 and 2 provide the .rman and .mel scripts that define and implement the interface shown below.



Figure 2


Listing 3 does most of the "work". It gets the values from the interface, queries the positions of the polymesh vertices and writes an archive rib file that contains the RenderMan description of the Blobby. The archive is written to the current Maya project RIB_Archive directory. The renderer is told to render the archive via a ReadArchive command.

The three scripts should be copied to the users Maya "scripts" directory or, as explained in the tutorial "RfM: Customizing" in the users "RfM_mel" directory. The scripts will only work if the current project directory has a "RIB_Archive" directory.

To see the effect of the scripts create a polymesh object, select it and run this command in the script editor, "polyMeshBlobbyUI;". The gui shown in figure 2 should appear in Maya's attribute editor for the shape node of the mesh.


Improvements

Probably the most noteable improvement that could be made is for a Blobby to be made from selected vertices of a mesh. Currently, the polyMeshBlobbyRI() procedure uses all the vertices of a polymesh to create the Blobby.


Listing 1 (polyMeshBlobbyUI.rman)


rman "-version 1" {
Declare param {int pmb_cache} {
    label "Caching Behaviour"
    subtype selector
    range {
        "Compute" 0
        "Reuse"   1
        "Disable" 2
        }
    }
Declare param {float pmb_size} {
    label "Blobby Size"
    subtype slider
    range {0 1 .001}
    description "Uniformly scales the individual blobbies."
    }
Declare param {float pmb_height} {
    label "Height Offset"
    subtype slider
    range {0 1 .001}
    description {Use this slider to move the Blobby
                 above its true location in the scene.}
    }
}


Listing 2 (polyMeshBlobbyUI.mel)


global proc polyMeshBlobbyUI() 
{
string $selected[] = `ls -sl`;
int $i;
for($i=0; $i < size($selected); $i++) 
    {
    string $shp[] = `listRelatives -shapes $selected[$i]`;
    string $shapeName = $shp[0];
    string $attr = `rmanGetAttrName "preShapeScript"`;
  
    rmanAddAttr $shapeName $attr "polyMeshBlobbyRI";
        
    $attr = `rmanGetAttrName "pmb_cache"`;
    rmanAddAttr $shapeName $attr "0";
  
    $attr = `rmanGetAttrName "pmb_size"`;
    rmanAddAttr $shapeName $attr "0.5";
  
    $attr = `rmanGetAttrName "pmb_height"`;
    rmanAddAttr $shapeName $attr "1.0";
    }
}


Listing 3 (polyMeshBlobbyRI.mel)


global proc polyMeshBlobbyRI()
{
// Get the names of the shape and transform nodes
string $shapeNode = `rman ctxGetObject`;
string $parents[] = `listRelatives -parent $shapeNode`;
string $tformNode = $parents[0];
  
// The values from the interface
string $attr;
$attr = `rmanGetAttrName "pmb_cache"`;
int $pmb_cache = `getAttr($shapeNode + "." + $attr)`;
  
// User has selected "Disable"
if($pmb_cache == 2) {
    print("Blobby will not be generated - Disable is active");
    return;
    }
$attr = `rmanGetAttrName "pmb_size"`;
float $pmb_size = `getAttr($shapeNode + "." + $attr)`;
  
$attr = `rmanGetAttrName "pmb_height"`;
float $pmb_height = `getAttr($shapeNode + "." + $attr)`;
    
// Get the number of vertices of the polymesh
int  $num[] = `polyEvaluate -v $tformNode`;
  
// The path to the rib file containing the description of the
// Blobby consists of "RIB_Archive" directory, the scene name,
// the shape name of the polymesh and the frame number, for
// example,
//        RIB_Archive/bathroom/shaving_cream.0001.rib
string $projPath = `workspace -q -rootDirectory`;
string $sceneName = `file -q -sceneName -shortName`;
if(size($sceneName) == 0)
    $sceneName = "untitled";
int    $frame = `currentTime -q`;
string $fStr = "." + $frame;
if($frame < 10) 
    $fStr = ".000" + $frame;
else if($frame < 100)
    $fStr = ".00" + $frame;
  
string $archiveNme = $sceneName +"_"+ $shapeNode + $fStr + ".rib";
string $path = $projPath + "RIB_Archive/"+ $archiveNme;
  
// User has selected "Compute"
if($pmb_cache == 0) {
    int    $fileid = `fopen $path "w"`;
    print("Writing Blobby archive to:\n");
    print("    \"" + $path + "\"\n");
    // Begin writing the Blobby to the archive
    fprint($fileid, "Blobby " + $num[0] + " [\n");
    
    // Make each blob an ellipsoid and provide its array
    // index. The indices monotonously increment by 16.
    for($n = 0; $n < $num[0]; $n++)
        fprint($fileid, "1001 " + ($n * 16) + "\n");
      
    // Add the blending code "0" and the number of blobs to blend.
    fprint($fileid, "0 " + $num[0]);
      
    // Specify the indices of all the blobs.
    for($n = 0; $n < $num[0]; $n++)
        fprint($fileid, " " + $n);
    fprint($fileid, "]\n");
    fprint($fileid, "[\n");
            
    // Specify the transformations of each blob
    string $row1, $row2, $row3;
    for($n = 0; $n < $num[0]; $n++) {
        string $vert = $shapeNode + ".vtx[" + $n + "]";
        $pos = `pointPosition -local $vert`;
        $row1 = $pmb_size + " 0 0 0 ";
        $row2 = " 0 " + $pmb_size + " 0 0 ";
        $row3 = " 0 0 " + $pmb_size + " 0 ";
        $row4 = $pos[0] + " " + 
                ($pos[1] * $pmb_height) + " " + 
                $pos[2] + " 1\n";
        fprint($fileid, $row1 + $row2 + $row3 + $row4);
        }
    fprint($fileid, "]\n");
    fprint($fileid, "[\"\"]\n");
    fclose $fileid;
    }
else
    {
    print("Attempting to reuse:\n");
    print("    \"" + $path + "\"\n");    
    }    
// Tell prman to render the Blobby
RiTransformBegin();    
    RiReadArchive($path);
RiTransformEnd();
// Make sure the polymesh is totally invisible   
RiAttribute "visibility" "int camera" 0;
RiAttribute "visibility" "int transmission" 0; 
RiAttribute "visibility" "int diffuse" 0; 
RiAttribute "visibility" "int specular" 0; 
RiAttribute "visibility" "int photon" 0; 
}


© 2002- Malcolm Kesson. All rights reserved.