LlSculpt mel/sculpt.mel

From Second Life Wiki
Jump to navigation Jump to search

// * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. // * $License$


global proc string llFirst(string $list[]) { return $list[0]; }



global proc llSculptExport(string $object, string $file_name, string $file_format, int $resolution_x, int $resolution_y, int $maximize_scale, int $fix_orientation, int $flip_horizontal)

{ // copy it, because we're going to mutilate it. MUHAHAHAAAaa... string $object_copy = llFirst(duplicate($object));

// disentangle from groups string $parents[] = listRelatives("-parent", $object_copy); if (size($parents) != 0) $object_copy = llFirst(parent("-world", $object_copy));

// scale it to unit cube float $bounding_min[3]; float $bounding_max[3];

$bounding_min = getAttr($object_copy + ".boundingBoxMin"); $bounding_max = getAttr($object_copy + ".boundingBoxMax");

float $scale[3]; int $i; for ($i = 0; $i < 3; $i++) $scale[$i] = $bounding_max[$i] - $bounding_min[$i];

float $scale_max = 0; for ($i = 0; $i < 3; $i++) if ($scale[$i] > $scale_max) $scale_max = $scale[$i];

if ($maximize_scale) { print($object + " scale normalized - scale by " + $scale[0] + " " + $scale[1] + " " + $scale[2] + " inside SL to get original shape\n"); } else { for ($i = 0; $i < 3; $i++) $scale[$i] = $scale_max; }


scale("-relative", 1/$scale[0], 1/$scale[1], 1/$scale[2], $object_copy);

// position it in unit cube $bounding_min = getAttr($object_copy + ".boundingBoxMin"); $bounding_max = getAttr($object_copy + ".boundingBoxMax");

float $center[3]; for ($i = 0; $i < 3; $i++) $center[$i] = ($bounding_min[$i] + $bounding_max[$i]) / 2.0;

move("-relative", 0.5 - $center[0], 0.5 - $center[1], 0.5 - $center[2], $object_copy);


// // nurbs surfaces can be adjusted to ensure correct orientation //

if ($fix_orientation) { string $shape = llFirst(listRelatives("-shapes", $object_copy)); if ((nodeType($object_copy) == "nurbsSurface") || (($shape != "") && (nodeType($shape) == "nurbsSurface"))) { // try to determine the "north pole"; float $pole[] = pointOnSurface("-turnOnPercentage", 1, "-parameterU", 0.5, "-parameterV", 0, $object_copy); float $total_distance = 0;

float $v; for ($v = 0; $v <= 1; $v += 0.1) { float $point[] = pointOnSurface("-turnOnPercentage", 1, "-parameterU", $v, "-parameterV", 0, $object_copy); float $distance = 0; int $i; for ($i = 0; $i < 3; $i++) $distance += pow($pole[$i] - $point[$i], 2); $distance = sqrt($distance);

$total_distance += $distance; }

if ($total_distance > 0.1) // the points don't converge on the pole - swap { print("swapping UVs to orient poles for " + $object + "\n"); reverseSurface("-direction", 3, $object_copy); }

// now try to ensure the normal points "out" // note: this could easily fail - but there's no better way (i think.)

float $total_orientation = 0; float $u; for ($u = 0; $u <= 1; $u += 0.1) for ($v = 0; $v <= 1; $v += 0.1) { float $point[] = pointOnSurface("-turnOnPercentage", 1, "-parameterU", $u, "-parameterV", $v, $object_copy);

float $normal[] = pointOnSurface("-normal", "-turnOnPercentage", 1, "-parameterU", $u, "-parameterV", $v, $object_copy);

// check the orientation of the normal w/r/t the direction from center

float $center_dir[]; for ($i = 0; $i < 3; $i++) $center_dir[$i] = $point[$i] - 0.5;

float $orientation = 0; // dot product for ($i = 0; $i < 3; $i++) $orientation += $center_dir[$i] * $normal[$i];

$total_orientation += $orientation; }

if ($total_orientation > 0) // need to invert { print("reversing V for " + $object + "\n"); reverseSurface("-direction", 1, $object_copy); } if ($flip_horizontal) { // reverse U, for compatibility with surface textures print("reversing U for " + $object + "\n"); reverseSurface("-direction", 0, $object_copy); } }

else { warning("cannot fix orientation on non-nurbs object: " + $object); }


}

// create temporary shading network string $sampler_info = createNode("samplerInfo");

print("exporting sculpt map for " + $object + " into file " + $file_name + "\n");

// bake sculpt texture string $fileNodes[] = convertSolidTx("-fileImageName", $file_name, "-fileFormat", $file_format, "-force", 1, "-resolutionX", $resolution_x, "-resolutionY", $resolution_y, $sampler_info + ".pointWorld", $object_copy);

delete($fileNodes); // we don't want 'em. why do you make 'em?

delete($sampler_info); delete($object_copy); }


global proc int llSculptEditorCallback() { string $objects[] = ls("-sl");

if (size($objects) == 0) { warning("please select objects to export"); return 0; }

string $filename = textFieldButtonGrp("-query", "-fileName", "llSculptEditorFilename"); int $resolution_x = intSliderGrp("-query", "-value", "llSculptEditorResolutionX"); int $resolution_y = intSliderGrp("-query", "-value", "llSculptEditorResolutionY"); int $fix_orientation = checkBoxGrp("-query", "-value1", "llSculptEditorFixOrientation"); int $flip_horizontal = checkBoxGrp("-query", "-value1", "llSculptEditorFlipHorizontal"); int $maximize_scale = checkBoxGrp("-query", "-value1", "llSculptEditorMaximizeScale");

// get filetype string $file_type; string $file_base; string $file_extension;

string $tokens[]; tokenize($filename, ".", $tokens);

if (size($tokens) == 1) // no extension, default to bmp { $file_base = $filename; $file_type = "bmp"; $file_extension = "bmp"; } else { $file_extension = $tokens[size($tokens) - 1]; int $i; for ($i = 0; $i < size($tokens) - 1; $i++) { $file_base += $tokens[$i]; if ($i != size($tokens) - 2) $file_base += "."; }

if ($file_extension == "bmp") $file_type = "bmp"; else if (($file_extension == "jpg") || ($file_extension == "jpeg")) $file_type = "jpg"; else if (($file_extension == "tif") || ($file_extension == "tiff")) $file_type = "tif"; else if ($file_extension == "tga") $file_type = "tga"; else { warning("unknown image type (" + $file_extension + "). switching to bmp"); $file_type = "bmp"; $file_extension = "bmp"; } }


string $object; for ($object in $objects) { string $this_filename = $file_base; if (size($objects) > 1) $this_filename += "-" + $object; $this_filename += "." + $file_extension;

llSculptExport($object, $this_filename, $file_type, $resolution_x, $resolution_y, $maximize_scale, $fix_orientation, $flip_horizontal); }


select($objects);

return 1; }

global proc llSculptEditorSetFilenameCallback(string $filename, string $filetype) { textFieldButtonGrp("-edit", "-fileName", $filename, "llSculptEditorFilename"); }

global proc llSculptEditorBrowseCallback() { fileBrowser("llSculptEditorSetFilenameCallback", "Export", "image", 1); }


global proc llSculptEditor() { string $commandName = "llSculptExport";

string $layout = getOptionBox(); setParent $layout;

setOptionBoxCommandName($commandName);

setUITemplate -pushTemplate DefaultTemplate;

scrollLayout;

tabLayout -tabsVisible 0 -scrollable 0;

string $parent = `columnLayout -adjustableColumn 1`;

separator -height 10 -style "none";

textFieldButtonGrp -label "Filename" -fileName "sculpt.bmp" -buttonLabel "Browse" -buttonCommand "llSculptEditorBrowseCallback" llSculptEditorFilename;

intSliderGrp -field on -label "X Resolution" -minValue 1 -maxValue 512 -fieldMinValue 1 -fieldMaxValue 4096 -value 64 llSculptEditorResolutionX;

intSliderGrp -field on -label "Y Resolution" -minValue 1 -maxValue 512 -fieldMinValue 1 -fieldMaxValue 4096 -value 64 llSculptEditorResolutionY;

checkBoxGrp -label "" -label1 "Maximize scale" -numberOfCheckBoxes 1 -value1 off llSculptEditorMaximizeScale;

checkBoxGrp -label "" -label1 "Flip Horizontal" -numberOfCheckBoxes 1 -value1 on llSculptEditorFlipHorizontal;

checkBoxGrp -label "" -label1 "Correct orientation" -numberOfCheckBoxes 1 -value1 on llSculptEditorFixOrientation;

setUITemplate -popTemplate;

string $applyBtn = getOptionBoxApplyBtn(); button -edit -label "Export" -command "llSculptEditorCallback" $applyBtn;

string $applyAndCloseBtn = getOptionBoxApplyAndCloseBtn(); button -edit -label "Export and Close" -command "llSculptEditorCallback" $applyAndCloseBtn;


setOptionBoxTitle("Export Sculpt Texture");

setOptionBoxHelpTag( "ConvertFileText" );

showOptionBox(); }


//

llSculptEditor;