// 
// Pre Shape Mel Script
//
global proc wyvillEdgesRI() {
// Get the name of the shape node
string $shapeNode = `rman ctxGetObject`;
string $parents[] = `listRelatives -parent $shapeNode`;
string $tformNode = $parents[0];
  
string $attr;
$attr = `rmanGetAttrName "wyvill_maxEdges"`;
$attr = `rmanGetFullSharedGeometricAttrName $shapeNode $attr`;
int $wyvill_maxEdges = `getAttr $attr`;
  
$attr = `rmanGetAttrName "wyvill_cacheName"`;
$attr = `rmanGetFullSharedGeometricAttrName $shapeNode $attr`;
string $wyvill_cacheName = `getAttr $attr`;
  
$attr = `rmanGetAttrName "wyvill_cacheMode"`;
$attr = `rmanGetFullSharedGeometricAttrName $shapeNode $attr`;
int $wyvill_cacheMode = `getAttr $attr`;
  
$attr = `rmanGetAttrName "wyvill_renderMode"`;
$attr = `rmanGetFullSharedGeometricAttrName $shapeNode $attr`;
int $wyvill_renderMode = `getAttr $attr`;
  
$attr = `rmanGetAttrName "wyvill_thickness"`;
$attr = `rmanGetFullSharedGeometricAttrName $shapeNode $attr`;
float $wyvill_thickness = `getAttr $attr`;
  
string $attrs_archive_path = getArchivePath($wyvill_cacheName + "_attributes");
vector $vertData[];
int    $numVerts = -1;
int    $numEdges;
if($wyvill_cacheMode == 0) { // Bake
    $numEdges = getEdges($tformNode, $vertData, 1);
    
    // Ensure we do not write (bake) more data than can be handled 
    // by the wyvillLines osl shader can handle.
    $numVerts = $numEdges * 2;
    int $maxVerts = $wyvill_maxEdges * 2;
    if($numVerts > $maxVerts)
        $numVerts = $maxVerts;
    
    // Create an archive rib containing the two user attrs. For example,
    //      Attribute "user" "int verts_count" [100]
    //      Attribute "user" "point[400] verts_data" [ 400 xyzs ]
    // "verts_count" will tell the osl shader that only the first 100
    // points are valid - the remaining 300 points are "padding".
    string $attrsStr;
    $attrId = fopen($attrs_archive_path, "w");
    $attrsStr = "Attribute \"user\" \"int verts_count\" [" + $numVerts + "]\n";
    fprint($attrId, $attrsStr);
    
    $attrsStr = "Attribute \"user\" \"point[" + $maxVerts + "] verts_data\" [\n";
    fprint($attrId, $attrsStr);
    int $n;
    for($n = 0; $n < size($vertData); $n++) {
        vector $vert = $vertData[$n];
        fprint($attrId, $vert.x + " " + $vert.y + " " + $vert.z + "\n");
        }
    // Add "padding" vertices
    if($numVerts < $maxVerts) {
        int $padding = $maxVerts - $numVerts;
        for($n = 0; $n < $padding; $n++)
            fprint($attrId, "0 0 0\n");
        } 
    fprint($attrId, "]\n");
    fclose($attrId);
    }
else if($wyvill_cacheMode == 1) // Read
    RiReadArchive($attrs_archive_path);
else
    /* ignore */ ;
    
  
if($wyvill_renderMode == 2) { // wireframe
    if(size($vertData) == 0 || $numVerts == -1) {
        clear($vertData);
        $numEdges = getEdges($tformNode, $vertData, 1);
        if($numEdges > $wyvill_maxEdges)
            $numVerts = $wyvill_maxEdges * 2;
        }
    int $n;
    string $wire_archive_path = getArchivePath($wyvill_cacheName + "_wireframe");
    
    $wireId = fopen($wire_archive_path, "w");
    fprint($wireId, "Attribute \"dice\" \"int roundcurve\" [1]\n");
    string $vertStr = "";
    for($n = 0; $n < $numEdges; $n++)
        $vertStr += "2 ";
    fprint($wireId, "Curves \"linear\" [" + $vertStr + "] \"nonperiodic\" \"P\" [\n");
    for($n = 0; $n < size($vertData); $n++) {
        vector $vert = $vertData[$n];
        fprint($wireId, $vert.x + " " + $vert.y + " " + $vert.z + "\n");
        }
    fprint($wireId, "] \"constantwidth\" [" + $wyvill_thickness + "]\n");
    fclose($wireId);
    RiIdentity();
    RiReadArchive($wire_archive_path);
    }
// Make the proxy object inactive...
if($wyvill_renderMode == 0 || $wyvill_renderMode == 2) {
    RiAttribute "visibility" "int camera" 0;
    RiAttribute "visibility" "int indirect" 0;
    RiAttribute "visibility" "int transmission" 0;
    }
}
  
//__________________________________________________________
// A utility to create a rib path for an archive to be saved
// in the project directories "data" folder.
global proc string getArchivePath(string $name) {
    string $projpath = `workspace -q -rootDirectory`;
    string $datapath = $projpath + "data/";
    string $scenename = `file -q -sceneName -shortName`;
    int $frame = `currentTime -q`;
    string $fstr = "0" + $frame;
    if($frame < 10)
        $fstr = "000" + $frame;
    else if($frame < 100)
        $fstr = "00" + $frame;
    $ribpath = $datapath + $name + "." + $fstr + ".rib";
    return $ribpath;
    }