Easy Volume Rendering

Not too long ago I was looking for volume data of the human brain. I couldn't find much that was easy to work with, and one of the best data sets I could find at the time consisted of a demonstration, which you had to pay to get full access to, and a lower quality movie which ran through every slice, 'visible human' style.

Well, not considering MPEG's quality loss, I decided it would be easy enough to convert each frame in the movie into a slice in 3D space, and I also decided it would be really easy to hack together in Maya using MEL and a stack of textured planes. I whipped out a handy copy of linux's mplayer to extract each frame into a separate image, and then wrote a MEL script to apply each sequential image to its own shader and polygon plane.

I won't even get into how slow it was, but it did work:




This is the MEL script that generates the volume slices:

 
	 
	{ 
	 
		string $file2d; 
		string $lambert; 
		string $intToStr; 
		string $fileName; 
		string $plane[]; 
		string $fullPlanePath[]; 
	 
		string $prefix = "/home/shea/mdquad/"; 
		string $base = "00000000"; 
		string $format = ".jpg"; 
	
		int $slices = 32;		// number of slices to import ( starting with ($base) + 1 ) 
		
		float $spacing = 100;		// increase spacing to decrease gap. 
		float $ambVal = 0.035;		// ambient brightness for volume 
		float $alphaOffset = 0.36;	// transparency offset per slice 
	
		for ($i=1; $i<$slices; $i++) 
		{ 
			$file2d = createNode("file"); 
			$lambert = createNode("lambert"); 
	 
			connectAttr( ($file2d+".outColor"), ($lambert+".transparency") ); 
	 
			setAttr( ($file2d+".invert"), 1 ); 
			setAttr( ($file2d+".filterType"), 3 ); 
	 
			setAttr( ($file2d+".colorOffsetR"), $alphaOffset ); 
			setAttr( ($file2d+".colorOffsetG"), $alphaOffset ); 
			setAttr( ($file2d+".colorOffsetB"), $alphaOffset ); 
		
			setAttr( ($lambert+".colorR"), 1 ); 
			setAttr( ($lambert+".colorG"), 1 ); 
			setAttr( ($lambert+".colorB"), 1 ); 
	 
			setAttr( ($lambert+".ambientColorR"), $ambVal ); 
			setAttr( ($lambert+".ambientColorG"), $ambVal ); 
			setAttr( ($lambert+".ambientColorB"), $ambVal ); 
	 
	 
			$intToStr = string($i); 
			$fileName = ( $prefix + (substring($base, 1, 8-size($intToStr)) + $intToStr + $format) ); 
	 
			setAttr( "-type", "string", ($file2d+".fileTextureName"), $fileName ); 
				
		
			$plane = polyPlane("-sx", 1, "-sy", 1, "-ch", 0, "-n", $fileName); 
			xform("-ws", "-a", "-t", 0, float($i)/$spacing, 0, $plane[0]); 
			$fullPlanePath = listRelatives("-f", $plane[0]); 
	 
			inform($fileName); 
		
			defaultNavigation("-source", $lambert, "-destination"
				, ($fullPlanePath[0]+".instObjGroups[0]"), "-connectToExisting"); 
			connectNodeToAttrOverride($lambert, ($plane[0]+".instObjGroups[0]") );		
		} 
	 
	 
	} 
	 
	

Programming
Tutorials