LlSculpt mel
Revision as of 19:45, 24 May 2007 by Damanios Thetan (talk | contribs) (added a reverseSurface on U, as this changed in the latest fix, to be compatible with surface textures)
// * 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) { // 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); } } else { warning("cannot fix orientation on non-nurbs object: " + $object); } } // reverse U, for compatibility with surface textures print("reversing U for " + $object + "\n"); reverseSurface("-direction", 0, $object_copy); // 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 $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); } 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 1; 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 "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;